[jboss-cvs] JBossAS SVN: r68603 - in projects/aop/branches/joinpoint_graph/aop: src/test/org/jboss and 10 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Thu Jan 3 13:54:25 EST 2008


Author: flavia.rainone at jboss.com
Date: 2008-01-03 13:54:24 -0500 (Thu, 03 Jan 2008)
New Revision: 68603

Added:
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/AllTests.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/ExtendedLengthRangeTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/KeyPartTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/SlotCollectionTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/SlotFlagSystemTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/TreeInsertionTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/TreeSearchTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/Util.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/insertion/
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/insertion/AllTests.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/insertion/InsertionKeyTestCase.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/AllTests.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/SearchKeyTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/common/
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/common/AllTests.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/common/PrefixFunctionImplTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/common/PrefixFunctionLoaderTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/element/
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/element/AllTests.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/element/ComparableElementFactoryTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/element/ComparableElementTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/AllTests.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/ComparisonAlgorithmTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/ComparisonEndStateTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/ComparisonResultTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/ComparisonStartStateTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/ComparisonStartTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/IndexTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/LengthRangeTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/LengthRestrictionTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/MatcherFactoryTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/MatcherTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/MatchingStateTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/part/
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/part/AllTests.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/part/ComparableKeyPartFactoryTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/part/ComparableKeyPartPatternTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/part/ComparableKeyPartPrefixTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/part/ComparableKeyPartSimpleTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/part/ComparableKeyPartSuffixTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/part/ComparableKeyPartTest.java
Modified:
   projects/aop/branches/joinpoint_graph/aop/build-tests-jdk50.xml
Log:
[JBAOP-503] The search tree implementation, with tests.

Modified: projects/aop/branches/joinpoint_graph/aop/build-tests-jdk50.xml
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/build-tests-jdk50.xml	2008-01-03 17:46:01 UTC (rev 68602)
+++ projects/aop/branches/joinpoint_graph/aop/build-tests-jdk50.xml	2008-01-03 18:54:24 UTC (rev 68603)
@@ -872,6 +872,8 @@
                <include name="org/jboss/test/aop/pointcut/PointcutTestCase.class"/>
                <include name="org/jboss/test/aop/unit/assignability/*Test.class"/>
                <exclude name="org/jboss/test/aop/unit/assignability/ParameterizedTypeTest.class"/>
+               <include name="org/jboss/aop/joinpoint/graph/**/*Test.class"/>
+               <exclude name="org/jboss/aop/joinpoint/graph/tree/search/part/ComparableKeyPartTest.class"/>
                <exclude name="org/jboss/test/aop/unit/assignability/VariableTargetAlgorithmTest.class"/>
             </fileset>
          </batchtest>

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/AllTests.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/AllTests.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/AllTests.java	2008-01-03 18:54:24 UTC (rev 68603)
@@ -0,0 +1,51 @@
+/*
+ * 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 junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * Test suite that contains all test cases of this package.
+ * 
+ * @author Flavia Rainone
+ */
+public class AllTests
+{
+
+   public static Test suite()
+   {
+      TestSuite suite = new TestSuite("Test for org.jboss.aop.joinpoint.graph.tree");
+      //$JUnit-BEGIN$
+      suite.addTestSuite(SlotFlagSystemTest.class);
+      suite.addTestSuite(SlotCollectionTest.class);
+      suite.addTestSuite(ExtendedLengthRangeTest.class);
+      suite.addTestSuite(KeyPartTest.class);
+      suite.addTestSuite(TreeInsertionTest.class);
+      suite.addTestSuite(TreeSearchTest.class);
+      suite.addTest(org.jboss.aop.joinpoint.graph.tree.insertion.AllTests.suite());
+      suite.addTest(org.jboss.aop.joinpoint.graph.tree.search.AllTests.suite());
+      //$JUnit-END$
+      return suite;
+   }
+
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/ExtendedLengthRangeTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/ExtendedLengthRangeTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/ExtendedLengthRangeTest.java	2008-01-03 18:54:24 UTC (rev 68603)
@@ -0,0 +1,54 @@
+/*
+  * 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.ExtendedLengthRange;
+import org.jboss.aop.joinpoint.graph.tree.search.match.LengthRange;
+
+import junit.framework.TestCase;
+
+/**
+ * Test of the {@link ExtendedLengthRange} class.
+ * 
+ * @author Flavia Rainone
+ */
+public class ExtendedLengthRangeTest extends TestCase
+{
+   
+   public void test1()
+   {
+      LengthRange lengthRange = new LengthRange((byte) 1, (byte) 3);
+      ExtendedLengthRange elr = new ExtendedLengthRange((byte) 1, (byte) 3,
+            (byte) 3, lengthRange);
+      assertEquals(3, elr.getSuffixMinLength());
+      assertEquals(3, elr.getSuffixMaxLength());
+   }
+
+   public void test2()
+   {
+      LengthRange lengthRange = new LengthRange((byte) 1, (byte) 5);
+      ExtendedLengthRange elr = new ExtendedLengthRange((byte) 7, (byte) 11,
+            (byte) 25, lengthRange);
+      assertEquals(5, elr.getSuffixMinLength());
+      assertEquals(19, elr.getSuffixMaxLength());
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/KeyPartTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/KeyPartTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/KeyPartTest.java	2008-01-03 18:54:24 UTC (rev 68603)
@@ -0,0 +1,240 @@
+/*
+ * 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.KeyPart;
+import org.jboss.aop.joinpoint.graph.tree.search.match.LengthRange;
+
+import junit.framework.TestCase;
+
+/**
+ * Test of the {@link KeyPart} class.
+ * 
+ * @author Flavia Rainone
+ */
+public class KeyPartTest extends TestCase
+{
+   public void testEmptyKeyPart()
+   {
+      Util.assertKeyPart(KeyPart.EMPTY_KEY_END,
+            KeyPart.KEY_ELEMENT_END, new String[0]);
+   }
+   
+   public void testOneElementKeyPart()
+   {
+      KeyPart keyPart = new KeyPart("oneElement");
+      Util.assertKeyPart(keyPart, 'o', new String[] {"oneElement"});
+   }
+   
+   public void testTwoElementsKeyPart()
+   {
+      KeyPart keyPart = new KeyPart("two.Elements");
+      Util.assertKeyPart(keyPart, 't',
+            new String[] {"two", "Elements"});
+   }
+   
+   public void testElementsKeyPart()
+   {
+      KeyPart keyPart = new KeyPart("a.lot.of.Elements");
+      Util.assertKeyPart(keyPart, 'a', new
+            String[]{"a", "lot", "of", "Elements"});
+   }
+   
+   public void testFirstEmptyKeyPart()
+   {
+      KeyPart keyPart = new KeyPart(".element");
+      Util.assertKeyPart(keyPart, KeyPart.KEY_ELEMENT_END, new
+            String[] {"", "element"});
+   }
+   
+   public void testExtractPrefix1()
+   {
+      KeyPart keyPart = new KeyPart("lots.of.element.key.part");
+      Util.assertKeyPart(keyPart, 'l', new
+            String[] {"lots", "of", "element", "key", "part"});
+      KeyPart prefix = keyPart.extractPrefixPart(3, 1);
+      Util.assertKeyPart(keyPart, 'e', new String[]{"ey", "part"});
+      Util.assertKeyPart(prefix, 'l', new String[]{"lots", "of", "element",
+            "k"}, 5, 5, 3, 3);
+   }
+   
+   public void testExtractPrefix2()
+   {
+      KeyPart keyPart = new KeyPart("lots.of.element.key.part");
+      Util.assertKeyPart(keyPart, 'l', new
+            String[] {"lots", "of", "element", "key", "part"});
+      KeyPart prefix = keyPart.extractPrefixPart(2, 0);
+      Util.assertKeyPart(keyPart, 'e', new String[]{"element", "key",
+            "part"});
+      Util.assertKeyPart(prefix, 'l', new String[]{"lots", "of"}, 5, 5);
+   }
+
+   public void testExtractPrefix3()
+   {
+      KeyPart keyPart = new KeyPart("lots.of.element.key.part");
+      Util.assertKeyPart(keyPart, 'l', new
+            String[] {"lots", "of", "element", "key", "part"});
+      KeyPart prefix = keyPart.extractPrefixPart(0, 4);
+      Util.assertKeyPart(keyPart, KeyPart.KEY_ELEMENT_END,
+            new String[]{"", "of", "element", "key", "part"});
+      Util.assertKeyPart(prefix, 'l', new String[] {"lots"}, 5, 5, 4, 4);
+      
+      keyPart = prefix;
+      prefix = keyPart.extractPrefixPart(0, 3);
+      Util.assertKeyPart(keyPart, 's', new String[] {"s"}, 5, 5, 1, 1);
+      Util.assertKeyPart(prefix, 'l', new String[] {"lot"}, 5, 5, 4, 4);
+   }
+   
+   public void testExtractPrefix4()
+   {
+      KeyPart keyPart = new KeyPart("lots.of.element.key.part");
+      Util.assertKeyPart(keyPart, 'l', new
+            String[] {"lots", "of", "element", "key", "part"});
+      KeyPart prefix1 = keyPart.extractPrefixPart(3, 2);
+      Util.assertKeyPart(prefix1, 'l', new String[] {"lots", "of", "element",
+            "ke"}, 5, 5, 3, 3);
+      KeyPart prefix2 = prefix1.extractPrefixPart(3, 1);
+      Util.assertKeyPart(prefix2, 'l', new String[] {"lots", "of", "element",
+            "k"}, 5, 5, 3, 3);
+      Util.assertKeyPart(prefix1, 'e', new String[] {"e"}, 2, 2, 2, 2);
+   }
+   
+   public void testExtractPrefix5()
+   {
+      KeyPart keyPart = new KeyPart("element");
+      Util.assertKeyPart(keyPart, 'e', new String[] {"element"});
+      KeyPart prefix = keyPart.extractPrefixPart(0, 0);
+      Util.assertKeyPart(prefix, KeyPart.KEY_ELEMENT_END, new String[] {""},
+            1, 1, 7, 7);
+   }
+
+   public void testExtractPrefix6()
+   {
+      KeyPart keyPart = new KeyPart("lots.of.element.key.part");
+      Util.assertKeyPart(keyPart, 'l', new
+            String[] {"lots", "of", "element", "key", "part"});
+      KeyPart prefix = keyPart.extractPrefixPart(0, 0);
+      Util.assertKeyPart(prefix, KeyPart.KEY_ELEMENT_END, new String[] {""},
+            5, 5, 4, 4);
+   }
+   
+   public void testNewSuffix1()
+   {
+      KeyPart keyPart = new KeyPart("element");
+      Util.assertKeyPart(keyPart, 'e', new String[] {"element"});
+      KeyPart keyPartSuffix = new KeyPart("suffix");
+      keyPart.newSuffix(keyPartSuffix);
+      LengthRange lengthRange = keyPart.getLengthRange();
+      assertEquals(1, lengthRange.getLength());
+      assertEquals(1, lengthRange.getPostPrefixMinLength());
+      assertEquals(2, lengthRange.getPostPrefixMaxLength());
+   }
+   
+   public void testNewSuffix2()
+   {
+      KeyPart keyPart = new KeyPart("lots.of.element.key.part");
+      Util.assertKeyPart(keyPart, 'l', new
+            String[] {"lots", "of", "element", "key", "part"});
+      KeyPart prefix = keyPart.extractPrefixPart(2, 0);
+      Util.assertKeyPart(keyPart, 'e', new String[]{"element", "key",
+            "part"});
+      Util.assertKeyPart(prefix, 'l', new String[]{"lots", "of"},
+            5, 5);
+      // add an equal length suffix
+      prefix.newSuffix(new KeyPart("a.new.suffix"));
+      Util.assertLengthRange(prefix.getLengthRange(), 2, 5, 5);
+      // add a shorter suffix
+      prefix.newSuffix(new KeyPart("shortSuffix"));
+      Util.assertLengthRange(prefix.getLengthRange(), 2, 3, 5);
+      // add a longer suffix
+      prefix.newSuffix(new KeyPart("a.new.suffix.longer.than.I.thought"));
+      Util.assertLengthRange(prefix.getLengthRange(), 2, 3, 9);
+   }
+   
+   public void testNewSuffix3()
+   {
+      KeyPart keyPart = new KeyPart("lots.of.element.key.part");
+      Util.assertKeyPart(keyPart, 'l', new
+            String[] {"lots", "of", "element", "key", "part"});
+      KeyPart prefix = keyPart.extractPrefixPart(0, 3);
+      Util.assertKeyPart(keyPart, 's',
+            new String[]{"s", "of", "element", "key", "part"});
+      Util.assertKeyPart(prefix, 'l', new String[]{"lot"}, 5, 5, 4, 4);
+      // add an equal length element suffix
+      prefix.newSuffix(new KeyPart("a.new.suffix"));
+      Util.assertLengthRange(prefix.getLengthRange(), 1, 3, 5, 3, 4, 4);
+      // add a longer element suffix
+      prefix.newSuffix(new KeyPart("shortSuffix"));
+      Util.assertLengthRange(prefix.getLengthRange(), 1, 1, 5, 3, 4, 14);
+      // add a shorter element suffix
+      prefix.newSuffix(new KeyPart(".new.suffix.longer.than.I.thought"));
+      Util.assertLengthRange(prefix.getLengthRange(), 1, 1, 7, 3, 3, 14);
+   }
+   
+   public void testNewSuffix4()
+   {
+      KeyPart keyPart = new KeyPart("lots.of.element.key.part");
+      Util.assertKeyPart(keyPart, 'l', new
+            String[] {"lots", "of", "element", "key", "part"});
+      KeyPart prefix = keyPart.extractPrefixPart(0, 3);
+      Util.assertKeyPart(keyPart, 's',
+            new String[]{"s", "of", "element", "key", "part"});
+      Util.assertKeyPart(prefix, 'l', new String[]{"lot"}, 5, 5, 4, 4);
+      
+      KeyPart keyPart2 = new KeyPart("other.elements.key.part");
+      Util.assertKeyPart(keyPart2, 'o', new
+            String[] {"other", "elements", "key", "part"});
+      KeyPart prefix2 = keyPart2.extractPrefixPart(0, 1);
+      Util.assertKeyPart(keyPart2, 't', new
+            String[] {"ther", "elements", "key", "part"});
+      Util.assertKeyPart(prefix2, 'o', new String[]{"o"}, 4, 4, 5, 5);
+      
+      KeyPart keyPart3 = new KeyPart("other.keyPart");
+      Util.assertKeyPart(keyPart3, 'o', new
+            String[] {"other", "keyPart"});
+      KeyPart prefix3 = keyPart3.extractPrefixPart(0, 2);
+      Util.assertKeyPart(keyPart3, 'h', new
+            String[] {"her", "keyPart"});
+      Util.assertKeyPart(prefix3, 'o', new String[]{"ot"}, 2, 2, 5, 5);
+      prefix3.newSuffix(new KeyPart("blablabla"));
+      Util.assertLengthRange(prefix3.getLengthRange(), 1, 1, 2, 2, 5, 11);
+      
+      KeyPart keyPart4 = new KeyPart(
+            "a.keyPart.that.is.longer.than.the.others");
+      Util.assertKeyPart(keyPart4, 'a', new String[] {"a", "keyPart",
+            "that", "is", "longer", "than", "the", "others"});
+      KeyPart prefix4 = keyPart4.extractPrefixPart(0, 1);
+      Util.assertKeyPart(keyPart4, KeyPart.KEY_ELEMENT_END,
+            new String[] {"", "keyPart", "that", "is", "longer", "than", "the",
+            "others"});
+      Util.assertKeyPart(prefix4, 'a', new String[]{"a"}, 8, 8, 1, 1);
+      prefix4.newSuffix(new KeyPart("ab.lots.elements.more.more.more"));
+      Util.assertLengthRange(prefix4.getLengthRange(), 1, 6, 8, 1, 1, 3);
+      // add suffixes
+      prefix.newSuffix(prefix2);
+      Util.assertLengthRange(prefix.getLengthRange(), 1, 4, 5, 3, 4, 8);
+      prefix.newSuffix(prefix3);
+      Util.assertLengthRange(prefix.getLengthRange(), 1, 1, 5, 3, 4, 14);
+      prefix.newSuffix(prefix4);
+      Util.assertLengthRange(prefix.getLengthRange(), 1, 1, 8, 3, 4, 14);
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/SlotCollectionTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/SlotCollectionTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/SlotCollectionTest.java	2008-01-03 18:54:24 UTC (rev 68603)
@@ -0,0 +1,105 @@
+/*
+  * 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.SlotCollection;
+
+import junit.framework.TestCase;
+
+/**
+ * Test of the {@link SlotCollection} class.
+ * 
+ * @author Flavia Rainone
+ */
+public class SlotCollectionTest extends TestCase
+{
+   SlotCollection collection;
+   
+   public void setUp()
+   {
+      collection = new SlotCollection(Character.valueOf('A'), 'A',
+            Character.valueOf('S'), 'S');
+   }
+   
+   public void testConstruction()
+   {
+      collection.loadSlot('A');
+      assertFalse(collection.isSlotEmpty());
+      assertEquals('A', collection.getSlotContent());
+      collection.loadSlot('S');
+      assertFalse(collection.isSlotEmpty());
+      assertEquals('S', collection.getSlotContent());
+   }
+   
+   public void testReplacement()
+   {
+      collection.loadSlot('A');
+      collection.getSlotContent();
+      collection.replaceSlotContent(Character.valueOf('B'));
+      collection.loadSlot('X');
+      collection.loadSlot('A');
+      assertFalse(collection.isSlotEmpty());
+      assertEquals('B', collection.getSlotContent());
+   }
+   
+   public void testAll()
+   {
+      char[] slots = {'X', 'C', 'x', 'W', 'Z', 'k', 'G', 'a', 'H', 'n', 'M',
+            'I', 'd', 'e', 'm', 'V', 'c', 'F', 'l', 'J', 'Q', 'y', 'B'};
+      fillSlots(slots);
+      char[] orderedSlots = {'A', 'B', 'C', 'F', 'G', 'H', 'I', 'J', 'M', 'Q',
+            'S', 'V', 'W', 'X', 'Z', 'a', 'c', 'd', 'e', 'k', 'l', 'm', 'n',
+            'x', 'y'};
+      assertSlotContents(orderedSlots);
+   }
+   
+   private void assertSlotContents(char[] orderedSlots)
+   {
+      Object[] contents = collection.getAllContents();
+      assertNotNull(contents);
+      assertEquals(orderedSlots.length, contents.length);
+      for (int i = 0; i < orderedSlots.length; i++)
+      {
+         collection.loadSlot(orderedSlots[i]);
+         assertFalse(collection.isSlotEmpty());
+         assertEquals(orderedSlots[i],
+               ((Character) collection.getSlotContent()).charValue());
+         assertEquals(orderedSlots[i], ((Character) contents[i]).charValue());
+      }
+   }
+   
+   /**
+    * Fills the slots identified by <code>slots</code> with </code>slots</code>
+    * itself.
+    * 
+    * @param slots contains the characters that identify the slots to be filled
+    *              and is the contents that will fill the slots.
+    */
+   private void fillSlots(char[] slots)
+   {
+      for (int i = 0; i < slots.length; i++)
+      {
+         collection.loadSlot(slots[i]);
+         collection.fillSlot(Character.valueOf(slots[i]));
+      }
+   }  
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/SlotFlagSystemTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/SlotFlagSystemTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/SlotFlagSystemTest.java	2008-01-03 18:54:24 UTC (rev 68603)
@@ -0,0 +1,156 @@
+/*
+ * 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.Random;
+
+import org.jboss.aop.joinpoint.graph.tree.SlotFlagSystem;
+
+import junit.framework.TestCase;
+
+/**
+ * Test of the {@link SlotFlagSystem} class.
+ * 
+ * @author Flavia Rainone
+ */
+public class SlotFlagSystemTest extends TestCase
+{
+   SlotFlagSystem flagSystem;
+   
+   public void setUp()
+   {
+      flagSystem = new SlotFlagSystem('a', 'B');
+   }
+   
+   public void testConstruction()
+   {
+      assertPositiveIndexes(new char[] {'B', 'a'});
+      
+      flagSystem.loadFlag((char)5000);
+      assertFalse(flagSystem.getFlagValue());
+      
+      flagSystem.loadFlag('A');
+      assertFalse(flagSystem.getFlagValue());
+   }
+   
+   public void testChanges()
+   {
+      setPositive('x');
+      assertPositiveIndexes(new char[] {'B', 'a', 'x'});
+   }
+   
+   public void testChanges2()
+   {
+      setPositive((char) 500);
+      assertPositiveIndexes(new char[] {'B', 'a', (char) 500});
+   }
+   
+   public void testChanges3()
+   {
+      assertRandomScenario(Character.MAX_VALUE);
+   }
+
+   public void testChanges4()
+   {
+      assertRandomScenario('{');
+   }
+   
+   /**
+    * Asserts the flag system in a random scenario, that generates 100 ids of
+    * flags to be set as positive.
+    * 
+    * @param upperLimit the uppder limit of the id values to be generated
+    */
+   public void assertRandomScenario(char upperLimit)
+   {
+      char[] flags = new char[]{'B', 'a'};
+      Random random = new Random();
+      externLoop: for (int i = 0; i < 100; i++)
+      {
+         char randomChar = (char) (random.nextInt() % upperLimit);
+         if (randomChar < '#')
+         {
+            continue;
+         }
+         int j;
+         for (j = 0; j < flags.length; j++)
+         {
+            if (flags[j] == randomChar)
+            {
+               continue externLoop;
+            }
+            if (flags[j] > randomChar)
+            {
+               break;
+            }
+         }
+         char[] oldFlags = flags;
+         flags = new char[flags.length + 1];
+         for (int k = 0; k < j; k++)
+         {
+            flags[k] = oldFlags[k];
+         }
+         flags[j] = randomChar;
+         for (int k = j + 1; k < flags.length; k++)
+         {
+            flags[k] = oldFlags[k - 1];
+         }
+         
+         setPositive(randomChar);
+         assertPositiveIndexes(flags);
+      }
+      
+   }
+   
+   /**
+    * Sets the flag identified by <code>flag</code> as positive in the system.
+    * <p>
+    * This method should not be called if the flag already has a positive value.
+    * 
+    * @param flag the id of the flag to be set as positive
+    */
+   public void setPositive(char flag)
+   {
+      flagSystem.loadFlag(flag);
+      assertFalse(flagSystem.getFlagValue());
+      flagSystem.setFlagPositive();
+   }
+   
+   /**
+    * Asserts that all characters contained in <code>positiveFlags</code>
+    * have a positive flag in the system, and that their calculated index is
+    * the same as their indexes in <code>positiveFlags</code>.
+    * 
+    * @param positiveFlags contains the expected number, id and order of the
+    *                      positive flags
+    */
+   private void assertPositiveIndexes(char[] positiveFlags)
+   {
+      for (int i = 0; i < positiveFlags.length; i++)
+      {
+         flagSystem.loadFlag(positiveFlags[i]);
+         assertTrue(positiveFlags[i] + " is false", flagSystem.getFlagValue());
+         assertEquals(positiveFlags[i] + " has wrong index", i,
+               flagSystem.calculateFlagIndex());
+      }
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/TreeInsertionTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/TreeInsertionTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/TreeInsertionTest.java	2008-01-03 18:54:24 UTC (rev 68603)
@@ -0,0 +1,3548 @@
+/*
+ * 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.lang.reflect.Field;
+
+import org.jboss.aop.joinpoint.graph.tree.InternalNode;
+import org.jboss.aop.joinpoint.graph.tree.KeyPart;
+import org.jboss.aop.joinpoint.graph.tree.LeafNode;
+import org.jboss.aop.joinpoint.graph.tree.Node;
+import org.jboss.aop.joinpoint.graph.tree.SlotCollection;
+import org.jboss.aop.joinpoint.graph.tree.Tree;
+
+import junit.framework.TestCase;
+
+/**
+ * Test of the {@link Tree#insert} method.
+ * 
+ * @author Flavia Rainone
+ */
+public class TreeInsertionTest extends TestCase
+{
+   private Tree<String> tree;
+   private Field treeStateField;
+   private Field rootField;
+   private Field valueField;
+   private Field childrenField;
+   
+   public void setUp() throws Exception
+   {
+      treeStateField = Tree.class.getDeclaredField("state");
+      treeStateField.setAccessible(true);
+      rootField = Tree.class.getDeclaredField("root");
+      rootField.setAccessible(true);
+      valueField = LeafNode.class.getDeclaredField("value");
+      valueField.setAccessible(true);
+      childrenField = InternalNode.class.getDeclaredField("children");
+      childrenField.setAccessible(true);
+      this.tree = new Tree<String>();
+   }
+   
+   public void testTwoDifferentKeys() throws Exception
+   {
+      assertTreeState(Tree.EmptyState.class);
+      tree.insert("the.key", "THE");
+      assertTreeState(Tree.NotEmptyState.class);
+      String[] firstKeyElements = new String[] {"the", "key"};
+      assertRootLeafNode('t', firstKeyElements, "THE");
+      
+      tree.insert("other.key.very.very.different", "OTHER");
+      Node root = getRoot();
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, new String[] {""},
+            2, 5, 3, 5);
+      assertChildLeafNode(root, 't', firstKeyElements, "THE");
+      String[] secondKeyElements = new String[] {"other", "key", "very", "very",
+            "different"};
+      assertChildLeafNode(root, 'o', secondKeyElements, "OTHER");
+   }
+
+   public void testElementLengthRanges() throws Exception
+   {
+      assertTreeState(Tree.EmptyState.class);
+      // first insertion
+      tree.insert("myPackage1", "A");
+      assertTreeState(Tree.NotEmptyState.class);
+      assertRootLeafNode('m', new String[] {"myPackage1"}, "A");
+
+      // new insertion
+      String[] elements = new String[] {"myPackage"};
+      tree.insert("myPackage", "B");
+      Node root = getRoot();
+      assertInternalNode(root, 'm', elements, 1, 1, 9, 10);
+      assertChildLeafNode(root, '1', new String[] {"1"}, "A");
+      assertChildLeafNode(root, KeyPart.KEY_ELEMENT_END, new String[] {""},
+            "B");
+      
+      // new insertion
+      tree.insert("myPackageClass", "C");
+      root = getRoot();
+      assertInternalNode(root, 'm', elements, 1, 1, 9, 14);
+      assertChildLeafNode(root, '1', new String[] {"1"}, "A");
+      assertChildLeafNode(root, KeyPart.KEY_ELEMENT_END, new String[] {""},
+            "B");
+      assertChildLeafNode(root, 'C', new String[] {"Class"}, "C");
+      
+      // new insertion
+      tree.insert("m", "D");
+      root = getRoot();
+      assertInternalNode(root, 'm', new String[] {"m"}, 1, 1, 1, 14);
+      assertChildLeafNode(root, KeyPart.KEY_ELEMENT_END, new String[]{""}, "D");
+      root = getChildNode(root, 'y');
+      assertInternalNode(root, 'y', new String[] {"yPackage"}, 1, 1, 8, 13);
+      assertChildLeafNode(root, '1', new String[] {"1"}, "A");
+      assertChildLeafNode(root, KeyPart.KEY_ELEMENT_END, new String[] {""},
+            "B");
+      assertChildLeafNode(root, 'C', new String[] {"Class"}, "C");      
+   }
+   
+   public void testComplexScenario1() throws Exception
+   {
+      assertTreeState(Tree.EmptyState.class);
+      // first insertion
+      tree.insert("a.piece.of.paper", "A");
+      assertTreeState(Tree.NotEmptyState.class);
+      String[] elements = new String[] {"a", "piece", "of", "paper"};
+      assertRootLeafNode('a', elements, "A");
+
+      // new insertion
+      tree.insert("a.piece.of.paper123", "B");
+      Node root = getRoot();
+      assertInternalNode(root, 'a', elements, 4, 4, 5, 8);
+      assertChildLeafNode(root, KeyPart.KEY_ELEMENT_END, new String[] {""},
+            "A");
+      assertChildLeafNode(root, '1', new String[] {"123"}, "B");
+      
+      // new insertion
+      tree.insert("a.piece.of.paper.in.which.we.can.write", "C");
+      root = getRoot();
+      assertInternalNode(root, 'a', elements, 4, 9, 5, 8);
+      Node internal = getChildNode(root, KeyPart.KEY_ELEMENT_END);
+      assertInternalNode(internal, KeyPart.KEY_ELEMENT_END, new String[] {""},
+            1, 6);
+      assertChildLeafNode(root, '1', new String[] {"123"}, "B");
+      assertChildLeafNode(internal, KeyPart.KEY_ELEMENT_END, new String[0],
+            "A");
+      assertChildLeafNode(internal, 'i', new String[] {"in", "which", "we",
+            "can", "write"}, "C");
+      
+      // new insertion
+      tree.insert("a.piece.of.paper.in.which.we.can.draw", "D");
+      assertInternalNode(root, 'a', elements, 4, 9, 5, 8);
+      internal = getChildNode(root, KeyPart.KEY_ELEMENT_END);
+      assertInternalNode(internal, KeyPart.KEY_ELEMENT_END, new String[] {""},
+            1, 6);
+      assertChildLeafNode(root, '1', new String[] {"123"}, "B");
+      assertChildLeafNode(internal, KeyPart.KEY_ELEMENT_END, new String[0],
+            "A");
+      internal = getChildNode(internal, 'i');
+      assertInternalNode(internal, 'i', new String[] {"in", "which", "we",
+            "can"},
+            5, 5);
+      assertChildLeafNode(internal, 'w', new String[] {"write"}, "C");
+      assertChildLeafNode(internal, 'd', new String[] {"draw"}, "D");
+   }
+      
+   public void testComplexScenario2() throws Exception
+   {
+      assertTreeState(Tree.EmptyState.class);
+      // first insertion
+      tree.insert("my.package1", "A");
+      assertTreeState(Tree.NotEmptyState.class);
+      assertRootLeafNode('m', new String[] {"my", "package1"}, "A");
+
+      // new insertion
+      String[] elements = new String[] {"my", "package"};
+      tree.insert("my.package", "B");
+      Node root = getRoot();
+      assertInternalNode(root, 'm', elements, 2, 2, 7, 8);
+      assertChildLeafNode(root, '1', new String[] {"1"}, "A");
+      assertChildLeafNode(root, KeyPart.KEY_ELEMENT_END, new String[] {""},
+            "B");
+      
+      // new insertion
+      tree.insert("my.package.Class", "C");
+      root = getRoot();
+      assertInternalNode(root, 'm', elements, 2, 3, 7, 8);
+      assertChildLeafNode(root, '1', new String[] {"1"}, "A");
+      Node internal = getChildNode(root, KeyPart.KEY_ELEMENT_END);
+      assertInternalNode(internal, KeyPart.KEY_ELEMENT_END,
+            new String[] {""}, 1, 2);
+      assertChildLeafNode(internal, KeyPart.KEY_ELEMENT_END, new String[0],
+            "B");
+      assertChildLeafNode(internal, 'C', new String[] {"Class"}, "C");
+   }
+
+   public void testComplexScenario3() throws Exception
+   {
+      assertTreeState(Tree.EmptyState.class);
+      // insert A
+      tree.insert("abc.def.ghi.jkl.mno.pqr.stu.vwx.yz", "A");
+      assertTreeState(Tree.NotEmptyState.class);
+      String[] elementsA = new String[] {"abc", "def", "ghi", "jkl", "mno",
+            "pqr", "stu", "vwx", "yz"};
+      char idA = 'a';
+      assertRootLeafNode(idA, elementsA, "A");
+
+      // insert B
+      tree.insert("short.key", "B");
+      Node root = getRoot();
+      String[] rootElements = new String[] {""};
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 9, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      String[] elementsB = new String[] {"short", "key"};
+      char idB = 's';
+      assertChildLeafNode(root, idB, elementsB, "B");
+      
+      // insert C
+      tree.insert("pre.fi.xpa.tt.er.n1pa.tt.er.n2pa.tt.er.n3suf.fi.x", "C");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 14, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      assertChildLeafNode(root, 'p', new String[] {"pre", "fi",
+         "xpa", "tt", "er", "n1pa", "tt", "er", "n2pa", "tt", "er", "n3suf",
+         "fi", "x"}, "C");
+
+      // insert D
+      tree.insert("pre.fi.xpa.tt.er.n1pa.tt.er.n2pa.tt.er.n3suf.fi.a", "D");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 14, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      Node internalCDEFG = getChildNode(root, 'p');
+      assertInternalNode(internalCDEFG, 'p', new String[] {"pre", "fi",
+         "xpa", "tt", "er", "n1pa", "tt", "er", "n2pa", "tt", "er", "n3suf",
+         "fi"}, 14, 14);
+      String[] elementsC = new String[] {"x"};
+      char idC = 'x';
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      String[] elementsD = new String[] {"a"};
+      char idD = 'a';
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      
+      // insert E
+      tree.insert("pre.fi.xpa.tt.er.n1pa.tt.er.n2pa.tt.er.n3suf.fi.S", "E");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 14, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      assertInternalNode(internalCDEFG, 'p', new String[] {"pre", "fi",
+         "xpa", "tt", "er", "n1pa", "tt", "er", "n2pa", "tt", "er", "n3suf",
+         "fi"}, 14, 14);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      String[] elementsE = new String[] {"S"};
+      char idE = 'S';
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      
+      // insert F
+      tree.insert("pre.fi.xpa.tt.er.n1pa.tt.er.n2pa.tt.er.n3suf.fi.w", "F");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 14, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      assertInternalNode(internalCDEFG, 'p', new String[] {"pre", "fi",
+         "xpa", "tt", "er", "n1pa", "tt", "er", "n2pa", "tt", "er", "n3suf",
+         "fi"}, 14, 14);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      String[] elementsF = new String[] {"w"};
+      char idF = 'w';
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      
+      // insert G
+      tree.insert("pre.fi.xpa.tt.er.n1pa.tt.er.n2pa.tt.er.n3suf.fi.k", "G");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 14, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      assertInternalNode(internalCDEFG, 'p', new String[] {"pre", "fi",
+         "xpa", "tt", "er", "n1pa", "tt", "er", "n2pa", "tt", "er", "n3suf",
+         "fi"}, 14, 14);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      String[] elementsG = new String[] {"k"};
+      char idG = 'k';
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      
+      // insert H
+      tree.insert("pre.fi.xpa.tt.er.n1pa.tt.er.n2pa.tt.er.n3suf.fi.Q", "H");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 14, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      assertInternalNode(internalCDEFG, 'p', new String[] {"pre", "fi",
+         "xpa", "tt", "er", "n1pa", "tt", "er", "n2pa", "tt", "er", "n3suf",
+         "fi"}, 14, 14);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      String[] elementsH = new String[] {"Q"};
+      char idH = 'Q';
+      assertChildLeafNode(internalCDEFG, idH, elementsH, "H");
+      
+      // insert J
+      tree.insert("pre.fi.xpa.tt.er.n1pa.tt.er.n2pa.tt.er.n3suf.fa.b", "J");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 14, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      Node internalJKL_CDEFG = getChildNode(root, 'p');
+      assertInternalNode(internalJKL_CDEFG, 'p', new String[] {"pre", "fi",
+         "xpa", "tt", "er", "n1pa", "tt", "er", "n2pa", "tt", "er", "n3suf",
+         "f"}, 14, 14, 2, 2);
+      String[] elementsJ = new String[] {"a", "b"};
+      char idJ = 'a';
+      assertChildLeafNode(internalJKL_CDEFG, idJ, elementsJ, "J");
+      String[] elementsCDEFG = new String[] {"i"};
+      char idCDEFG = 'i';
+      internalCDEFG = getChildNode(internalJKL_CDEFG, idCDEFG);
+      assertInternalNode(internalCDEFG, idCDEFG, elementsCDEFG, 2, 2);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      assertChildLeafNode(internalCDEFG, idH, elementsH, "H");
+      
+      // insert K
+      tree.insert("pre.fi.xpa.tt.er.n1pa.tt.er.n2pa.tt.er.n3suf.fc.d", "K");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 14, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      assertInternalNode(internalJKL_CDEFG, 'p', new String[] {"pre", "fi",
+         "xpa", "tt", "er", "n1pa", "tt", "er", "n2pa", "tt", "er", "n3suf",
+         "f"}, 14, 14, 2, 2);
+      assertChildLeafNode(internalJKL_CDEFG, idJ, elementsJ, "J");
+      String[] elementsK = new String[] {"c", "d"};
+      char idK = 'c';
+      assertChildLeafNode(internalJKL_CDEFG, idK, elementsK, "K");
+      assertInternalNode(internalCDEFG, idCDEFG, elementsCDEFG, 2, 2);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      assertChildLeafNode(internalCDEFG, idH, elementsH, "H");
+
+      // insert L
+      tree.insert("pre.fi.xpa.tt.er.n1pa.tt.er.n2pa.tt.er.n3suf.fe.f", "L");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 14, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      assertInternalNode(internalJKL_CDEFG, 'p', new String[] {"pre", "fi",
+         "xpa", "tt", "er", "n1pa", "tt", "er", "n2pa", "tt", "er", "n3suf",
+         "f"}, 14, 14, 2, 2);
+      assertChildLeafNode(internalJKL_CDEFG, idJ, elementsJ, "J");
+      assertChildLeafNode(internalJKL_CDEFG, idK, elementsK, "K");
+      String[] elementsL = new String[] {"e", "f"};
+      char idL = 'e';
+      assertChildLeafNode(internalJKL_CDEFG, idL, elementsL, "L");
+      assertInternalNode(internalCDEFG, idCDEFG, elementsCDEFG, 2, 2);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      assertChildLeafNode(internalCDEFG, idH, elementsH, "H");
+
+      // insert M
+      tree.insert("pre.fi.xpa.tt.er.n1pa.tt.er.n2pa.tt.er.somea.bc.e", "M");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 14, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      Node internalMNO_JKL_CDEFG = getChildNode(root, 'p');
+      assertInternalNode(internalMNO_JKL_CDEFG, 'p', new String[] {"pre", "fi",
+            "xpa", "tt", "er", "n1pa", "tt", "er", "n2pa", "tt", "er"}, 14, 14);
+      String[] elementsM = new String[] {"somea", "bc", "e"};
+      char idM = 's';      
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idM, elementsM, "M");
+      String[] elementsJKL_CDEFG = new String[] {"n3suf", "f"};
+      char idJKL_CDEFG = 'n';
+      internalJKL_CDEFG = getChildNode(internalMNO_JKL_CDEFG, idJKL_CDEFG);
+      assertInternalNode(internalJKL_CDEFG, idJKL_CDEFG, elementsJKL_CDEFG, 3,
+            3, 2, 2);
+      assertChildLeafNode(internalJKL_CDEFG, idJ, elementsJ, "J");
+      assertChildLeafNode(internalJKL_CDEFG, idK, elementsK, "K");
+      assertChildLeafNode(internalJKL_CDEFG, idL, elementsL, "L");
+      assertInternalNode(internalCDEFG, idCDEFG, elementsCDEFG, 2, 2);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      assertChildLeafNode(internalCDEFG, idH, elementsH, "H");
+
+      // insert N
+      tree.insert("pre.fi.xpa.tt.er.n1pa.tt.er.n2pa.tt.er.fghij.kl.m", "N");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 14, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      assertInternalNode(internalMNO_JKL_CDEFG, 'p', new String[] {"pre", "fi",
+            "xpa", "tt", "er", "n1pa", "tt", "er", "n2pa", "tt", "er"}, 14, 14);
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idM, elementsM, "M");
+      String[] elementsN = new String[] {"fghij", "kl", "m"};
+      char idN = 'f';      
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idN, elementsN, "N");
+      assertInternalNode(internalJKL_CDEFG, idJKL_CDEFG, elementsJKL_CDEFG, 3,
+            3, 2, 2);
+      assertChildLeafNode(internalJKL_CDEFG, idJ, elementsJ, "J");
+      assertChildLeafNode(internalJKL_CDEFG, idK, elementsK, "K");
+      assertChildLeafNode(internalJKL_CDEFG, idL, elementsL, "L");
+      assertInternalNode(internalCDEFG, idCDEFG, elementsCDEFG, 2, 2);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      assertChildLeafNode(internalCDEFG, idH, elementsH, "H");
+      
+      // insert O
+      tree.insert("pre.fi.xpa.tt.er.n1pa.tt.er.n2pa.tt.er.opqrs.tu.v", "O");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 14, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      assertInternalNode(internalMNO_JKL_CDEFG, 'p', new String[] {"pre", "fi",
+            "xpa", "tt", "er", "n1pa", "tt", "er", "n2pa", "tt", "er"}, 14, 14);
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idM, elementsM, "M");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idN, elementsN, "N");
+      String[] elementsO = new String[] {"opqrs", "tu", "v"};
+      char idO = 'o';      
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idO, elementsO, "O");
+      assertInternalNode(internalJKL_CDEFG, idJKL_CDEFG, elementsJKL_CDEFG, 3,
+            3, 2, 2);
+      assertChildLeafNode(internalJKL_CDEFG, idJ, elementsJ, "J");
+      assertChildLeafNode(internalJKL_CDEFG, idK, elementsK, "K");
+      assertChildLeafNode(internalJKL_CDEFG, idL, elementsL, "L");
+      assertInternalNode(internalCDEFG, idCDEFG, elementsCDEFG, 2, 2);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      assertChildLeafNode(internalCDEFG, idH, elementsH, "H");
+      
+      // insert P
+      tree.insert("pre.fi.xpa.tt.er.n1pa.tt.er.n2pa.ab.cd.efghi.jk.l", "P");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 14, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      Node internalPQ_MNO_JKL_CDEFG = getChildNode(root, 'p');
+      assertInternalNode(internalPQ_MNO_JKL_CDEFG, 'p', new String[] {"pre",
+            "fi", "xpa", "tt", "er", "n1pa", "tt", "er", "n2pa"}, 14, 14);
+      String[] elementsP = new String[] {"ab", "cd", "efghi", "jk", "l"};
+      char idP = 'a';      
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idP, elementsP, "P");
+      String[] elementsMNO_JKL_CDEFG = new String[] {"tt", "er"};
+      char idMNO_JKL_CDEFG = 't';
+      internalMNO_JKL_CDEFG = getChildNode(internalPQ_MNO_JKL_CDEFG,
+            idMNO_JKL_CDEFG);
+      assertInternalNode(internalMNO_JKL_CDEFG, idMNO_JKL_CDEFG,
+            elementsMNO_JKL_CDEFG, 5, 5);
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idM, elementsM, "M");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idN, elementsN, "N");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idO, elementsO, "O");
+      assertInternalNode(internalJKL_CDEFG, idJKL_CDEFG, elementsJKL_CDEFG, 3,
+            3, 2, 2);
+      assertChildLeafNode(internalJKL_CDEFG, idJ, elementsJ, "J");
+      assertChildLeafNode(internalJKL_CDEFG, idK, elementsK, "K");
+      assertChildLeafNode(internalJKL_CDEFG, idL, elementsL, "L");
+      assertInternalNode(internalCDEFG, idCDEFG, elementsCDEFG, 2, 2);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      assertChildLeafNode(internalCDEFG, idH, elementsH, "H");
+      
+      // insert Q
+      tree.insert("pre.fi.xpa.tt.er.n1pa.tt.er.n2pa.mn.op.qrstu.vw.x", "Q");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 14, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      assertInternalNode(internalPQ_MNO_JKL_CDEFG, 'p', new String[] {"pre",
+            "fi", "xpa", "tt", "er", "n1pa", "tt", "er", "n2pa"}, 14, 14);    
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idP, elementsP, "P");
+      String[] elementsQ = new String[] {"mn", "op", "qrstu", "vw", "x"};
+      char idQ = 'm';      
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idQ, elementsQ, "Q");
+      assertInternalNode(internalMNO_JKL_CDEFG, idMNO_JKL_CDEFG,
+            elementsMNO_JKL_CDEFG, 5, 5);
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idM, elementsM, "M");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idN, elementsN, "N");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idO, elementsO, "O");
+      assertInternalNode(internalJKL_CDEFG, idJKL_CDEFG, elementsJKL_CDEFG, 3,
+            3, 2, 2);
+      assertChildLeafNode(internalJKL_CDEFG, idJ, elementsJ, "J");
+      assertChildLeafNode(internalJKL_CDEFG, idK, elementsK, "K");
+      assertChildLeafNode(internalJKL_CDEFG, idL, elementsL, "L");
+      assertInternalNode(internalCDEFG, idCDEFG, elementsCDEFG, 2, 2);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      assertChildLeafNode(internalCDEFG, idH, elementsH, "H");
+      
+      // insert R
+      tree.insert("pre.fi.xpa.tt.er.n1pa.tt.ab.cdef.gh.ij.klmno.pq.r", "R");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 14, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      Node internalRS_PQ_MNO_JKL_CDEFG = getChildNode(root, 'p');
+      assertInternalNode(internalRS_PQ_MNO_JKL_CDEFG, 'p', new String[] {"pre",
+            "fi", "xpa", "tt", "er", "n1pa", "tt"}, 14, 14);
+      String[] elementsR = new String[] {"ab", "cdef", "gh", "ij", "klmno",
+            "pq", "r"};
+      char idR = 'a';
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idR, elementsR, "R");
+      String[] elementsPQ_MNO_JKL_CDEFG = new String[] {"er", "n2pa"};
+      char idPQ_MNO_JKL_CDEFG = 'e';
+      internalPQ_MNO_JKL_CDEFG = getChildNode(internalRS_PQ_MNO_JKL_CDEFG,
+            idPQ_MNO_JKL_CDEFG);
+      assertInternalNode(internalPQ_MNO_JKL_CDEFG, idPQ_MNO_JKL_CDEFG,
+            elementsPQ_MNO_JKL_CDEFG, 7, 7);    
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idP, elementsP, "P");
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idQ, elementsQ, "Q");
+      assertInternalNode(internalMNO_JKL_CDEFG, idMNO_JKL_CDEFG,
+            elementsMNO_JKL_CDEFG, 5, 5);
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idM, elementsM, "M");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idN, elementsN, "N");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idO, elementsO, "O");
+      assertInternalNode(internalJKL_CDEFG, idJKL_CDEFG, elementsJKL_CDEFG, 3,
+            3, 2, 2);
+      assertChildLeafNode(internalJKL_CDEFG, idJ, elementsJ, "J");
+      assertChildLeafNode(internalJKL_CDEFG, idK, elementsK, "K");
+      assertChildLeafNode(internalJKL_CDEFG, idL, elementsL, "L");
+      assertInternalNode(internalCDEFG, idCDEFG, elementsCDEFG, 2, 2);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      assertChildLeafNode(internalCDEFG, idH, elementsH, "H");
+      
+      // insert S
+      tree.insert("pre.fi.xpa.tt.er.n1pa.tt.st.uvwx.yz.ab.cdefg.hi.j", "S");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 14, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      assertInternalNode(internalRS_PQ_MNO_JKL_CDEFG, 'p', new String[] {"pre",
+            "fi", "xpa", "tt", "er", "n1pa", "tt"}, 14, 14);
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idR, elementsR, "R");
+      String[] elementsS = new String[] {"st", "uvwx", "yz", "ab", "cdefg",
+            "hi", "j"};
+      char idS = 's';
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idS, elementsS, "S");
+      assertInternalNode(internalPQ_MNO_JKL_CDEFG, idPQ_MNO_JKL_CDEFG,
+            elementsPQ_MNO_JKL_CDEFG, 7, 7);    
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idP, elementsP, "P");
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idQ, elementsQ, "Q");
+      assertInternalNode(internalMNO_JKL_CDEFG, idMNO_JKL_CDEFG,
+            elementsMNO_JKL_CDEFG, 5, 5);
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idM, elementsM, "M");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idN, elementsN, "N");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idO, elementsO, "O");
+      assertInternalNode(internalJKL_CDEFG, idJKL_CDEFG, elementsJKL_CDEFG, 3,
+            3, 2, 2);
+      assertChildLeafNode(internalJKL_CDEFG, idJ, elementsJ, "J");
+      assertChildLeafNode(internalJKL_CDEFG, idK, elementsK, "K");
+      assertChildLeafNode(internalJKL_CDEFG, idL, elementsL, "L");
+      assertInternalNode(internalCDEFG, idCDEFG, elementsCDEFG, 2, 2);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      assertChildLeafNode(internalCDEFG, idH, elementsH, "H");
+      
+      // insert T
+      tree.insert("pre.fi.xpa.tt.er.n1pb.cd.ef.ghij.kl.mn.opqrs.tu.v", "T");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 14, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      Node internalTU_RS_PQ_MNO_JKL_CDEFG = getChildNode(root, 'p');
+      assertInternalNode(internalTU_RS_PQ_MNO_JKL_CDEFG, 'p', new String[] {
+            "pre", "fi", "xpa", "tt", "er", "n1p", }, 14, 14, 4, 4);
+      String[] elementsT = new String[] {"b", "cd", "ef", "ghij", "kl", "mn",
+            "opqrs", "tu", "v"};
+      char idT = 'b';
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idT, elementsT, "T");
+      String[] elementsRS_PQ_MNO_JKL_CDEFG = new String[] {"a", "tt"};
+      char idRS_PQ_MNO_JKL_CDEDFG = 'a';
+      internalRS_PQ_MNO_JKL_CDEFG = getChildNode(internalTU_RS_PQ_MNO_JKL_CDEFG,
+            idRS_PQ_MNO_JKL_CDEDFG);
+      assertInternalNode(internalRS_PQ_MNO_JKL_CDEFG, idRS_PQ_MNO_JKL_CDEDFG,
+            elementsRS_PQ_MNO_JKL_CDEFG,9, 9);
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idR, elementsR, "R");
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idS, elementsS, "S");
+      assertInternalNode(internalPQ_MNO_JKL_CDEFG, idPQ_MNO_JKL_CDEFG,
+            elementsPQ_MNO_JKL_CDEFG, 7, 7);    
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idP, elementsP, "P");
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idQ, elementsQ, "Q");
+      assertInternalNode(internalMNO_JKL_CDEFG, idMNO_JKL_CDEFG,
+            elementsMNO_JKL_CDEFG, 5, 5);
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idM, elementsM, "M");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idN, elementsN, "N");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idO, elementsO, "O");
+      assertInternalNode(internalJKL_CDEFG, idJKL_CDEFG, elementsJKL_CDEFG, 3,
+            3, 2, 2);
+      assertChildLeafNode(internalJKL_CDEFG, idJ, elementsJ, "J");
+      assertChildLeafNode(internalJKL_CDEFG, idK, elementsK, "K");
+      assertChildLeafNode(internalJKL_CDEFG, idL, elementsL, "L");
+      assertInternalNode(internalCDEFG, idCDEFG, elementsCDEFG, 2, 2);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      assertChildLeafNode(internalCDEFG, idH, elementsH, "H");
+      
+      // insert U
+      tree.insert("pre.fi.xpa.tt.er.n1pw.xy.za.bcde.fg.hi.jklmn.op.q", "U");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 14, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      assertInternalNode(internalTU_RS_PQ_MNO_JKL_CDEFG, 'p', new String[] {
+            "pre", "fi", "xpa", "tt", "er", "n1p", }, 14, 14, 4, 4);
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idT, elementsT, "T");
+      String[] elementsU = new String[] {"w", "xy", "za", "bcde", "fg", "hi",
+            "jklmn", "op", "q"};
+      char idU = 'w';
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idU, elementsU, "U");
+      assertInternalNode(internalRS_PQ_MNO_JKL_CDEFG, idRS_PQ_MNO_JKL_CDEDFG,
+            elementsRS_PQ_MNO_JKL_CDEFG,9, 9);
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idR, elementsR, "R");
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idS, elementsS, "S");
+      assertInternalNode(internalPQ_MNO_JKL_CDEFG, idPQ_MNO_JKL_CDEFG,
+            elementsPQ_MNO_JKL_CDEFG, 7, 7);    
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idP, elementsP, "P");
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idQ, elementsQ, "Q");
+      assertInternalNode(internalMNO_JKL_CDEFG, idMNO_JKL_CDEFG,
+            elementsMNO_JKL_CDEFG, 5, 5);
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idM, elementsM, "M");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idN, elementsN, "N");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idO, elementsO, "O");
+      assertInternalNode(internalJKL_CDEFG, idJKL_CDEFG, elementsJKL_CDEFG, 3,
+            3, 2, 2);
+      assertChildLeafNode(internalJKL_CDEFG, idJ, elementsJ, "J");
+      assertChildLeafNode(internalJKL_CDEFG, idK, elementsK, "K");
+      assertChildLeafNode(internalJKL_CDEFG, idL, elementsL, "L");
+      assertInternalNode(internalCDEFG, idCDEFG, elementsCDEFG, 2, 2);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      assertChildLeafNode(internalCDEFG, idH, elementsH, "H");
+      
+      // insert V
+      tree.insert("pre.fi.xpa.tt.er.n2pa.tt.er.n1pa.tt.er.n3suf.fi.x", "V");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 14, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      Node internalVW_TU_RS_PQ_MNO_JKL_CDEFG = getChildNode(root, 'p');
+      assertInternalNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, 'p', new String[] {
+            "pre", "fi", "xpa", "tt", "er", "n", }, 14, 14, 4, 4);
+      String[] elementsV = new String[] {"2pa", "tt", "er", "n1pa", "tt", "er",
+            "n3suf", "fi", "x"};
+      char idV = '2';
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idV, elementsV,
+            "V");
+      String[] elementsTU_RS_PQ_MNO_JKL_CDEFG = new String[] {"1p"};
+      char idTU_RS_PQ_MNO_JKL_CDEFG = '1';
+      assertInternalNode(internalTU_RS_PQ_MNO_JKL_CDEFG, '1',
+            elementsTU_RS_PQ_MNO_JKL_CDEFG, 9, 9, 3, 3);
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idT, elementsT, "T");
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idU, elementsU, "U");
+      assertInternalNode(internalRS_PQ_MNO_JKL_CDEFG, idRS_PQ_MNO_JKL_CDEDFG,
+            elementsRS_PQ_MNO_JKL_CDEFG,9, 9);
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idR, elementsR, "R");
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idS, elementsS, "S");
+      assertInternalNode(internalPQ_MNO_JKL_CDEFG, idPQ_MNO_JKL_CDEFG,
+            elementsPQ_MNO_JKL_CDEFG, 7, 7);    
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idP, elementsP, "P");
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idQ, elementsQ, "Q");
+      assertInternalNode(internalMNO_JKL_CDEFG, idMNO_JKL_CDEFG,
+            elementsMNO_JKL_CDEFG, 5, 5);
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idM, elementsM, "M");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idN, elementsN, "N");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idO, elementsO, "O");
+      assertInternalNode(internalJKL_CDEFG, idJKL_CDEFG, elementsJKL_CDEFG, 3,
+            3, 2, 2);
+      assertChildLeafNode(internalJKL_CDEFG, idJ, elementsJ, "J");
+      assertChildLeafNode(internalJKL_CDEFG, idK, elementsK, "K");
+      assertChildLeafNode(internalJKL_CDEFG, idL, elementsL, "L");
+      assertInternalNode(internalCDEFG, idCDEFG, elementsCDEFG, 2, 2);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      assertChildLeafNode(internalCDEFG, idH, elementsH, "H");
+      
+      // insert W
+      tree.insert("pre.fi.xpa.tt.er.n3papapa.tt.er.npa.tt.er.n1pa.tt.er.n2pa." +
+            "tt.er.n3suf.fi.x", "W");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 20, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      assertInternalNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, 'p', new String[] {
+            "pre", "fi", "xpa", "tt", "er", "n", }, 14, 20, 4, 8);
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idV, elementsV,
+      "V");
+      String[] elementsW = new String[] {"3papapa", "tt", "er", "npa", "tt",
+            "er", "n1pa", "tt", "er", "n2pa", "tt", "er", "n3suf", "fi", "x"};
+      char idW= '3';
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idW, elementsW,
+            "W");
+      assertInternalNode(internalTU_RS_PQ_MNO_JKL_CDEFG, '1',
+            elementsTU_RS_PQ_MNO_JKL_CDEFG, 9, 9, 3, 3);
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idT, elementsT, "T");
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idU, elementsU, "U");
+      assertInternalNode(internalRS_PQ_MNO_JKL_CDEFG, idRS_PQ_MNO_JKL_CDEDFG,
+            elementsRS_PQ_MNO_JKL_CDEFG,9, 9);
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idR, elementsR, "R");
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idS, elementsS, "S");
+      assertInternalNode(internalPQ_MNO_JKL_CDEFG, idPQ_MNO_JKL_CDEFG,
+            elementsPQ_MNO_JKL_CDEFG, 7, 7);    
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idP, elementsP, "P");
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idQ, elementsQ, "Q");
+      assertInternalNode(internalMNO_JKL_CDEFG, idMNO_JKL_CDEFG,
+            elementsMNO_JKL_CDEFG, 5, 5);
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idM, elementsM, "M");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idN, elementsN, "N");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idO, elementsO, "O");
+      assertInternalNode(internalJKL_CDEFG, idJKL_CDEFG, elementsJKL_CDEFG, 3,
+            3, 2, 2);
+      assertChildLeafNode(internalJKL_CDEFG, idJ, elementsJ, "J");
+      assertChildLeafNode(internalJKL_CDEFG, idK, elementsK, "K");
+      assertChildLeafNode(internalJKL_CDEFG, idL, elementsL, "L");
+      assertInternalNode(internalCDEFG, idCDEFG, elementsCDEFG, 2, 2);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      assertChildLeafNode(internalCDEFG, idH, elementsH, "H");
+      
+      // insert X
+      tree.insert("pre.fi.x.pa.tt.pa.tt.er.n1pa.tt.er.n2pa.tt.er.n3suf.fi.x",
+            "X");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 20, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      String[] elementsFromC = new String[] {"pre", "fi", "x"};
+      char idFromC = 'p';
+      Node internalFromC = getChildNode(root, idFromC);
+      assertInternalNode(internalFromC, idFromC, elementsFromC, 14, 20, 1, 3);
+      assertChildLeafNode(internalFromC, KeyPart.KEY_ELEMENT_END,
+            new String[] {"", "pa", "tt", "pa", "tt", "er", "n1pa", "tt", "er",
+            "n2pa", "tt", "er", "n3suf", "fi", "x"}, "X");
+      String[] elementsVW_TU_RS_PQ_MNO_JKL_CDEFG = new String[] {"pa", "tt",
+            "er", "n"}; 
+      char idVW_TU_RS_PQ_MNO_JKL_CDEFG = 'p'; 
+      internalVW_TU_RS_PQ_MNO_JKL_CDEFG = getChildNode(internalFromC,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG);
+      assertInternalNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG, elementsVW_TU_RS_PQ_MNO_JKL_CDEFG, 12,
+            18, 4, 8);
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idV, elementsV,
+      "V");
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idW, elementsW,
+            "W");
+      assertInternalNode(internalTU_RS_PQ_MNO_JKL_CDEFG, '1',
+            elementsTU_RS_PQ_MNO_JKL_CDEFG, 9, 9, 3, 3);
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idT, elementsT, "T");
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idU, elementsU, "U");
+      assertInternalNode(internalRS_PQ_MNO_JKL_CDEFG, idRS_PQ_MNO_JKL_CDEDFG,
+            elementsRS_PQ_MNO_JKL_CDEFG,9, 9);
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idR, elementsR, "R");
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idS, elementsS, "S");
+      assertInternalNode(internalPQ_MNO_JKL_CDEFG, idPQ_MNO_JKL_CDEFG,
+            elementsPQ_MNO_JKL_CDEFG, 7, 7);    
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idP, elementsP, "P");
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idQ, elementsQ, "Q");
+      assertInternalNode(internalMNO_JKL_CDEFG, idMNO_JKL_CDEFG,
+            elementsMNO_JKL_CDEFG, 5, 5);
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idM, elementsM, "M");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idN, elementsN, "N");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idO, elementsO, "O");
+      assertInternalNode(internalJKL_CDEFG, idJKL_CDEFG, elementsJKL_CDEFG, 3,
+            3, 2, 2);
+      assertChildLeafNode(internalJKL_CDEFG, idJ, elementsJ, "J");
+      assertChildLeafNode(internalJKL_CDEFG, idK, elementsK, "K");
+      assertChildLeafNode(internalJKL_CDEFG, idL, elementsL, "L");
+      assertInternalNode(internalCDEFG, idCDEFG, elementsCDEFG, 2, 2);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      assertChildLeafNode(internalCDEFG, idH, elementsH, "H");
+      
+      // insert Y
+      tree.insert("pre.fi.x", "Y");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 20, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      assertInternalNode(internalFromC, idFromC, elementsFromC, 3, 20, 1, 3);
+      String[] elementsXY = new String[] {""};
+      char idXY= KeyPart.KEY_ELEMENT_END;
+      Node internalXY = getChildNode(internalFromC, idXY);
+      assertInternalNode(internalXY, idXY, elementsXY, 1, 15);
+      String[] elementsX = new String[] {"pa", "tt", "pa", "tt", "er",
+            "n1pa", "tt", "er", "n2pa", "tt", "er", "n3suf", "fi", "x"};
+      char idX= 'p';
+      assertChildLeafNode(internalXY, idX, elementsX, "X");
+      String[] elementsY = new String[0];
+      char idY = KeyPart.KEY_ELEMENT_END;
+      assertChildLeafNode(internalXY, idY, elementsY, "Y");
+      internalVW_TU_RS_PQ_MNO_JKL_CDEFG = getChildNode(internalFromC,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG);
+      assertInternalNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG, elementsVW_TU_RS_PQ_MNO_JKL_CDEFG, 12,
+            18, 4, 8);
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idV, elementsV,
+      "V");
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idW, elementsW,
+            "W");
+      assertInternalNode(internalTU_RS_PQ_MNO_JKL_CDEFG, '1',
+            elementsTU_RS_PQ_MNO_JKL_CDEFG, 9, 9, 3, 3);
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idT, elementsT, "T");
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idU, elementsU, "U");
+      assertInternalNode(internalRS_PQ_MNO_JKL_CDEFG, idRS_PQ_MNO_JKL_CDEDFG,
+            elementsRS_PQ_MNO_JKL_CDEFG,9, 9);
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idR, elementsR, "R");
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idS, elementsS, "S");
+      assertInternalNode(internalPQ_MNO_JKL_CDEFG, idPQ_MNO_JKL_CDEFG,
+            elementsPQ_MNO_JKL_CDEFG, 7, 7);    
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idP, elementsP, "P");
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idQ, elementsQ, "Q");
+      assertInternalNode(internalMNO_JKL_CDEFG, idMNO_JKL_CDEFG,
+            elementsMNO_JKL_CDEFG, 5, 5);
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idM, elementsM, "M");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idN, elementsN, "N");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idO, elementsO, "O");
+      assertInternalNode(internalJKL_CDEFG, idJKL_CDEFG, elementsJKL_CDEFG, 3,
+            3, 2, 2);
+      assertChildLeafNode(internalJKL_CDEFG, idJ, elementsJ, "J");
+      assertChildLeafNode(internalJKL_CDEFG, idK, elementsK, "K");
+      assertChildLeafNode(internalJKL_CDEFG, idL, elementsL, "L");
+      assertInternalNode(internalCDEFG, idCDEFG, elementsCDEFG, 2, 2);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      assertChildLeafNode(internalCDEFG, idH, elementsH, "H");
+      
+      // insert Z
+      tree.insert("pre.fi.xsomething.pa.tt.er.n1.pa.tt.er.n2.pa.tt.er.n3.suf." +
+            "fi.x", "Z");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 20, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      assertInternalNode(internalFromC, idFromC, elementsFromC, 3, 20, 1, 10);
+      assertChildLeafNode(internalFromC, 's', new String[] {"something", "pa",
+            "tt", "er", "n1", "pa", "tt", "er", "n2", "pa", "tt", "er", "n3",
+            "suf", "fi", "x"}, "Z");
+      assertInternalNode(internalXY, idXY, elementsXY, 1, 15);
+      assertChildLeafNode(internalXY, idX, elementsX, "X");
+      assertChildLeafNode(internalXY, idY, elementsY, "Y");
+      internalVW_TU_RS_PQ_MNO_JKL_CDEFG = getChildNode(internalFromC,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG);
+      assertInternalNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG, elementsVW_TU_RS_PQ_MNO_JKL_CDEFG, 12,
+            18, 4, 8);
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idV, elementsV,
+      "V");
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idW, elementsW,
+            "W");
+      assertInternalNode(internalTU_RS_PQ_MNO_JKL_CDEFG, '1',
+            elementsTU_RS_PQ_MNO_JKL_CDEFG, 9, 9, 3, 3);
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idT, elementsT, "T");
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idU, elementsU, "U");
+      assertInternalNode(internalRS_PQ_MNO_JKL_CDEFG, idRS_PQ_MNO_JKL_CDEDFG,
+            elementsRS_PQ_MNO_JKL_CDEFG,9, 9);
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idR, elementsR, "R");
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idS, elementsS, "S");
+      assertInternalNode(internalPQ_MNO_JKL_CDEFG, idPQ_MNO_JKL_CDEFG,
+            elementsPQ_MNO_JKL_CDEFG, 7, 7);    
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idP, elementsP, "P");
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idQ, elementsQ, "Q");
+      assertInternalNode(internalMNO_JKL_CDEFG, idMNO_JKL_CDEFG,
+            elementsMNO_JKL_CDEFG, 5, 5);
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idM, elementsM, "M");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idN, elementsN, "N");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idO, elementsO, "O");
+      assertInternalNode(internalJKL_CDEFG, idJKL_CDEFG, elementsJKL_CDEFG, 3,
+            3, 2, 2);
+      assertChildLeafNode(internalJKL_CDEFG, idJ, elementsJ, "J");
+      assertChildLeafNode(internalJKL_CDEFG, idK, elementsK, "K");
+      assertChildLeafNode(internalJKL_CDEFG, idL, elementsL, "L");
+      assertInternalNode(internalCDEFG, idCDEFG, elementsCDEFG, 2, 2);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      assertChildLeafNode(internalCDEFG, idH, elementsH, "H");
+      
+      // insert A1
+      tree.insert("pre.fi.xsomething.pa.tt.er.n1.pa.tt.er.n2.pa.tt.er.n3.suf." +
+            "fi.b", "A1");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 20, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      assertInternalNode(internalFromC, idFromC, elementsFromC, 3, 20, 1, 10);
+      Node internalZA1B1C1 = getChildNode(internalFromC, 's');
+      assertInternalNode(internalZA1B1C1, 's', new String[] {"something", "pa",
+            "tt", "er", "n1", "pa", "tt", "er", "n2", "pa", "tt", "er", "n3",
+            "suf", "fi"}, 16, 16);
+      String[] elementsZ = new String[] {"x"};
+      char idZ = 'x';
+      assertChildLeafNode(internalZA1B1C1, idZ, elementsZ, "Z");
+      String[] elementsA1 = new String[] {"b"};
+      char idA1 = 'b';
+      assertChildLeafNode(internalZA1B1C1, idA1, elementsA1, "A1");
+      assertInternalNode(internalXY, idXY, elementsXY, 1, 15);
+      assertChildLeafNode(internalXY, idX, elementsX, "X");
+      assertChildLeafNode(internalXY, idY, elementsY, "Y");
+      internalVW_TU_RS_PQ_MNO_JKL_CDEFG = getChildNode(internalFromC,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG);
+      assertInternalNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG, elementsVW_TU_RS_PQ_MNO_JKL_CDEFG, 12,
+            18, 4, 8);
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idV, elementsV,
+      "V");
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idW, elementsW,
+            "W");
+      assertInternalNode(internalTU_RS_PQ_MNO_JKL_CDEFG, '1',
+            elementsTU_RS_PQ_MNO_JKL_CDEFG, 9, 9, 3, 3);
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idT, elementsT, "T");
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idU, elementsU, "U");
+      assertInternalNode(internalRS_PQ_MNO_JKL_CDEFG, idRS_PQ_MNO_JKL_CDEDFG,
+            elementsRS_PQ_MNO_JKL_CDEFG,9, 9);
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idR, elementsR, "R");
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idS, elementsS, "S");
+      assertInternalNode(internalPQ_MNO_JKL_CDEFG, idPQ_MNO_JKL_CDEFG,
+            elementsPQ_MNO_JKL_CDEFG, 7, 7);    
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idP, elementsP, "P");
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idQ, elementsQ, "Q");
+      assertInternalNode(internalMNO_JKL_CDEFG, idMNO_JKL_CDEFG,
+            elementsMNO_JKL_CDEFG, 5, 5);
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idM, elementsM, "M");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idN, elementsN, "N");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idO, elementsO, "O");
+      assertInternalNode(internalJKL_CDEFG, idJKL_CDEFG, elementsJKL_CDEFG, 3,
+            3, 2, 2);
+      assertChildLeafNode(internalJKL_CDEFG, idJ, elementsJ, "J");
+      assertChildLeafNode(internalJKL_CDEFG, idK, elementsK, "K");
+      assertChildLeafNode(internalJKL_CDEFG, idL, elementsL, "L");
+      assertInternalNode(internalCDEFG, idCDEFG, elementsCDEFG, 2, 2);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      assertChildLeafNode(internalCDEFG, idH, elementsH, "H");
+      
+      // insert B1
+      tree.insert("pre.fi.xsomething.pa.tt.er.n1.pa.tt.er.n2.pa.tt.er.n3.suf." +
+            "fi.defgh", "B1");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 20, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      assertInternalNode(internalFromC, idFromC, elementsFromC, 3, 20, 1, 10);
+      assertInternalNode(internalZA1B1C1, 's', new String[] {"something", "pa",
+            "tt", "er", "n1", "pa", "tt", "er", "n2", "pa", "tt", "er", "n3",
+            "suf", "fi"}, 16, 16);
+      assertChildLeafNode(internalZA1B1C1, idZ, elementsZ, "Z");
+      assertChildLeafNode(internalZA1B1C1, idA1, elementsA1, "A1");
+      String[] elementsB1 = new String[] {"defgh"};
+      char idB1 = 'd';
+      assertChildLeafNode(internalZA1B1C1, idB1, elementsB1, "B1");
+      assertInternalNode(internalXY, idXY, elementsXY, 1, 15);
+      assertChildLeafNode(internalXY, idX, elementsX, "X");
+      assertChildLeafNode(internalXY, idY, elementsY, "Y");
+      internalVW_TU_RS_PQ_MNO_JKL_CDEFG = getChildNode(internalFromC,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG);
+      assertInternalNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG, elementsVW_TU_RS_PQ_MNO_JKL_CDEFG, 12,
+            18, 4, 8);
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idV, elementsV,
+      "V");
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idW, elementsW,
+            "W");
+      assertInternalNode(internalTU_RS_PQ_MNO_JKL_CDEFG, '1',
+            elementsTU_RS_PQ_MNO_JKL_CDEFG, 9, 9, 3, 3);
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idT, elementsT, "T");
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idU, elementsU, "U");
+      assertInternalNode(internalRS_PQ_MNO_JKL_CDEFG, idRS_PQ_MNO_JKL_CDEDFG,
+            elementsRS_PQ_MNO_JKL_CDEFG,9, 9);
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idR, elementsR, "R");
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idS, elementsS, "S");
+      assertInternalNode(internalPQ_MNO_JKL_CDEFG, idPQ_MNO_JKL_CDEFG,
+            elementsPQ_MNO_JKL_CDEFG, 7, 7);    
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idP, elementsP, "P");
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idQ, elementsQ, "Q");
+      assertInternalNode(internalMNO_JKL_CDEFG, idMNO_JKL_CDEFG,
+            elementsMNO_JKL_CDEFG, 5, 5);
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idM, elementsM, "M");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idN, elementsN, "N");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idO, elementsO, "O");
+      assertInternalNode(internalJKL_CDEFG, idJKL_CDEFG, elementsJKL_CDEFG, 3,
+            3, 2, 2);
+      assertChildLeafNode(internalJKL_CDEFG, idJ, elementsJ, "J");
+      assertChildLeafNode(internalJKL_CDEFG, idK, elementsK, "K");
+      assertChildLeafNode(internalJKL_CDEFG, idL, elementsL, "L");
+      assertInternalNode(internalCDEFG, idCDEFG, elementsCDEFG, 2, 2);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      assertChildLeafNode(internalCDEFG, idH, elementsH, "H");
+      
+      // insert C1
+      tree.insert("pre.fi.xsomething.pa.tt.er.n1.pa.tt.er.n2.pa.tt.er.n3.suf." +
+            "fi.zap", "C1");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 20, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      assertInternalNode(internalFromC, idFromC, elementsFromC, 3, 20, 1, 10);
+      assertInternalNode(internalZA1B1C1, 's', new String[] {"something", "pa",
+            "tt", "er", "n1", "pa", "tt", "er", "n2", "pa", "tt", "er", "n3",
+            "suf", "fi"}, 16, 16);
+      assertChildLeafNode(internalZA1B1C1, idZ, elementsZ, "Z");
+      assertChildLeafNode(internalZA1B1C1, idA1, elementsA1, "A1");
+      assertChildLeafNode(internalZA1B1C1, idB1, elementsB1, "B1");
+      String[] elementsC1 = new String[] {"zap"};
+      char idC1 = 'z';
+      assertChildLeafNode(internalZA1B1C1, idC1, elementsC1, "C1");
+      assertInternalNode(internalXY, idXY, elementsXY, 1, 15);
+      assertChildLeafNode(internalXY, idX, elementsX, "X");
+      assertChildLeafNode(internalXY, idY, elementsY, "Y");
+      internalVW_TU_RS_PQ_MNO_JKL_CDEFG = getChildNode(internalFromC,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG);
+      assertInternalNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG, elementsVW_TU_RS_PQ_MNO_JKL_CDEFG, 12,
+            18, 4, 8);
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idV, elementsV,
+      "V");
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idW, elementsW,
+            "W");
+      assertInternalNode(internalTU_RS_PQ_MNO_JKL_CDEFG, '1',
+            elementsTU_RS_PQ_MNO_JKL_CDEFG, 9, 9, 3, 3);
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idT, elementsT, "T");
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idU, elementsU, "U");
+      assertInternalNode(internalRS_PQ_MNO_JKL_CDEFG, idRS_PQ_MNO_JKL_CDEDFG,
+            elementsRS_PQ_MNO_JKL_CDEFG,9, 9);
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idR, elementsR, "R");
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idS, elementsS, "S");
+      assertInternalNode(internalPQ_MNO_JKL_CDEFG, idPQ_MNO_JKL_CDEFG,
+            elementsPQ_MNO_JKL_CDEFG, 7, 7);    
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idP, elementsP, "P");
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idQ, elementsQ, "Q");
+      assertInternalNode(internalMNO_JKL_CDEFG, idMNO_JKL_CDEFG,
+            elementsMNO_JKL_CDEFG, 5, 5);
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idM, elementsM, "M");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idN, elementsN, "N");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idO, elementsO, "O");
+      assertInternalNode(internalJKL_CDEFG, idJKL_CDEFG, elementsJKL_CDEFG, 3,
+            3, 2, 2);
+      assertChildLeafNode(internalJKL_CDEFG, idJ, elementsJ, "J");
+      assertChildLeafNode(internalJKL_CDEFG, idK, elementsK, "K");
+      assertChildLeafNode(internalJKL_CDEFG, idL, elementsL, "L");
+      assertInternalNode(internalCDEFG, idCDEFG, elementsCDEFG, 2, 2);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      assertChildLeafNode(internalCDEFG, idH, elementsH, "H");
+      
+      // insert D1
+      tree.insert("pre.fi.xsomething.pa.tt.er.n1.pa.tt.er.n2.pa.tt.er.n3.suf." +
+            "fa.b", "D1");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 20, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      assertInternalNode(internalFromC, idFromC, elementsFromC, 3, 20, 1, 10);
+      Node internalD1E1_ZA1B1C1 = getChildNode(internalFromC, 's');
+      assertInternalNode(internalD1E1_ZA1B1C1, 's', new String[] {"something",
+            "pa", "tt", "er", "n1", "pa", "tt", "er", "n2", "pa", "tt", "er",
+            "n3", "suf", "f"}, 16, 16, 2, 2);
+      String[] elementsD1 = new String[] {"a", "b"};
+      char idD1 = 'a';
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idD1, elementsD1, "D1");
+      String[] elementsZA1B1C1 = new String[] {"i"};
+      char idZA1B1C1 = 'i';
+      internalZA1B1C1 = getChildNode(internalD1E1_ZA1B1C1, idZA1B1C1);
+      assertInternalNode(internalZA1B1C1, idZA1B1C1, elementsZA1B1C1, 2, 2);
+      assertChildLeafNode(internalZA1B1C1, idZ, elementsZ, "Z");
+      assertChildLeafNode(internalZA1B1C1, idA1, elementsA1, "A1");
+      assertChildLeafNode(internalZA1B1C1, idB1, elementsB1, "B1");
+      assertChildLeafNode(internalZA1B1C1, idC1, elementsC1, "C1");
+      assertInternalNode(internalXY, idXY, elementsXY, 1, 15);
+      assertChildLeafNode(internalXY, idX, elementsX, "X");
+      assertChildLeafNode(internalXY, idY, elementsY, "Y");
+      internalVW_TU_RS_PQ_MNO_JKL_CDEFG = getChildNode(internalFromC,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG);
+      assertInternalNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG, elementsVW_TU_RS_PQ_MNO_JKL_CDEFG, 12,
+            18, 4, 8);
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idV, elementsV,
+            "V");
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idW, elementsW,
+            "W");
+      assertInternalNode(internalTU_RS_PQ_MNO_JKL_CDEFG, '1',
+            elementsTU_RS_PQ_MNO_JKL_CDEFG, 9, 9, 3, 3);
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idT, elementsT, "T");
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idU, elementsU, "U");
+      assertInternalNode(internalRS_PQ_MNO_JKL_CDEFG, idRS_PQ_MNO_JKL_CDEDFG,
+            elementsRS_PQ_MNO_JKL_CDEFG,9, 9);
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idR, elementsR, "R");
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idS, elementsS, "S");
+      assertInternalNode(internalPQ_MNO_JKL_CDEFG, idPQ_MNO_JKL_CDEFG,
+            elementsPQ_MNO_JKL_CDEFG, 7, 7);    
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idP, elementsP, "P");
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idQ, elementsQ, "Q");
+      assertInternalNode(internalMNO_JKL_CDEFG, idMNO_JKL_CDEFG,
+            elementsMNO_JKL_CDEFG, 5, 5);
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idM, elementsM, "M");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idN, elementsN, "N");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idO, elementsO, "O");
+      assertInternalNode(internalJKL_CDEFG, idJKL_CDEFG, elementsJKL_CDEFG, 3,
+            3, 2, 2);
+      assertChildLeafNode(internalJKL_CDEFG, idJ, elementsJ, "J");
+      assertChildLeafNode(internalJKL_CDEFG, idK, elementsK, "K");
+      assertChildLeafNode(internalJKL_CDEFG, idL, elementsL, "L");
+      assertInternalNode(internalCDEFG, idCDEFG, elementsCDEFG, 2, 2);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      assertChildLeafNode(internalCDEFG, idH, elementsH, "H");
+      
+      // insert E1
+      tree.insert("pre.fi.xsomething.pa.tt.er.n1.pa.tt.er.n2.pa.tt.er.n3.suf." +
+            "fdefgh.hijkl", "E1");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 20, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      assertInternalNode(internalFromC, idFromC, elementsFromC, 3, 20, 1, 10);
+      assertInternalNode(internalD1E1_ZA1B1C1, 's', new String[] {"something",
+            "pa", "tt", "er", "n1", "pa", "tt", "er", "n2", "pa", "tt", "er",
+            "n3", "suf", "f"}, 16, 16, 2, 6);
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idD1, elementsD1, "D1");
+      String[] elementsE1 = new String[] {"defgh", "hijkl"};
+      char idE1 = 'd';
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idE1, elementsE1, "E1");
+      assertInternalNode(internalZA1B1C1, idZA1B1C1, elementsZA1B1C1, 2, 2);
+      assertChildLeafNode(internalZA1B1C1, idZ, elementsZ, "Z");
+      assertChildLeafNode(internalZA1B1C1, idA1, elementsA1, "A1");
+      assertChildLeafNode(internalZA1B1C1, idB1, elementsB1, "B1");
+      assertChildLeafNode(internalZA1B1C1, idC1, elementsC1, "C1");
+      assertInternalNode(internalXY, idXY, elementsXY, 1, 15);
+      assertChildLeafNode(internalXY, idX, elementsX, "X");
+      assertChildLeafNode(internalXY, idY, elementsY, "Y");
+      internalVW_TU_RS_PQ_MNO_JKL_CDEFG = getChildNode(internalFromC,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG);
+      assertInternalNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG, elementsVW_TU_RS_PQ_MNO_JKL_CDEFG, 12,
+            18, 4, 8);
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idV, elementsV,
+      "V");
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idW, elementsW,
+            "W");
+      assertInternalNode(internalTU_RS_PQ_MNO_JKL_CDEFG, '1',
+            elementsTU_RS_PQ_MNO_JKL_CDEFG, 9, 9, 3, 3);
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idT, elementsT, "T");
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idU, elementsU, "U");
+      assertInternalNode(internalRS_PQ_MNO_JKL_CDEFG, idRS_PQ_MNO_JKL_CDEDFG,
+            elementsRS_PQ_MNO_JKL_CDEFG,9, 9);
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idR, elementsR, "R");
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idS, elementsS, "S");
+      assertInternalNode(internalPQ_MNO_JKL_CDEFG, idPQ_MNO_JKL_CDEFG,
+            elementsPQ_MNO_JKL_CDEFG, 7, 7);    
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idP, elementsP, "P");
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idQ, elementsQ, "Q");
+      assertInternalNode(internalMNO_JKL_CDEFG, idMNO_JKL_CDEFG,
+            elementsMNO_JKL_CDEFG, 5, 5);
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idM, elementsM, "M");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idN, elementsN, "N");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idO, elementsO, "O");
+      assertInternalNode(internalJKL_CDEFG, idJKL_CDEFG, elementsJKL_CDEFG, 3,
+            3, 2, 2);
+      assertChildLeafNode(internalJKL_CDEFG, idJ, elementsJ, "J");
+      assertChildLeafNode(internalJKL_CDEFG, idK, elementsK, "K");
+      assertChildLeafNode(internalJKL_CDEFG, idL, elementsL, "L");
+      assertInternalNode(internalCDEFG, idCDEFG, elementsCDEFG, 2, 2);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      assertChildLeafNode(internalCDEFG, idH, elementsH, "H");
+      
+      // insert F1
+      tree.insert("pre.fi.xsomething.pa.tt.er.n1.pa.tt.er.n2.pa.tt.er.n3." +
+            "suabcdefgh.abc.abc", "F1");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 20, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      assertInternalNode(internalFromC, idFromC, elementsFromC, 3, 20, 1, 10);
+      Node internalF1G1H1_D1E1_ZA1B1C1 = getChildNode(internalFromC, 's');
+      assertInternalNode(internalF1G1H1_D1E1_ZA1B1C1, 's', new String[] {
+            "something", "pa", "tt", "er", "n1", "pa", "tt", "er", "n2", "pa",
+            "tt", "er", "n3", "su"}, 16, 16, 3, 10);
+      String[] elementsF1 = new String[] {"abcdefgh", "abc", "abc"};
+      char idF1 = 'a';
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idF1, elementsF1, "F1");
+      String[] elementsD1E1_ZA1B1C1 = new String[] {"f", "f"};
+      char idD1E1_ZA1B1C1 = 'f'; 
+      internalD1E1_ZA1B1C1 = getChildNode(internalF1G1H1_D1E1_ZA1B1C1,
+            idD1E1_ZA1B1C1);
+      assertInternalNode(internalD1E1_ZA1B1C1, idD1E1_ZA1B1C1,
+            elementsD1E1_ZA1B1C1, 3, 3, 2, 6);
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idD1, elementsD1, "D1");
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idE1, elementsE1, "E1");
+      assertInternalNode(internalZA1B1C1, idZA1B1C1, elementsZA1B1C1, 2, 2);
+      assertChildLeafNode(internalZA1B1C1, idZ, elementsZ, "Z");
+      assertChildLeafNode(internalZA1B1C1, idA1, elementsA1, "A1");
+      assertChildLeafNode(internalZA1B1C1, idB1, elementsB1, "B1");
+      assertChildLeafNode(internalZA1B1C1, idC1, elementsC1, "C1");
+      assertInternalNode(internalXY, idXY, elementsXY, 1, 15);
+      assertChildLeafNode(internalXY, idX, elementsX, "X");
+      assertChildLeafNode(internalXY, idY, elementsY, "Y");
+      internalVW_TU_RS_PQ_MNO_JKL_CDEFG = getChildNode(internalFromC,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG);
+      assertInternalNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG, elementsVW_TU_RS_PQ_MNO_JKL_CDEFG, 12,
+            18, 4, 8);
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idV, elementsV,
+      "V");
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idW, elementsW,
+            "W");
+      assertInternalNode(internalTU_RS_PQ_MNO_JKL_CDEFG, '1',
+            elementsTU_RS_PQ_MNO_JKL_CDEFG, 9, 9, 3, 3);
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idT, elementsT, "T");
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idU, elementsU, "U");
+      assertInternalNode(internalRS_PQ_MNO_JKL_CDEFG, idRS_PQ_MNO_JKL_CDEDFG,
+            elementsRS_PQ_MNO_JKL_CDEFG,9, 9);
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idR, elementsR, "R");
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idS, elementsS, "S");
+      assertInternalNode(internalPQ_MNO_JKL_CDEFG, idPQ_MNO_JKL_CDEFG,
+            elementsPQ_MNO_JKL_CDEFG, 7, 7);    
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idP, elementsP, "P");
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idQ, elementsQ, "Q");
+      assertInternalNode(internalMNO_JKL_CDEFG, idMNO_JKL_CDEFG,
+            elementsMNO_JKL_CDEFG, 5, 5);
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idM, elementsM, "M");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idN, elementsN, "N");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idO, elementsO, "O");
+      assertInternalNode(internalJKL_CDEFG, idJKL_CDEFG, elementsJKL_CDEFG, 3,
+            3, 2, 2);
+      assertChildLeafNode(internalJKL_CDEFG, idJ, elementsJ, "J");
+      assertChildLeafNode(internalJKL_CDEFG, idK, elementsK, "K");
+      assertChildLeafNode(internalJKL_CDEFG, idL, elementsL, "L");
+      assertInternalNode(internalCDEFG, idCDEFG, elementsCDEFG, 2, 2);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      assertChildLeafNode(internalCDEFG, idH, elementsH, "H");
+      
+      // insert G1
+      tree.insert("pre.fi.xsomething.pa.tt.er.n1.pa.tt.er.n2.pa.tt.er.n3." +
+            "suhello.worl.d", "G1");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 20, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      assertInternalNode(internalFromC, idFromC, elementsFromC, 3, 20, 1, 10);
+      assertInternalNode(internalF1G1H1_D1E1_ZA1B1C1, 's', new String[] {
+            "something", "pa", "tt", "er", "n1", "pa", "tt", "er", "n2", "pa",
+            "tt", "er", "n3", "su"}, 16, 16, 3, 10);
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idF1, elementsF1, "F1");
+      String[] elementsG1 = new String[] {"hello", "worl", "d"};
+      char idG1 = 'h';
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idG1, elementsG1, "G1");
+      internalD1E1_ZA1B1C1 = getChildNode(internalF1G1H1_D1E1_ZA1B1C1,
+            idD1E1_ZA1B1C1);
+      assertInternalNode(internalD1E1_ZA1B1C1, idD1E1_ZA1B1C1,
+            elementsD1E1_ZA1B1C1, 3, 3, 2, 6);
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idD1, elementsD1, "D1");
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idE1, elementsE1, "E1");
+      assertInternalNode(internalZA1B1C1, idZA1B1C1, elementsZA1B1C1, 2, 2);
+      assertChildLeafNode(internalZA1B1C1, idZ, elementsZ, "Z");
+      assertChildLeafNode(internalZA1B1C1, idA1, elementsA1, "A1");
+      assertChildLeafNode(internalZA1B1C1, idB1, elementsB1, "B1");
+      assertChildLeafNode(internalZA1B1C1, idC1, elementsC1, "C1");
+      assertInternalNode(internalXY, idXY, elementsXY, 1, 15);
+      assertChildLeafNode(internalXY, idX, elementsX, "X");
+      assertChildLeafNode(internalXY, idY, elementsY, "Y");
+      internalVW_TU_RS_PQ_MNO_JKL_CDEFG = getChildNode(internalFromC,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG);
+      assertInternalNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG, elementsVW_TU_RS_PQ_MNO_JKL_CDEFG, 12,
+            18, 4, 8);
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idV, elementsV,
+      "V");
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idW, elementsW,
+            "W");
+      assertInternalNode(internalTU_RS_PQ_MNO_JKL_CDEFG, '1',
+            elementsTU_RS_PQ_MNO_JKL_CDEFG, 9, 9, 3, 3);
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idT, elementsT, "T");
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idU, elementsU, "U");
+      assertInternalNode(internalRS_PQ_MNO_JKL_CDEFG, idRS_PQ_MNO_JKL_CDEDFG,
+            elementsRS_PQ_MNO_JKL_CDEFG,9, 9);
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idR, elementsR, "R");
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idS, elementsS, "S");
+      assertInternalNode(internalPQ_MNO_JKL_CDEFG, idPQ_MNO_JKL_CDEFG,
+            elementsPQ_MNO_JKL_CDEFG, 7, 7);    
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idP, elementsP, "P");
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idQ, elementsQ, "Q");
+      assertInternalNode(internalMNO_JKL_CDEFG, idMNO_JKL_CDEFG,
+            elementsMNO_JKL_CDEFG, 5, 5);
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idM, elementsM, "M");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idN, elementsN, "N");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idO, elementsO, "O");
+      assertInternalNode(internalJKL_CDEFG, idJKL_CDEFG, elementsJKL_CDEFG, 3,
+            3, 2, 2);
+      assertChildLeafNode(internalJKL_CDEFG, idJ, elementsJ, "J");
+      assertChildLeafNode(internalJKL_CDEFG, idK, elementsK, "K");
+      assertChildLeafNode(internalJKL_CDEFG, idL, elementsL, "L");
+      assertInternalNode(internalCDEFG, idCDEFG, elementsCDEFG, 2, 2);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      assertChildLeafNode(internalCDEFG, idH, elementsH, "H");
+      
+      // insert H1
+      tree.insert("pre.fi.xsomething.pa.tt.er.n1.pa.tt.er.n2.pa.tt.er.n3.sus." +
+            "ome.thing", "H1");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 20, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      assertInternalNode(internalFromC, idFromC, elementsFromC, 3, 20, 1, 10);
+      assertInternalNode(internalF1G1H1_D1E1_ZA1B1C1, 's', new String[] {
+            "something", "pa", "tt", "er", "n1", "pa", "tt", "er", "n2", "pa",
+            "tt", "er", "n3", "su"}, 16, 16, 3, 10);
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idF1, elementsF1, "F1");
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idG1, elementsG1, "G1");
+      String[] elementsH1 = new String[] {"s", "ome", "thing"};
+      char idH1 = 's';
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idH1, elementsH1, "H1");
+      internalD1E1_ZA1B1C1 = getChildNode(internalF1G1H1_D1E1_ZA1B1C1,
+            idD1E1_ZA1B1C1);
+      assertInternalNode(internalD1E1_ZA1B1C1, idD1E1_ZA1B1C1,
+            elementsD1E1_ZA1B1C1, 3, 3, 2, 6);
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idD1, elementsD1, "D1");
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idE1, elementsE1, "E1");
+      assertInternalNode(internalZA1B1C1, idZA1B1C1, elementsZA1B1C1, 2, 2);
+      assertChildLeafNode(internalZA1B1C1, idZ, elementsZ, "Z");
+      assertChildLeafNode(internalZA1B1C1, idA1, elementsA1, "A1");
+      assertChildLeafNode(internalZA1B1C1, idB1, elementsB1, "B1");
+      assertChildLeafNode(internalZA1B1C1, idC1, elementsC1, "C1");
+      assertInternalNode(internalXY, idXY, elementsXY, 1, 15);
+      assertChildLeafNode(internalXY, idX, elementsX, "X");
+      assertChildLeafNode(internalXY, idY, elementsY, "Y");
+      internalVW_TU_RS_PQ_MNO_JKL_CDEFG = getChildNode(internalFromC,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG);
+      assertInternalNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG, elementsVW_TU_RS_PQ_MNO_JKL_CDEFG, 12,
+            18, 4, 8);
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idV, elementsV,
+      "V");
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idW, elementsW,
+            "W");
+      assertInternalNode(internalTU_RS_PQ_MNO_JKL_CDEFG, '1',
+            elementsTU_RS_PQ_MNO_JKL_CDEFG, 9, 9, 3, 3);
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idT, elementsT, "T");
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idU, elementsU, "U");
+      assertInternalNode(internalRS_PQ_MNO_JKL_CDEFG, idRS_PQ_MNO_JKL_CDEDFG,
+            elementsRS_PQ_MNO_JKL_CDEFG,9, 9);
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idR, elementsR, "R");
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idS, elementsS, "S");
+      assertInternalNode(internalPQ_MNO_JKL_CDEFG, idPQ_MNO_JKL_CDEFG,
+            elementsPQ_MNO_JKL_CDEFG, 7, 7);    
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idP, elementsP, "P");
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idQ, elementsQ, "Q");
+      assertInternalNode(internalMNO_JKL_CDEFG, idMNO_JKL_CDEFG,
+            elementsMNO_JKL_CDEFG, 5, 5);
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idM, elementsM, "M");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idN, elementsN, "N");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idO, elementsO, "O");
+      assertInternalNode(internalJKL_CDEFG, idJKL_CDEFG, elementsJKL_CDEFG, 3,
+            3, 2, 2);
+      assertChildLeafNode(internalJKL_CDEFG, idJ, elementsJ, "J");
+      assertChildLeafNode(internalJKL_CDEFG, idK, elementsK, "K");
+      assertChildLeafNode(internalJKL_CDEFG, idL, elementsL, "L");
+      assertInternalNode(internalCDEFG, idCDEFG, elementsCDEFG, 2, 2);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      assertChildLeafNode(internalCDEFG, idH, elementsH, "H");
+      
+      // insert I1
+      tree.insert("pre.fi.xsomething.pa.tt.er.n1.pa.tt.er.n2.ppa.tt.er.n3suf." +
+            "fi.x", "I1");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 20, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      assertInternalNode(internalFromC, idFromC, elementsFromC, 3, 20, 1, 10);
+      Node internalI1J1_F1G1H1_D1E1_ZA1B1C1 = getChildNode(internalFromC, 's');
+      assertInternalNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1, 's', new String[] {
+            "something", "pa", "tt", "er", "n1", "pa", "tt", "er", "n2", "p"},
+            15, 16, 2, 3);
+      String[] elementsI1 = new String[] {"pa", "tt", "er", "n3suf", "fi", "x"};
+      char idI1 = 'p';
+      assertChildLeafNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1, idI1, elementsI1,
+            "I1");
+      String[] elementsF1G1H1_D1E1_ZA1B1C1 = new String[] {"a", "tt", "er",
+            "n3", "su"};
+      char idF1G1H1_D1E1_ZA1B1C1 = 'a';
+      internalF1G1H1_D1E1_ZA1B1C1 = getChildNode(
+            internalI1J1_F1G1H1_D1E1_ZA1B1C1, idF1G1H1_D1E1_ZA1B1C1);
+      assertInternalNode(internalF1G1H1_D1E1_ZA1B1C1, idF1G1H1_D1E1_ZA1B1C1,
+            elementsF1G1H1_D1E1_ZA1B1C1, 7, 7, 3, 10);
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idF1, elementsF1, "F1");
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idG1, elementsG1, "G1");
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idH1, elementsH1, "H1");
+      internalD1E1_ZA1B1C1 = getChildNode(internalF1G1H1_D1E1_ZA1B1C1,
+            idD1E1_ZA1B1C1);
+      assertInternalNode(internalD1E1_ZA1B1C1, idD1E1_ZA1B1C1,
+            elementsD1E1_ZA1B1C1, 3, 3, 2, 6);
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idD1, elementsD1, "D1");
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idE1, elementsE1, "E1");
+      assertInternalNode(internalZA1B1C1, idZA1B1C1, elementsZA1B1C1, 2, 2);
+      assertChildLeafNode(internalZA1B1C1, idZ, elementsZ, "Z");
+      assertChildLeafNode(internalZA1B1C1, idA1, elementsA1, "A1");
+      assertChildLeafNode(internalZA1B1C1, idB1, elementsB1, "B1");
+      assertChildLeafNode(internalZA1B1C1, idC1, elementsC1, "C1");
+      assertInternalNode(internalXY, idXY, elementsXY, 1, 15);
+      assertChildLeafNode(internalXY, idX, elementsX, "X");
+      assertChildLeafNode(internalXY, idY, elementsY, "Y");
+      internalVW_TU_RS_PQ_MNO_JKL_CDEFG = getChildNode(internalFromC,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG);
+      assertInternalNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG, elementsVW_TU_RS_PQ_MNO_JKL_CDEFG, 12,
+            18, 4, 8);
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idV, elementsV,
+      "V");
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idW, elementsW,
+            "W");
+      assertInternalNode(internalTU_RS_PQ_MNO_JKL_CDEFG, '1',
+            elementsTU_RS_PQ_MNO_JKL_CDEFG, 9, 9, 3, 3);
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idT, elementsT, "T");
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idU, elementsU, "U");
+      assertInternalNode(internalRS_PQ_MNO_JKL_CDEFG, idRS_PQ_MNO_JKL_CDEDFG,
+            elementsRS_PQ_MNO_JKL_CDEFG,9, 9);
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idR, elementsR, "R");
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idS, elementsS, "S");
+      assertInternalNode(internalPQ_MNO_JKL_CDEFG, idPQ_MNO_JKL_CDEFG,
+            elementsPQ_MNO_JKL_CDEFG, 7, 7);    
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idP, elementsP, "P");
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idQ, elementsQ, "Q");
+      assertInternalNode(internalMNO_JKL_CDEFG, idMNO_JKL_CDEFG,
+            elementsMNO_JKL_CDEFG, 5, 5);
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idM, elementsM, "M");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idN, elementsN, "N");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idO, elementsO, "O");
+      assertInternalNode(internalJKL_CDEFG, idJKL_CDEFG, elementsJKL_CDEFG, 3,
+            3, 2, 2);
+      assertChildLeafNode(internalJKL_CDEFG, idJ, elementsJ, "J");
+      assertChildLeafNode(internalJKL_CDEFG, idK, elementsK, "K");
+      assertChildLeafNode(internalJKL_CDEFG, idL, elementsL, "L");
+      assertInternalNode(internalCDEFG, idCDEFG, elementsCDEFG, 2, 2);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      assertChildLeafNode(internalCDEFG, idH, elementsH, "H");
+
+      // insert J1
+      tree.insert("pre.fi.xsomething.pa.tt.er.n1.pa.tt.er.n2.pcdefghij.pa.tt." +
+            "er.n3suf.fix", "J1");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 20, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      assertInternalNode(internalFromC, idFromC, elementsFromC, 3, 20, 1, 10);
+      assertInternalNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1, 's', new String[] {
+            "something", "pa", "tt", "er", "n1", "pa", "tt", "er", "n2", "p"},
+            15, 16, 2, 9);
+      assertChildLeafNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1, idI1, elementsI1,
+      "I1");
+      String[] elementsJ1 = new String[] {"cdefghij", "pa", "tt", "er", "n3suf",
+            "fix"};
+      char idJ1 = 'c';
+      assertChildLeafNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1, idJ1, elementsJ1,
+            "J1");
+      assertInternalNode(internalF1G1H1_D1E1_ZA1B1C1, idF1G1H1_D1E1_ZA1B1C1,
+            elementsF1G1H1_D1E1_ZA1B1C1, 7, 7, 3, 10);
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idF1, elementsF1, "F1");
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idG1, elementsG1, "G1");
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idH1, elementsH1, "H1");
+      internalD1E1_ZA1B1C1 = getChildNode(internalF1G1H1_D1E1_ZA1B1C1,
+            idD1E1_ZA1B1C1);
+      assertInternalNode(internalD1E1_ZA1B1C1, idD1E1_ZA1B1C1,
+            elementsD1E1_ZA1B1C1, 3, 3, 2, 6);
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idD1, elementsD1, "D1");
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idE1, elementsE1, "E1");
+      assertInternalNode(internalZA1B1C1, idZA1B1C1, elementsZA1B1C1, 2, 2);
+      assertChildLeafNode(internalZA1B1C1, idZ, elementsZ, "Z");
+      assertChildLeafNode(internalZA1B1C1, idA1, elementsA1, "A1");
+      assertChildLeafNode(internalZA1B1C1, idB1, elementsB1, "B1");
+      assertChildLeafNode(internalZA1B1C1, idC1, elementsC1, "C1");
+      assertInternalNode(internalXY, idXY, elementsXY, 1, 15);
+      assertChildLeafNode(internalXY, idX, elementsX, "X");
+      assertChildLeafNode(internalXY, idY, elementsY, "Y");
+      internalVW_TU_RS_PQ_MNO_JKL_CDEFG = getChildNode(internalFromC,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG);
+      assertInternalNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG, elementsVW_TU_RS_PQ_MNO_JKL_CDEFG, 12,
+            18, 4, 8);
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idV, elementsV,
+      "V");
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idW, elementsW,
+            "W");
+      assertInternalNode(internalTU_RS_PQ_MNO_JKL_CDEFG, '1',
+            elementsTU_RS_PQ_MNO_JKL_CDEFG, 9, 9, 3, 3);
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idT, elementsT, "T");
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idU, elementsU, "U");
+      assertInternalNode(internalRS_PQ_MNO_JKL_CDEFG, idRS_PQ_MNO_JKL_CDEDFG,
+            elementsRS_PQ_MNO_JKL_CDEFG,9, 9);
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idR, elementsR, "R");
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idS, elementsS, "S");
+      assertInternalNode(internalPQ_MNO_JKL_CDEFG, idPQ_MNO_JKL_CDEFG,
+            elementsPQ_MNO_JKL_CDEFG, 7, 7);    
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idP, elementsP, "P");
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idQ, elementsQ, "Q");
+      assertInternalNode(internalMNO_JKL_CDEFG, idMNO_JKL_CDEFG,
+            elementsMNO_JKL_CDEFG, 5, 5);
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idM, elementsM, "M");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idN, elementsN, "N");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idO, elementsO, "O");
+      assertInternalNode(internalJKL_CDEFG, idJKL_CDEFG, elementsJKL_CDEFG, 3,
+            3, 2, 2);
+      assertChildLeafNode(internalJKL_CDEFG, idJ, elementsJ, "J");
+      assertChildLeafNode(internalJKL_CDEFG, idK, elementsK, "K");
+      assertChildLeafNode(internalJKL_CDEFG, idL, elementsL, "L");
+      assertInternalNode(internalCDEFG, idCDEFG, elementsCDEFG, 2, 2);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      assertChildLeafNode(internalCDEFG, idH, elementsH, "H");
+      
+      // insert K1
+      tree.insert("pre.fi.xsomething", "K1");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 20, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      assertInternalNode(internalFromC, idFromC, elementsFromC, 3, 20, 1, 10);
+      String[] elementsK1_I1J1_F1G1H1_D1E1_ZA1B1C1 = new String[] {"something"};
+      char idK1_I1J1_F1G1H1_D1E1_ZA1B1C1 = 's';
+      Node internalK1_I1J1_F1G1H1_D1E1_ZA1B1C1 = getChildNode(internalFromC,
+            idK1_I1J1_F1G1H1_D1E1_ZA1B1C1);
+      assertInternalNode(internalK1_I1J1_F1G1H1_D1E1_ZA1B1C1,
+            idK1_I1J1_F1G1H1_D1E1_ZA1B1C1, elementsK1_I1J1_F1G1H1_D1E1_ZA1B1C1,
+            1, 16);
+      String[] elementsK1 = new String[0];
+      char idK1 = KeyPart.KEY_ELEMENT_END;
+      assertChildLeafNode(internalK1_I1J1_F1G1H1_D1E1_ZA1B1C1, idK1, elementsK1,
+            "K1");
+      String[] elementsI1J1_F1G1H1_D1E1_ZA1B1C1 = new String[] {"pa", "tt",
+            "er", "n1", "pa", "tt", "er", "n2", "p"};
+      char idI1J1_F1G1H1_D1E1_ZA1B1C1 = 'p';
+      internalI1J1_F1G1H1_D1E1_ZA1B1C1 = getChildNode(
+            internalK1_I1J1_F1G1H1_D1E1_ZA1B1C1, idI1J1_F1G1H1_D1E1_ZA1B1C1);
+      assertInternalNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1,
+            idI1J1_F1G1H1_D1E1_ZA1B1C1, elementsI1J1_F1G1H1_D1E1_ZA1B1C1,
+            14, 15, 2, 9);
+      assertChildLeafNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1, idI1, elementsI1,
+      "I1");
+      assertChildLeafNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1, idJ1, elementsJ1,
+            "J1");
+      assertInternalNode(internalF1G1H1_D1E1_ZA1B1C1, idF1G1H1_D1E1_ZA1B1C1,
+            elementsF1G1H1_D1E1_ZA1B1C1, 7, 7, 3, 10);
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idF1, elementsF1, "F1");
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idG1, elementsG1, "G1");
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idH1, elementsH1, "H1");
+      internalD1E1_ZA1B1C1 = getChildNode(internalF1G1H1_D1E1_ZA1B1C1,
+            idD1E1_ZA1B1C1);
+      assertInternalNode(internalD1E1_ZA1B1C1, idD1E1_ZA1B1C1,
+            elementsD1E1_ZA1B1C1, 3, 3, 2, 6);
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idD1, elementsD1, "D1");
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idE1, elementsE1, "E1");
+      assertInternalNode(internalZA1B1C1, idZA1B1C1, elementsZA1B1C1, 2, 2);
+      assertChildLeafNode(internalZA1B1C1, idZ, elementsZ, "Z");
+      assertChildLeafNode(internalZA1B1C1, idA1, elementsA1, "A1");
+      assertChildLeafNode(internalZA1B1C1, idB1, elementsB1, "B1");
+      assertChildLeafNode(internalZA1B1C1, idC1, elementsC1, "C1");
+      assertInternalNode(internalXY, idXY, elementsXY, 1, 15);
+      assertChildLeafNode(internalXY, idX, elementsX, "X");
+      assertChildLeafNode(internalXY, idY, elementsY, "Y");
+      internalVW_TU_RS_PQ_MNO_JKL_CDEFG = getChildNode(internalFromC,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG);
+      assertInternalNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG, elementsVW_TU_RS_PQ_MNO_JKL_CDEFG, 12,
+            18, 4, 8);
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idV, elementsV,
+      "V");
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idW, elementsW,
+            "W");
+      assertInternalNode(internalTU_RS_PQ_MNO_JKL_CDEFG, '1',
+            elementsTU_RS_PQ_MNO_JKL_CDEFG, 9, 9, 3, 3);
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idT, elementsT, "T");
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idU, elementsU, "U");
+      assertInternalNode(internalRS_PQ_MNO_JKL_CDEFG, idRS_PQ_MNO_JKL_CDEDFG,
+            elementsRS_PQ_MNO_JKL_CDEFG,9, 9);
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idR, elementsR, "R");
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idS, elementsS, "S");
+      assertInternalNode(internalPQ_MNO_JKL_CDEFG, idPQ_MNO_JKL_CDEFG,
+            elementsPQ_MNO_JKL_CDEFG, 7, 7);    
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idP, elementsP, "P");
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idQ, elementsQ, "Q");
+      assertInternalNode(internalMNO_JKL_CDEFG, idMNO_JKL_CDEFG,
+            elementsMNO_JKL_CDEFG, 5, 5);
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idM, elementsM, "M");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idN, elementsN, "N");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idO, elementsO, "O");
+      assertInternalNode(internalJKL_CDEFG, idJKL_CDEFG, elementsJKL_CDEFG, 3,
+            3, 2, 2);
+      assertChildLeafNode(internalJKL_CDEFG, idJ, elementsJ, "J");
+      assertChildLeafNode(internalJKL_CDEFG, idK, elementsK, "K");
+      assertChildLeafNode(internalJKL_CDEFG, idL, elementsL, "L");
+      assertInternalNode(internalCDEFG, idCDEFG, elementsCDEFG, 2, 2);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      assertChildLeafNode(internalCDEFG, idH, elementsH, "H");
+      
+      // insert L1
+      tree.insert("pre.fi.xapapapa.pa.tt.erpa.tt.er.n1papaapa.tt.er.n2.pa.tt." +
+            "er.nn.pa.tt.er.n3suf.fi.x", "L1");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 22, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      assertInternalNode(internalFromC, idFromC, elementsFromC, 3, 22, 1, 10);
+      assertChildLeafNode(internalFromC, 'a', new String[] {"apapapa", "pa",
+            "tt", "erpa", "tt", "er", "n1papaapa", "tt", "er", "n2", "pa", "tt",
+            "er", "nn", "pa", "tt", "er", "n3suf", "fi", "x"}, "L1");
+      assertInternalNode(internalK1_I1J1_F1G1H1_D1E1_ZA1B1C1,
+            idK1_I1J1_F1G1H1_D1E1_ZA1B1C1, elementsK1_I1J1_F1G1H1_D1E1_ZA1B1C1,
+            1, 16);
+      assertChildLeafNode(internalK1_I1J1_F1G1H1_D1E1_ZA1B1C1, idK1, elementsK1,
+            "K1");
+      assertInternalNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1,
+            idI1J1_F1G1H1_D1E1_ZA1B1C1, elementsI1J1_F1G1H1_D1E1_ZA1B1C1,
+            14, 15, 2, 9);
+      assertChildLeafNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1, idI1, elementsI1,
+      "I1");
+      assertChildLeafNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1, idJ1, elementsJ1,
+            "J1");
+      assertInternalNode(internalF1G1H1_D1E1_ZA1B1C1, idF1G1H1_D1E1_ZA1B1C1,
+            elementsF1G1H1_D1E1_ZA1B1C1, 7, 7, 3, 10);
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idF1, elementsF1, "F1");
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idG1, elementsG1, "G1");
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idH1, elementsH1, "H1");
+      internalD1E1_ZA1B1C1 = getChildNode(internalF1G1H1_D1E1_ZA1B1C1,
+            idD1E1_ZA1B1C1);
+      assertInternalNode(internalD1E1_ZA1B1C1, idD1E1_ZA1B1C1,
+            elementsD1E1_ZA1B1C1, 3, 3, 2, 6);
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idD1, elementsD1, "D1");
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idE1, elementsE1, "E1");
+      assertInternalNode(internalZA1B1C1, idZA1B1C1, elementsZA1B1C1, 2, 2);
+      assertChildLeafNode(internalZA1B1C1, idZ, elementsZ, "Z");
+      assertChildLeafNode(internalZA1B1C1, idA1, elementsA1, "A1");
+      assertChildLeafNode(internalZA1B1C1, idB1, elementsB1, "B1");
+      assertChildLeafNode(internalZA1B1C1, idC1, elementsC1, "C1");
+      assertInternalNode(internalXY, idXY, elementsXY, 1, 15);
+      assertChildLeafNode(internalXY, idX, elementsX, "X");
+      assertChildLeafNode(internalXY, idY, elementsY, "Y");
+      internalVW_TU_RS_PQ_MNO_JKL_CDEFG = getChildNode(internalFromC,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG);
+      assertInternalNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG, elementsVW_TU_RS_PQ_MNO_JKL_CDEFG, 12,
+            18, 4, 8);
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idV, elementsV,
+      "V");
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idW, elementsW,
+            "W");
+      assertInternalNode(internalTU_RS_PQ_MNO_JKL_CDEFG, '1',
+            elementsTU_RS_PQ_MNO_JKL_CDEFG, 9, 9, 3, 3);
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idT, elementsT, "T");
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idU, elementsU, "U");
+      assertInternalNode(internalRS_PQ_MNO_JKL_CDEFG, idRS_PQ_MNO_JKL_CDEDFG,
+            elementsRS_PQ_MNO_JKL_CDEFG,9, 9);
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idR, elementsR, "R");
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idS, elementsS, "S");
+      assertInternalNode(internalPQ_MNO_JKL_CDEFG, idPQ_MNO_JKL_CDEFG,
+            elementsPQ_MNO_JKL_CDEFG, 7, 7);    
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idP, elementsP, "P");
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idQ, elementsQ, "Q");
+      assertInternalNode(internalMNO_JKL_CDEFG, idMNO_JKL_CDEFG,
+            elementsMNO_JKL_CDEFG, 5, 5);
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idM, elementsM, "M");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idN, elementsN, "N");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idO, elementsO, "O");
+      assertInternalNode(internalJKL_CDEFG, idJKL_CDEFG, elementsJKL_CDEFG, 3,
+            3, 2, 2);
+      assertChildLeafNode(internalJKL_CDEFG, idJ, elementsJ, "J");
+      assertChildLeafNode(internalJKL_CDEFG, idK, elementsK, "K");
+      assertChildLeafNode(internalJKL_CDEFG, idL, elementsL, "L");
+      assertInternalNode(internalCDEFG, idCDEFG, elementsCDEFG, 2, 2);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      assertChildLeafNode(internalCDEFG, idH, elementsH, "H");
+      
+      // insert M1
+      tree.insert("pre.fi.xapapapa.pa.tt.erpa.tt.er.n1papaapa.tt.er.n2.pa.tt." +
+            "er.nn.pa.tt.er.n1pa.tt.er.n3.sue.suf.fi.x", "M1");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 27, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      assertInternalNode(internalFromC, idFromC, elementsFromC, 3, 27, 1, 10);
+      Node internalL1M1N1 = getChildNode(internalFromC, 'a');
+      assertInternalNode(internalL1M1N1, 'a', new String[] {"apapapa", "pa",
+            "tt", "erpa", "tt", "er", "n1papaapa", "tt", "er", "n2", "pa", "tt",
+            "er", "nn", "pa", "tt", "er", "n"}, 20, 25, 4, 5);
+      String[] elementsL1 = new String[] {"3suf", "fi", "x"};
+      char idL1 = '3';
+      assertChildLeafNode(internalL1M1N1, idL1, elementsL1, "L1");
+      String[] elementsM1 = new String[] {"1pa", "tt", "er", "n3", "sue", "suf",
+            "fi", "x"};
+      char idM1 = '1';
+      assertChildLeafNode(internalL1M1N1, idM1, elementsM1, "M1");
+      assertInternalNode(internalK1_I1J1_F1G1H1_D1E1_ZA1B1C1,
+            idK1_I1J1_F1G1H1_D1E1_ZA1B1C1, elementsK1_I1J1_F1G1H1_D1E1_ZA1B1C1,
+            1, 16);
+      assertChildLeafNode(internalK1_I1J1_F1G1H1_D1E1_ZA1B1C1, idK1, elementsK1,
+            "K1");
+      assertInternalNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1,
+            idI1J1_F1G1H1_D1E1_ZA1B1C1, elementsI1J1_F1G1H1_D1E1_ZA1B1C1,
+            14, 15, 2, 9);
+      assertChildLeafNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1, idI1, elementsI1,
+      "I1");
+      assertChildLeafNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1, idJ1, elementsJ1,
+            "J1");
+      assertInternalNode(internalF1G1H1_D1E1_ZA1B1C1, idF1G1H1_D1E1_ZA1B1C1,
+            elementsF1G1H1_D1E1_ZA1B1C1, 7, 7, 3, 10);
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idF1, elementsF1, "F1");
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idG1, elementsG1, "G1");
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idH1, elementsH1, "H1");
+      internalD1E1_ZA1B1C1 = getChildNode(internalF1G1H1_D1E1_ZA1B1C1,
+            idD1E1_ZA1B1C1);
+      assertInternalNode(internalD1E1_ZA1B1C1, idD1E1_ZA1B1C1,
+            elementsD1E1_ZA1B1C1, 3, 3, 2, 6);
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idD1, elementsD1, "D1");
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idE1, elementsE1, "E1");
+      assertInternalNode(internalZA1B1C1, idZA1B1C1, elementsZA1B1C1, 2, 2);
+      assertChildLeafNode(internalZA1B1C1, idZ, elementsZ, "Z");
+      assertChildLeafNode(internalZA1B1C1, idA1, elementsA1, "A1");
+      assertChildLeafNode(internalZA1B1C1, idB1, elementsB1, "B1");
+      assertChildLeafNode(internalZA1B1C1, idC1, elementsC1, "C1");
+      assertInternalNode(internalXY, idXY, elementsXY, 1, 15);
+      assertChildLeafNode(internalXY, idX, elementsX, "X");
+      assertChildLeafNode(internalXY, idY, elementsY, "Y");
+      internalVW_TU_RS_PQ_MNO_JKL_CDEFG = getChildNode(internalFromC,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG);
+      assertInternalNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG, elementsVW_TU_RS_PQ_MNO_JKL_CDEFG, 12,
+            18, 4, 8);
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idV, elementsV,
+      "V");
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idW, elementsW,
+            "W");
+      assertInternalNode(internalTU_RS_PQ_MNO_JKL_CDEFG, '1',
+            elementsTU_RS_PQ_MNO_JKL_CDEFG, 9, 9, 3, 3);
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idT, elementsT, "T");
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idU, elementsU, "U");
+      assertInternalNode(internalRS_PQ_MNO_JKL_CDEFG, idRS_PQ_MNO_JKL_CDEDFG,
+            elementsRS_PQ_MNO_JKL_CDEFG,9, 9);
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idR, elementsR, "R");
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idS, elementsS, "S");
+      assertInternalNode(internalPQ_MNO_JKL_CDEFG, idPQ_MNO_JKL_CDEFG,
+            elementsPQ_MNO_JKL_CDEFG, 7, 7);    
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idP, elementsP, "P");
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idQ, elementsQ, "Q");
+      assertInternalNode(internalMNO_JKL_CDEFG, idMNO_JKL_CDEFG,
+            elementsMNO_JKL_CDEFG, 5, 5);
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idM, elementsM, "M");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idN, elementsN, "N");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idO, elementsO, "O");
+      assertInternalNode(internalJKL_CDEFG, idJKL_CDEFG, elementsJKL_CDEFG, 3,
+            3, 2, 2);
+      assertChildLeafNode(internalJKL_CDEFG, idJ, elementsJ, "J");
+      assertChildLeafNode(internalJKL_CDEFG, idK, elementsK, "K");
+      assertChildLeafNode(internalJKL_CDEFG, idL, elementsL, "L");
+      assertInternalNode(internalCDEFG, idCDEFG, elementsCDEFG, 2, 2);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      assertChildLeafNode(internalCDEFG, idH, elementsH, "H");
+      
+      // insert N1
+      tree.insert("pre.fi.xapapapa.pa.tt.erpa.tt.er.n1papaapa.tt.er.n2.pa.tt." +
+            "er.nn.pa.tt.er.n2.suf.fi.x", "N1");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 27, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      assertInternalNode(internalFromC, idFromC, elementsFromC, 3, 27, 1, 10);
+      assertInternalNode(internalL1M1N1, 'a', new String[] {"apapapa", "pa",
+            "tt", "erpa", "tt", "er", "n1papaapa", "tt", "er", "n2", "pa", "tt",
+            "er", "nn", "pa", "tt", "er", "n"}, 20, 25, 2, 5);
+      assertChildLeafNode(internalL1M1N1, idL1, elementsL1, "L1");
+      assertChildLeafNode(internalL1M1N1, idM1, elementsM1, "M1");
+      String[] elementsN1 = new String[] {"2", "suf", "fi", "x"};
+      char idN1 = '2';
+      assertChildLeafNode(internalL1M1N1, idN1, elementsN1, "N1");
+      assertInternalNode(internalK1_I1J1_F1G1H1_D1E1_ZA1B1C1,
+            idK1_I1J1_F1G1H1_D1E1_ZA1B1C1, elementsK1_I1J1_F1G1H1_D1E1_ZA1B1C1,
+            1, 16);
+      assertChildLeafNode(internalK1_I1J1_F1G1H1_D1E1_ZA1B1C1, idK1, elementsK1,
+            "K1");
+      assertInternalNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1,
+            idI1J1_F1G1H1_D1E1_ZA1B1C1, elementsI1J1_F1G1H1_D1E1_ZA1B1C1,
+            14, 15, 2, 9);
+      assertChildLeafNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1, idI1, elementsI1,
+      "I1");
+      assertChildLeafNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1, idJ1, elementsJ1,
+            "J1");
+      assertInternalNode(internalF1G1H1_D1E1_ZA1B1C1, idF1G1H1_D1E1_ZA1B1C1,
+            elementsF1G1H1_D1E1_ZA1B1C1, 7, 7, 3, 10);
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idF1, elementsF1, "F1");
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idG1, elementsG1, "G1");
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idH1, elementsH1, "H1");
+      internalD1E1_ZA1B1C1 = getChildNode(internalF1G1H1_D1E1_ZA1B1C1,
+            idD1E1_ZA1B1C1);
+      assertInternalNode(internalD1E1_ZA1B1C1, idD1E1_ZA1B1C1,
+            elementsD1E1_ZA1B1C1, 3, 3, 2, 6);
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idD1, elementsD1, "D1");
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idE1, elementsE1, "E1");
+      assertInternalNode(internalZA1B1C1, idZA1B1C1, elementsZA1B1C1, 2, 2);
+      assertChildLeafNode(internalZA1B1C1, idZ, elementsZ, "Z");
+      assertChildLeafNode(internalZA1B1C1, idA1, elementsA1, "A1");
+      assertChildLeafNode(internalZA1B1C1, idB1, elementsB1, "B1");
+      assertChildLeafNode(internalZA1B1C1, idC1, elementsC1, "C1");
+      assertInternalNode(internalXY, idXY, elementsXY, 1, 15);
+      assertChildLeafNode(internalXY, idX, elementsX, "X");
+      assertChildLeafNode(internalXY, idY, elementsY, "Y");
+      internalVW_TU_RS_PQ_MNO_JKL_CDEFG = getChildNode(internalFromC,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG);
+      assertInternalNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG, elementsVW_TU_RS_PQ_MNO_JKL_CDEFG, 12,
+            18, 4, 8);
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idV, elementsV,
+      "V");
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idW, elementsW,
+            "W");
+      assertInternalNode(internalTU_RS_PQ_MNO_JKL_CDEFG, '1',
+            elementsTU_RS_PQ_MNO_JKL_CDEFG, 9, 9, 3, 3);
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idT, elementsT, "T");
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idU, elementsU, "U");
+      assertInternalNode(internalRS_PQ_MNO_JKL_CDEFG, idRS_PQ_MNO_JKL_CDEDFG,
+            elementsRS_PQ_MNO_JKL_CDEFG,9, 9);
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idR, elementsR, "R");
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idS, elementsS, "S");
+      assertInternalNode(internalPQ_MNO_JKL_CDEFG, idPQ_MNO_JKL_CDEFG,
+            elementsPQ_MNO_JKL_CDEFG, 7, 7);    
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idP, elementsP, "P");
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idQ, elementsQ, "Q");
+      assertInternalNode(internalMNO_JKL_CDEFG, idMNO_JKL_CDEFG,
+            elementsMNO_JKL_CDEFG, 5, 5);
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idM, elementsM, "M");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idN, elementsN, "N");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idO, elementsO, "O");
+      assertInternalNode(internalJKL_CDEFG, idJKL_CDEFG, elementsJKL_CDEFG, 3,
+            3, 2, 2);
+      assertChildLeafNode(internalJKL_CDEFG, idJ, elementsJ, "J");
+      assertChildLeafNode(internalJKL_CDEFG, idK, elementsK, "K");
+      assertChildLeafNode(internalJKL_CDEFG, idL, elementsL, "L");
+      assertInternalNode(internalCDEFG, idCDEFG, elementsCDEFG, 2, 2);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      assertChildLeafNode(internalCDEFG, idH, elementsH, "H");
+      
+      // insert O1
+      tree.insert("pre.fi.xapapapa.pa.tt.erpa.tt.er.n1papaapa.tt.er.n2.pa.tt." +
+            "er.nn.pa.pa.tt.er.n3suf.fi.x", "O1");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 27, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      assertInternalNode(internalFromC, idFromC, elementsFromC, 3, 27, 1, 10);
+      Node internalO1P1_L1M1N1 = getChildNode(internalFromC, 'a');
+      assertInternalNode(internalO1P1_L1M1N1, 'a', new String[] {"apapapa",
+            "pa", "tt", "erpa", "tt", "er", "n1papaapa", "tt", "er", "n2", "pa",
+            "tt", "er", "nn", "pa"}, 20, 25);
+      assertChildLeafNode(internalO1P1_L1M1N1, 'p', new String[] {"pa",
+            "tt", "er", "n3suf", "fi", "x"}, "O1");
+      String[] elementsL1M1N1 = new String[] {"tt", "er", "n"};
+      char idL1M1N1 = 't';
+      internalL1M1N1 = getChildNode(internalO1P1_L1M1N1, idL1M1N1);
+      assertInternalNode(internalL1M1N1, idL1M1N1, elementsL1M1N1, 5, 10, 2, 5);
+      assertChildLeafNode(internalL1M1N1, idL1, elementsL1, "L1");
+      assertChildLeafNode(internalL1M1N1, idM1, elementsM1, "M1");
+      assertChildLeafNode(internalL1M1N1, idN1, elementsN1, "N1");
+      assertInternalNode(internalK1_I1J1_F1G1H1_D1E1_ZA1B1C1,
+            idK1_I1J1_F1G1H1_D1E1_ZA1B1C1, elementsK1_I1J1_F1G1H1_D1E1_ZA1B1C1,
+            1, 16);
+      assertChildLeafNode(internalK1_I1J1_F1G1H1_D1E1_ZA1B1C1, idK1, elementsK1,
+            "K1");
+      assertInternalNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1,
+            idI1J1_F1G1H1_D1E1_ZA1B1C1, elementsI1J1_F1G1H1_D1E1_ZA1B1C1,
+            14, 15, 2, 9);
+      assertChildLeafNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1, idI1, elementsI1,
+      "I1");
+      assertChildLeafNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1, idJ1, elementsJ1,
+            "J1");
+      assertInternalNode(internalF1G1H1_D1E1_ZA1B1C1, idF1G1H1_D1E1_ZA1B1C1,
+            elementsF1G1H1_D1E1_ZA1B1C1, 7, 7, 3, 10);
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idF1, elementsF1, "F1");
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idG1, elementsG1, "G1");
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idH1, elementsH1, "H1");
+      internalD1E1_ZA1B1C1 = getChildNode(internalF1G1H1_D1E1_ZA1B1C1,
+            idD1E1_ZA1B1C1);
+      assertInternalNode(internalD1E1_ZA1B1C1, idD1E1_ZA1B1C1,
+            elementsD1E1_ZA1B1C1, 3, 3, 2, 6);
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idD1, elementsD1, "D1");
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idE1, elementsE1, "E1");
+      assertInternalNode(internalZA1B1C1, idZA1B1C1, elementsZA1B1C1, 2, 2);
+      assertChildLeafNode(internalZA1B1C1, idZ, elementsZ, "Z");
+      assertChildLeafNode(internalZA1B1C1, idA1, elementsA1, "A1");
+      assertChildLeafNode(internalZA1B1C1, idB1, elementsB1, "B1");
+      assertChildLeafNode(internalZA1B1C1, idC1, elementsC1, "C1");
+      assertInternalNode(internalXY, idXY, elementsXY, 1, 15);
+      assertChildLeafNode(internalXY, idX, elementsX, "X");
+      assertChildLeafNode(internalXY, idY, elementsY, "Y");
+      internalVW_TU_RS_PQ_MNO_JKL_CDEFG = getChildNode(internalFromC,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG);
+      assertInternalNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG, elementsVW_TU_RS_PQ_MNO_JKL_CDEFG, 12,
+            18, 4, 8);
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idV, elementsV,
+      "V");
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idW, elementsW,
+            "W");
+      assertInternalNode(internalTU_RS_PQ_MNO_JKL_CDEFG, '1',
+            elementsTU_RS_PQ_MNO_JKL_CDEFG, 9, 9, 3, 3);
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idT, elementsT, "T");
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idU, elementsU, "U");
+      assertInternalNode(internalRS_PQ_MNO_JKL_CDEFG, idRS_PQ_MNO_JKL_CDEDFG,
+            elementsRS_PQ_MNO_JKL_CDEFG,9, 9);
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idR, elementsR, "R");
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idS, elementsS, "S");
+      assertInternalNode(internalPQ_MNO_JKL_CDEFG, idPQ_MNO_JKL_CDEFG,
+            elementsPQ_MNO_JKL_CDEFG, 7, 7);    
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idP, elementsP, "P");
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idQ, elementsQ, "Q");
+      assertInternalNode(internalMNO_JKL_CDEFG, idMNO_JKL_CDEFG,
+            elementsMNO_JKL_CDEFG, 5, 5);
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idM, elementsM, "M");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idN, elementsN, "N");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idO, elementsO, "O");
+      assertInternalNode(internalJKL_CDEFG, idJKL_CDEFG, elementsJKL_CDEFG, 3,
+            3, 2, 2);
+      assertChildLeafNode(internalJKL_CDEFG, idJ, elementsJ, "J");
+      assertChildLeafNode(internalJKL_CDEFG, idK, elementsK, "K");
+      assertChildLeafNode(internalJKL_CDEFG, idL, elementsL, "L");
+      assertInternalNode(internalCDEFG, idCDEFG, elementsCDEFG, 2, 2);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      assertChildLeafNode(internalCDEFG, idH, elementsH, "H");
+      
+      // insert P1
+      tree.insert("pre.fi.xapapapa.pa.tt.erpa.tt.er.n1papaapa.tt.er.n2.pa.tt." +
+            "er.nn.pa.pa.tt.er.n3suf.fi.x.abc", "P1");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 27, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      assertInternalNode(internalFromC, idFromC, elementsFromC, 3, 27, 1, 10);
+      assertInternalNode(internalO1P1_L1M1N1, 'a', new String[] {"apapapa",
+            "pa", "tt", "erpa", "tt", "er", "n1papaapa", "tt", "er", "n2", "pa",
+            "tt", "er", "nn", "pa"}, 20, 25);
+      String[] elementsO1P1Q1 = new String[] {"pa", "tt", "er", "n3suf", "fi",
+            "x"};
+      char idO1P1Q1 = 'p';
+      Node internalO1P1 = getChildNode(internalO1P1_L1M1N1, idO1P1Q1);
+      assertInternalNode(internalO1P1, idO1P1Q1, elementsO1P1Q1, 6, 7);
+      String[] elementsO1 = new String[0];
+      char idO1 = KeyPart.KEY_ELEMENT_END;
+      assertChildLeafNode(internalO1P1, idO1, elementsO1, "O1");
+      String[] elementsP1 = new String[] {"abc"};
+      char idP1 = 'a';
+      assertChildLeafNode(internalO1P1, idP1, elementsP1, "P1");
+      assertInternalNode(internalL1M1N1, idL1M1N1, elementsL1M1N1, 5, 10, 2, 5);
+      assertChildLeafNode(internalL1M1N1, idL1, elementsL1, "L1");
+      assertChildLeafNode(internalL1M1N1, idM1, elementsM1, "M1");
+      assertChildLeafNode(internalL1M1N1, idN1, elementsN1, "N1");
+      assertInternalNode(internalK1_I1J1_F1G1H1_D1E1_ZA1B1C1,
+            idK1_I1J1_F1G1H1_D1E1_ZA1B1C1, elementsK1_I1J1_F1G1H1_D1E1_ZA1B1C1,
+            1, 16);
+      assertChildLeafNode(internalK1_I1J1_F1G1H1_D1E1_ZA1B1C1, idK1, elementsK1,
+            "K1");
+      assertInternalNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1,
+            idI1J1_F1G1H1_D1E1_ZA1B1C1, elementsI1J1_F1G1H1_D1E1_ZA1B1C1,
+            14, 15, 2, 9);
+      assertChildLeafNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1, idI1, elementsI1,
+      "I1");
+      assertChildLeafNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1, idJ1, elementsJ1,
+            "J1");
+      assertInternalNode(internalF1G1H1_D1E1_ZA1B1C1, idF1G1H1_D1E1_ZA1B1C1,
+            elementsF1G1H1_D1E1_ZA1B1C1, 7, 7, 3, 10);
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idF1, elementsF1, "F1");
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idG1, elementsG1, "G1");
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idH1, elementsH1, "H1");
+      internalD1E1_ZA1B1C1 = getChildNode(internalF1G1H1_D1E1_ZA1B1C1,
+            idD1E1_ZA1B1C1);
+      assertInternalNode(internalD1E1_ZA1B1C1, idD1E1_ZA1B1C1,
+            elementsD1E1_ZA1B1C1, 3, 3, 2, 6);
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idD1, elementsD1, "D1");
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idE1, elementsE1, "E1");
+      assertInternalNode(internalZA1B1C1, idZA1B1C1, elementsZA1B1C1, 2, 2);
+      assertChildLeafNode(internalZA1B1C1, idZ, elementsZ, "Z");
+      assertChildLeafNode(internalZA1B1C1, idA1, elementsA1, "A1");
+      assertChildLeafNode(internalZA1B1C1, idB1, elementsB1, "B1");
+      assertChildLeafNode(internalZA1B1C1, idC1, elementsC1, "C1");
+      assertInternalNode(internalXY, idXY, elementsXY, 1, 15);
+      assertChildLeafNode(internalXY, idX, elementsX, "X");
+      assertChildLeafNode(internalXY, idY, elementsY, "Y");
+      internalVW_TU_RS_PQ_MNO_JKL_CDEFG = getChildNode(internalFromC,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG);
+      assertInternalNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG, elementsVW_TU_RS_PQ_MNO_JKL_CDEFG, 12,
+            18, 4, 8);
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idV, elementsV,
+      "V");
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idW, elementsW,
+            "W");
+      assertInternalNode(internalTU_RS_PQ_MNO_JKL_CDEFG, '1',
+            elementsTU_RS_PQ_MNO_JKL_CDEFG, 9, 9, 3, 3);
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idT, elementsT, "T");
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idU, elementsU, "U");
+      assertInternalNode(internalRS_PQ_MNO_JKL_CDEFG, idRS_PQ_MNO_JKL_CDEDFG,
+            elementsRS_PQ_MNO_JKL_CDEFG,9, 9);
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idR, elementsR, "R");
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idS, elementsS, "S");
+      assertInternalNode(internalPQ_MNO_JKL_CDEFG, idPQ_MNO_JKL_CDEFG,
+            elementsPQ_MNO_JKL_CDEFG, 7, 7);    
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idP, elementsP, "P");
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idQ, elementsQ, "Q");
+      assertInternalNode(internalMNO_JKL_CDEFG, idMNO_JKL_CDEFG,
+            elementsMNO_JKL_CDEFG, 5, 5);
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idM, elementsM, "M");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idN, elementsN, "N");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idO, elementsO, "O");
+      assertInternalNode(internalJKL_CDEFG, idJKL_CDEFG, elementsJKL_CDEFG, 3,
+            3, 2, 2);
+      assertChildLeafNode(internalJKL_CDEFG, idJ, elementsJ, "J");
+      assertChildLeafNode(internalJKL_CDEFG, idK, elementsK, "K");
+      assertChildLeafNode(internalJKL_CDEFG, idL, elementsL, "L");
+      assertInternalNode(internalCDEFG, idCDEFG, elementsCDEFG, 2, 2);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      assertChildLeafNode(internalCDEFG, idH, elementsH, "H");
+      
+      // insert Q1
+      tree.insert("pre.fi.xapapapa.pa.tt.erpa.tt.er.n1papaapa.tt.er.n2.pa.tt." +
+            "er.n3suf.fi.x", "Q1");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 27, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      assertInternalNode(internalFromC, idFromC, elementsFromC, 3, 27, 1, 10);
+      Node internalQ1_O1P1_L1M1N1 = getChildNode(internalFromC, 'a');
+      assertInternalNode(internalQ1_O1P1_L1M1N1, 'a', new String[] {"apapapa",
+            "pa", "tt", "erpa", "tt", "er", "n1papaapa", "tt", "er", "n2", "pa",
+            "tt", "er", "n"}, 16, 25, 2, 5);
+      String[] elementsQ1 = new String[] {"3suf", "fi", "x"};
+      char idQ1 = '3';
+      assertChildLeafNode(internalQ1_O1P1_L1M1N1, idQ1, elementsQ1, "Q1");
+      String[] elementsO1P1_L1M1N1 = new String[] {"n", "pa"};
+      char idO1P1_L1M1N1 = 'n';
+      internalO1P1_L1M1N1 = getChildNode(internalQ1_O1P1_L1M1N1, idO1P1_L1M1N1);
+      assertInternalNode(internalO1P1_L1M1N1, idO1P1_L1M1N1,
+            elementsO1P1_L1M1N1, 7, 12);
+      assertInternalNode(internalO1P1, idO1P1Q1, elementsO1P1Q1, 6, 7);
+      assertChildLeafNode(internalO1P1, idO1, elementsO1, "O1");
+      assertChildLeafNode(internalO1P1, idP1, elementsP1, "P1");
+      assertInternalNode(internalL1M1N1, idL1M1N1, elementsL1M1N1, 5, 10, 2, 5);
+      assertChildLeafNode(internalL1M1N1, idL1, elementsL1, "L1");
+      assertChildLeafNode(internalL1M1N1, idM1, elementsM1, "M1");
+      assertChildLeafNode(internalL1M1N1, idN1, elementsN1, "N1");
+      assertInternalNode(internalK1_I1J1_F1G1H1_D1E1_ZA1B1C1,
+            idK1_I1J1_F1G1H1_D1E1_ZA1B1C1, elementsK1_I1J1_F1G1H1_D1E1_ZA1B1C1,
+            1, 16);
+      assertChildLeafNode(internalK1_I1J1_F1G1H1_D1E1_ZA1B1C1, idK1, elementsK1,
+            "K1");
+      assertInternalNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1,
+            idI1J1_F1G1H1_D1E1_ZA1B1C1, elementsI1J1_F1G1H1_D1E1_ZA1B1C1,
+            14, 15, 2, 9);
+      assertChildLeafNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1, idI1, elementsI1,
+      "I1");
+      assertChildLeafNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1, idJ1, elementsJ1,
+            "J1");
+      assertInternalNode(internalF1G1H1_D1E1_ZA1B1C1, idF1G1H1_D1E1_ZA1B1C1,
+            elementsF1G1H1_D1E1_ZA1B1C1, 7, 7, 3, 10);
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idF1, elementsF1, "F1");
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idG1, elementsG1, "G1");
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idH1, elementsH1, "H1");
+      internalD1E1_ZA1B1C1 = getChildNode(internalF1G1H1_D1E1_ZA1B1C1,
+            idD1E1_ZA1B1C1);
+      assertInternalNode(internalD1E1_ZA1B1C1, idD1E1_ZA1B1C1,
+            elementsD1E1_ZA1B1C1, 3, 3, 2, 6);
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idD1, elementsD1, "D1");
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idE1, elementsE1, "E1");
+      assertInternalNode(internalZA1B1C1, idZA1B1C1, elementsZA1B1C1, 2, 2);
+      assertChildLeafNode(internalZA1B1C1, idZ, elementsZ, "Z");
+      assertChildLeafNode(internalZA1B1C1, idA1, elementsA1, "A1");
+      assertChildLeafNode(internalZA1B1C1, idB1, elementsB1, "B1");
+      assertChildLeafNode(internalZA1B1C1, idC1, elementsC1, "C1");
+      assertInternalNode(internalXY, idXY, elementsXY, 1, 15);
+      assertChildLeafNode(internalXY, idX, elementsX, "X");
+      assertChildLeafNode(internalXY, idY, elementsY, "Y");
+      internalVW_TU_RS_PQ_MNO_JKL_CDEFG = getChildNode(internalFromC,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG);
+      assertInternalNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG, elementsVW_TU_RS_PQ_MNO_JKL_CDEFG, 12,
+            18, 4, 8);
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idV, elementsV,
+      "V");
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idW, elementsW,
+            "W");
+      assertInternalNode(internalTU_RS_PQ_MNO_JKL_CDEFG, '1',
+            elementsTU_RS_PQ_MNO_JKL_CDEFG, 9, 9, 3, 3);
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idT, elementsT, "T");
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idU, elementsU, "U");
+      assertInternalNode(internalRS_PQ_MNO_JKL_CDEFG, idRS_PQ_MNO_JKL_CDEDFG,
+            elementsRS_PQ_MNO_JKL_CDEFG,9, 9);
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idR, elementsR, "R");
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idS, elementsS, "S");
+      assertInternalNode(internalPQ_MNO_JKL_CDEFG, idPQ_MNO_JKL_CDEFG,
+            elementsPQ_MNO_JKL_CDEFG, 7, 7);    
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idP, elementsP, "P");
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idQ, elementsQ, "Q");
+      assertInternalNode(internalMNO_JKL_CDEFG, idMNO_JKL_CDEFG,
+            elementsMNO_JKL_CDEFG, 5, 5);
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idM, elementsM, "M");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idN, elementsN, "N");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idO, elementsO, "O");
+      assertInternalNode(internalJKL_CDEFG, idJKL_CDEFG, elementsJKL_CDEFG, 3,
+            3, 2, 2);
+      assertChildLeafNode(internalJKL_CDEFG, idJ, elementsJ, "J");
+      assertChildLeafNode(internalJKL_CDEFG, idK, elementsK, "K");
+      assertChildLeafNode(internalJKL_CDEFG, idL, elementsL, "L");
+      assertInternalNode(internalCDEFG, idCDEFG, elementsCDEFG, 2, 2);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      assertChildLeafNode(internalCDEFG, idH, elementsH, "H");
+      
+      // insert R1
+      tree.insert("pre.fi.xapapapa.pa.tt.erpa.tt.er.n1papaapa.tt.er.n2.papa." +
+            "tt.er.n3.abababa.suf.fi.x", "R1");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 27, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      assertInternalNode(internalFromC, idFromC, elementsFromC, 3, 27, 1, 10);
+      Node internalR1S1_Q1_O1P1_L1M1N1 = getChildNode(internalFromC, 'a');
+      assertInternalNode(internalR1S1_Q1_O1P1_L1M1N1, 'a', new String[] {
+            "apapapa", "pa", "tt", "erpa", "tt", "er", "n1papaapa", "tt", "er",
+            "n2", "pa"}, 16, 25, 2, 4);
+      assertChildLeafNode(internalR1S1_Q1_O1P1_L1M1N1, 'p', new String[] {"pa",
+            "tt", "er", "n3", "abababa", "suf", "fi", "x"}, "R1");
+      String[] elementsQ1_O1P1_L1M1N1 = new String[] {"", "tt", "er", "n"};
+      char idQ1_O1P1_L1M1N1 = KeyPart.KEY_ELEMENT_END;
+      internalQ1_O1P1_L1M1N1 = getChildNode(internalR1S1_Q1_O1P1_L1M1N1,
+            idQ1_O1P1_L1M1N1);
+      assertInternalNode(internalQ1_O1P1_L1M1N1, idQ1_O1P1_L1M1N1,
+            elementsQ1_O1P1_L1M1N1, 6, 15, 2, 5);
+      assertChildLeafNode(internalQ1_O1P1_L1M1N1, idQ1, elementsQ1, "Q1");
+      internalO1P1_L1M1N1 = getChildNode(internalQ1_O1P1_L1M1N1, idO1P1_L1M1N1);
+      assertInternalNode(internalO1P1_L1M1N1, idO1P1_L1M1N1,
+            elementsO1P1_L1M1N1, 7, 12);
+      assertInternalNode(internalO1P1, idO1P1Q1, elementsO1P1Q1, 6, 7);
+      assertChildLeafNode(internalO1P1, idO1, elementsO1, "O1");
+      assertChildLeafNode(internalO1P1, idP1, elementsP1, "P1");
+      assertInternalNode(internalL1M1N1, idL1M1N1, elementsL1M1N1, 5, 10, 2, 5);
+      assertChildLeafNode(internalL1M1N1, idL1, elementsL1, "L1");
+      assertChildLeafNode(internalL1M1N1, idM1, elementsM1, "M1");
+      assertChildLeafNode(internalL1M1N1, idN1, elementsN1, "N1");
+      assertInternalNode(internalK1_I1J1_F1G1H1_D1E1_ZA1B1C1,
+            idK1_I1J1_F1G1H1_D1E1_ZA1B1C1, elementsK1_I1J1_F1G1H1_D1E1_ZA1B1C1,
+            1, 16);
+      assertChildLeafNode(internalK1_I1J1_F1G1H1_D1E1_ZA1B1C1, idK1, elementsK1,
+            "K1");
+      assertInternalNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1,
+            idI1J1_F1G1H1_D1E1_ZA1B1C1, elementsI1J1_F1G1H1_D1E1_ZA1B1C1,
+            14, 15, 2, 9);
+      assertChildLeafNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1, idI1, elementsI1,
+      "I1");
+      assertChildLeafNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1, idJ1, elementsJ1,
+            "J1");
+      assertInternalNode(internalF1G1H1_D1E1_ZA1B1C1, idF1G1H1_D1E1_ZA1B1C1,
+            elementsF1G1H1_D1E1_ZA1B1C1, 7, 7, 3, 10);
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idF1, elementsF1, "F1");
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idG1, elementsG1, "G1");
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idH1, elementsH1, "H1");
+      internalD1E1_ZA1B1C1 = getChildNode(internalF1G1H1_D1E1_ZA1B1C1,
+            idD1E1_ZA1B1C1);
+      assertInternalNode(internalD1E1_ZA1B1C1, idD1E1_ZA1B1C1,
+            elementsD1E1_ZA1B1C1, 3, 3, 2, 6);
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idD1, elementsD1, "D1");
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idE1, elementsE1, "E1");
+      assertInternalNode(internalZA1B1C1, idZA1B1C1, elementsZA1B1C1, 2, 2);
+      assertChildLeafNode(internalZA1B1C1, idZ, elementsZ, "Z");
+      assertChildLeafNode(internalZA1B1C1, idA1, elementsA1, "A1");
+      assertChildLeafNode(internalZA1B1C1, idB1, elementsB1, "B1");
+      assertChildLeafNode(internalZA1B1C1, idC1, elementsC1, "C1");
+      assertInternalNode(internalXY, idXY, elementsXY, 1, 15);
+      assertChildLeafNode(internalXY, idX, elementsX, "X");
+      assertChildLeafNode(internalXY, idY, elementsY, "Y");
+      internalVW_TU_RS_PQ_MNO_JKL_CDEFG = getChildNode(internalFromC,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG);
+      assertInternalNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG, elementsVW_TU_RS_PQ_MNO_JKL_CDEFG, 12,
+            18, 4, 8);
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idV, elementsV,
+      "V");
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idW, elementsW,
+            "W");
+      assertInternalNode(internalTU_RS_PQ_MNO_JKL_CDEFG, '1',
+            elementsTU_RS_PQ_MNO_JKL_CDEFG, 9, 9, 3, 3);
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idT, elementsT, "T");
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idU, elementsU, "U");
+      assertInternalNode(internalRS_PQ_MNO_JKL_CDEFG, idRS_PQ_MNO_JKL_CDEDFG,
+            elementsRS_PQ_MNO_JKL_CDEFG,9, 9);
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idR, elementsR, "R");
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idS, elementsS, "S");
+      assertInternalNode(internalPQ_MNO_JKL_CDEFG, idPQ_MNO_JKL_CDEFG,
+            elementsPQ_MNO_JKL_CDEFG, 7, 7);    
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idP, elementsP, "P");
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idQ, elementsQ, "Q");
+      assertInternalNode(internalMNO_JKL_CDEFG, idMNO_JKL_CDEFG,
+            elementsMNO_JKL_CDEFG, 5, 5);
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idM, elementsM, "M");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idN, elementsN, "N");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idO, elementsO, "O");
+      assertInternalNode(internalJKL_CDEFG, idJKL_CDEFG, elementsJKL_CDEFG, 3,
+            3, 2, 2);
+      assertChildLeafNode(internalJKL_CDEFG, idJ, elementsJ, "J");
+      assertChildLeafNode(internalJKL_CDEFG, idK, elementsK, "K");
+      assertChildLeafNode(internalJKL_CDEFG, idL, elementsL, "L");
+      assertInternalNode(internalCDEFG, idCDEFG, elementsCDEFG, 2, 2);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      assertChildLeafNode(internalCDEFG, idH, elementsH, "H");
+      
+      // insert S1
+      tree.insert("pre.fi.xapapapa.pa.tt.erpa.tt.er.n1papaapa.tt.er.n2.papa." +
+            "tt.er.n3suf.ab.c", "S1");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 27, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      assertInternalNode(internalFromC, idFromC, elementsFromC, 3, 27, 1, 10);
+      assertInternalNode(internalR1S1_Q1_O1P1_L1M1N1, 'a', new String[] {
+            "apapapa", "pa", "tt", "erpa", "tt", "er", "n1papaapa", "tt", "er",
+            "n2", "pa"}, 16, 25, 2, 4);
+      String[] elementsR1S1 = new String[] {"pa", "tt", "er", "n3"};
+      char idR1S1 = 'p';
+      Node internalR1S1 = getChildNode(internalR1S1_Q1_O1P1_L1M1N1, idR1S1);
+      assertInternalNode(internalR1S1, idR1S1, elementsR1S1, 6, 8, 2, 5);
+      String[] elementsR1 = new String[] {"", "abababa", "suf", "fi", "x"};
+      char idR1 = KeyPart.KEY_ELEMENT_END;
+      assertChildLeafNode(internalR1S1, idR1, elementsR1, "R1");
+      String[] elementsS1 = new String[] {"suf", "ab", "c"};
+      char idS1 = 's';
+      assertChildLeafNode(internalR1S1, idS1, elementsS1, "S1");
+      internalQ1_O1P1_L1M1N1 = getChildNode(internalR1S1_Q1_O1P1_L1M1N1,
+            idQ1_O1P1_L1M1N1);
+      assertInternalNode(internalQ1_O1P1_L1M1N1, idQ1_O1P1_L1M1N1,
+            elementsQ1_O1P1_L1M1N1, 6, 15, 2, 5);
+      assertChildLeafNode(internalQ1_O1P1_L1M1N1, idQ1, elementsQ1, "Q1");
+      internalO1P1_L1M1N1 = getChildNode(internalQ1_O1P1_L1M1N1, idO1P1_L1M1N1);
+      assertInternalNode(internalO1P1_L1M1N1, idO1P1_L1M1N1,
+            elementsO1P1_L1M1N1, 7, 12);
+      assertInternalNode(internalO1P1, idO1P1Q1, elementsO1P1Q1, 6, 7);
+      assertChildLeafNode(internalO1P1, idO1, elementsO1, "O1");
+      assertChildLeafNode(internalO1P1, idP1, elementsP1, "P1");
+      assertInternalNode(internalL1M1N1, idL1M1N1, elementsL1M1N1, 5, 10, 2, 5);
+      assertChildLeafNode(internalL1M1N1, idL1, elementsL1, "L1");
+      assertChildLeafNode(internalL1M1N1, idM1, elementsM1, "M1");
+      assertChildLeafNode(internalL1M1N1, idN1, elementsN1, "N1");
+      assertInternalNode(internalK1_I1J1_F1G1H1_D1E1_ZA1B1C1,
+            idK1_I1J1_F1G1H1_D1E1_ZA1B1C1, elementsK1_I1J1_F1G1H1_D1E1_ZA1B1C1,
+            1, 16);
+      assertChildLeafNode(internalK1_I1J1_F1G1H1_D1E1_ZA1B1C1, idK1, elementsK1,
+            "K1");
+      assertInternalNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1,
+            idI1J1_F1G1H1_D1E1_ZA1B1C1, elementsI1J1_F1G1H1_D1E1_ZA1B1C1,
+            14, 15, 2, 9);
+      assertChildLeafNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1, idI1, elementsI1,
+      "I1");
+      assertChildLeafNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1, idJ1, elementsJ1,
+            "J1");
+      assertInternalNode(internalF1G1H1_D1E1_ZA1B1C1, idF1G1H1_D1E1_ZA1B1C1,
+            elementsF1G1H1_D1E1_ZA1B1C1, 7, 7, 3, 10);
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idF1, elementsF1, "F1");
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idG1, elementsG1, "G1");
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idH1, elementsH1, "H1");
+      internalD1E1_ZA1B1C1 = getChildNode(internalF1G1H1_D1E1_ZA1B1C1,
+            idD1E1_ZA1B1C1);
+      assertInternalNode(internalD1E1_ZA1B1C1, idD1E1_ZA1B1C1,
+            elementsD1E1_ZA1B1C1, 3, 3, 2, 6);
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idD1, elementsD1, "D1");
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idE1, elementsE1, "E1");
+      assertInternalNode(internalZA1B1C1, idZA1B1C1, elementsZA1B1C1, 2, 2);
+      assertChildLeafNode(internalZA1B1C1, idZ, elementsZ, "Z");
+      assertChildLeafNode(internalZA1B1C1, idA1, elementsA1, "A1");
+      assertChildLeafNode(internalZA1B1C1, idB1, elementsB1, "B1");
+      assertChildLeafNode(internalZA1B1C1, idC1, elementsC1, "C1");
+      assertInternalNode(internalXY, idXY, elementsXY, 1, 15);
+      assertChildLeafNode(internalXY, idX, elementsX, "X");
+      assertChildLeafNode(internalXY, idY, elementsY, "Y");
+      internalVW_TU_RS_PQ_MNO_JKL_CDEFG = getChildNode(internalFromC,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG);
+      assertInternalNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG, elementsVW_TU_RS_PQ_MNO_JKL_CDEFG, 12,
+            18, 4, 8);
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idV, elementsV,
+      "V");
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idW, elementsW,
+            "W");
+      assertInternalNode(internalTU_RS_PQ_MNO_JKL_CDEFG, '1',
+            elementsTU_RS_PQ_MNO_JKL_CDEFG, 9, 9, 3, 3);
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idT, elementsT, "T");
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idU, elementsU, "U");
+      assertInternalNode(internalRS_PQ_MNO_JKL_CDEFG, idRS_PQ_MNO_JKL_CDEDFG,
+            elementsRS_PQ_MNO_JKL_CDEFG,9, 9);
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idR, elementsR, "R");
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idS, elementsS, "S");
+      assertInternalNode(internalPQ_MNO_JKL_CDEFG, idPQ_MNO_JKL_CDEFG,
+            elementsPQ_MNO_JKL_CDEFG, 7, 7);    
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idP, elementsP, "P");
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idQ, elementsQ, "Q");
+      assertInternalNode(internalMNO_JKL_CDEFG, idMNO_JKL_CDEFG,
+            elementsMNO_JKL_CDEFG, 5, 5);
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idM, elementsM, "M");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idN, elementsN, "N");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idO, elementsO, "O");
+      assertInternalNode(internalJKL_CDEFG, idJKL_CDEFG, elementsJKL_CDEFG, 3,
+            3, 2, 2);
+      assertChildLeafNode(internalJKL_CDEFG, idJ, elementsJ, "J");
+      assertChildLeafNode(internalJKL_CDEFG, idK, elementsK, "K");
+      assertChildLeafNode(internalJKL_CDEFG, idL, elementsL, "L");
+      assertInternalNode(internalCDEFG, idCDEFG, elementsCDEFG, 2, 2);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      assertChildLeafNode(internalCDEFG, idH, elementsH, "H");
+      
+      // insert T1
+      tree.insert("pre.fi.xapapapa.pa.tt.erpa.tt.er.n1pa.tt.er.n2ABC.pa.tt." +
+            "er.n3.ABCsuf.fi.x", "T1");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 27, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      assertInternalNode(internalFromC, idFromC, elementsFromC, 3, 27, 1, 10);
+      Node internalT1_R1S1_Q1_O1P1_L1M1N1 = getChildNode(internalFromC, 'a');
+      assertInternalNode(internalT1_R1S1_Q1_O1P1_L1M1N1, 'a', new String[] {
+            "apapapa", "pa", "tt", "erpa", "tt", "er", "n1pa"}, 16, 25, 4, 9);
+      String[] elementsT1 = new String[] {"", "tt", "er", "n2ABC", "pa", "tt",
+            "er", "n3", "ABCsuf", "fi", "x"};
+      char idT1 = KeyPart.KEY_ELEMENT_END;
+      assertChildLeafNode(internalT1_R1S1_Q1_O1P1_L1M1N1, idT1, elementsT1,
+            "T1");
+      String[] elementsR1S1_Q1_O1P1_L1M1N1 = new String[] {"paapa", "tt", "er",
+            "n2", "pa"};
+      char idR1S1_Q1_O1P1_L1M1N1 = 'p';
+      internalR1S1_Q1_O1P1_L1M1N1 = getChildNode(internalT1_R1S1_Q1_O1P1_L1M1N1,
+            idR1S1_Q1_O1P1_L1M1N1);
+      assertInternalNode(internalR1S1_Q1_O1P1_L1M1N1, idR1S1_Q1_O1P1_L1M1N1,
+            elementsR1S1_Q1_O1P1_L1M1N1, 10, 19, 2, 4);
+      assertInternalNode(internalR1S1, idR1S1, elementsR1S1, 6, 8, 2, 5);
+      assertChildLeafNode(internalR1S1, idR1, elementsR1, "R1");
+      assertChildLeafNode(internalR1S1, idS1, elementsS1, "S1");
+      internalQ1_O1P1_L1M1N1 = getChildNode(internalR1S1_Q1_O1P1_L1M1N1,
+            idQ1_O1P1_L1M1N1);
+      assertInternalNode(internalQ1_O1P1_L1M1N1, idQ1_O1P1_L1M1N1,
+            elementsQ1_O1P1_L1M1N1, 6, 15, 2, 5);
+      assertChildLeafNode(internalQ1_O1P1_L1M1N1, idQ1, elementsQ1, "Q1");
+      internalO1P1_L1M1N1 = getChildNode(internalQ1_O1P1_L1M1N1, idO1P1_L1M1N1);
+      assertInternalNode(internalO1P1_L1M1N1, idO1P1_L1M1N1,
+            elementsO1P1_L1M1N1, 7, 12);
+      assertInternalNode(internalO1P1, idO1P1Q1, elementsO1P1Q1, 6, 7);
+      assertChildLeafNode(internalO1P1, idO1, elementsO1, "O1");
+      assertChildLeafNode(internalO1P1, idP1, elementsP1, "P1");
+      assertInternalNode(internalL1M1N1, idL1M1N1, elementsL1M1N1, 5, 10, 2, 5);
+      assertChildLeafNode(internalL1M1N1, idL1, elementsL1, "L1");
+      assertChildLeafNode(internalL1M1N1, idM1, elementsM1, "M1");
+      assertChildLeafNode(internalL1M1N1, idN1, elementsN1, "N1");
+      assertInternalNode(internalK1_I1J1_F1G1H1_D1E1_ZA1B1C1,
+            idK1_I1J1_F1G1H1_D1E1_ZA1B1C1, elementsK1_I1J1_F1G1H1_D1E1_ZA1B1C1,
+            1, 16);
+      assertChildLeafNode(internalK1_I1J1_F1G1H1_D1E1_ZA1B1C1, idK1, elementsK1,
+            "K1");
+      assertInternalNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1,
+            idI1J1_F1G1H1_D1E1_ZA1B1C1, elementsI1J1_F1G1H1_D1E1_ZA1B1C1,
+            14, 15, 2, 9);
+      assertChildLeafNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1, idI1, elementsI1,
+      "I1");
+      assertChildLeafNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1, idJ1, elementsJ1,
+            "J1");
+      assertInternalNode(internalF1G1H1_D1E1_ZA1B1C1, idF1G1H1_D1E1_ZA1B1C1,
+            elementsF1G1H1_D1E1_ZA1B1C1, 7, 7, 3, 10);
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idF1, elementsF1, "F1");
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idG1, elementsG1, "G1");
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idH1, elementsH1, "H1");
+      internalD1E1_ZA1B1C1 = getChildNode(internalF1G1H1_D1E1_ZA1B1C1,
+            idD1E1_ZA1B1C1);
+      assertInternalNode(internalD1E1_ZA1B1C1, idD1E1_ZA1B1C1,
+            elementsD1E1_ZA1B1C1, 3, 3, 2, 6);
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idD1, elementsD1, "D1");
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idE1, elementsE1, "E1");
+      assertInternalNode(internalZA1B1C1, idZA1B1C1, elementsZA1B1C1, 2, 2);
+      assertChildLeafNode(internalZA1B1C1, idZ, elementsZ, "Z");
+      assertChildLeafNode(internalZA1B1C1, idA1, elementsA1, "A1");
+      assertChildLeafNode(internalZA1B1C1, idB1, elementsB1, "B1");
+      assertChildLeafNode(internalZA1B1C1, idC1, elementsC1, "C1");
+      assertInternalNode(internalXY, idXY, elementsXY, 1, 15);
+      assertChildLeafNode(internalXY, idX, elementsX, "X");
+      assertChildLeafNode(internalXY, idY, elementsY, "Y");
+      internalVW_TU_RS_PQ_MNO_JKL_CDEFG = getChildNode(internalFromC,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG);
+      assertInternalNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG, elementsVW_TU_RS_PQ_MNO_JKL_CDEFG, 12,
+            18, 4, 8);
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idV, elementsV,
+      "V");
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idW, elementsW,
+            "W");
+      assertInternalNode(internalTU_RS_PQ_MNO_JKL_CDEFG, '1',
+            elementsTU_RS_PQ_MNO_JKL_CDEFG, 9, 9, 3, 3);
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idT, elementsT, "T");
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idU, elementsU, "U");
+      assertInternalNode(internalRS_PQ_MNO_JKL_CDEFG, idRS_PQ_MNO_JKL_CDEDFG,
+            elementsRS_PQ_MNO_JKL_CDEFG,9, 9);
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idR, elementsR, "R");
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idS, elementsS, "S");
+      assertInternalNode(internalPQ_MNO_JKL_CDEFG, idPQ_MNO_JKL_CDEFG,
+            elementsPQ_MNO_JKL_CDEFG, 7, 7);    
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idP, elementsP, "P");
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idQ, elementsQ, "Q");
+      assertInternalNode(internalMNO_JKL_CDEFG, idMNO_JKL_CDEFG,
+            elementsMNO_JKL_CDEFG, 5, 5);
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idM, elementsM, "M");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idN, elementsN, "N");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idO, elementsO, "O");
+      assertInternalNode(internalJKL_CDEFG, idJKL_CDEFG, elementsJKL_CDEFG, 3,
+            3, 2, 2);
+      assertChildLeafNode(internalJKL_CDEFG, idJ, elementsJ, "J");
+      assertChildLeafNode(internalJKL_CDEFG, idK, elementsK, "K");
+      assertChildLeafNode(internalJKL_CDEFG, idL, elementsL, "L");
+      assertInternalNode(internalCDEFG, idCDEFG, elementsCDEFG, 2, 2);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      assertChildLeafNode(internalCDEFG, idH, elementsH, "H");
+      
+      // insert U1
+      tree.insert("pre.fi.xapapapa.pa.tt.erpa.er.n1.pa.tt.er.n2.pa.tt.er.n3." +
+            "suf.fi.x", "U1");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 27, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      assertInternalNode(internalFromC, idFromC, elementsFromC, 3, 27, 1, 10);
+      Node internalU1V1W1_T1_R1S1_Q1_O1P1_L1M1N1 = getChildNode(internalFromC,
+            'a');
+      assertInternalNode(internalU1V1W1_T1_R1S1_Q1_O1P1_L1M1N1, 'a',
+            new String[] {"apapapa", "pa", "tt", "erpa"}, 16, 25);
+      String[] elementsU1 = new String[] {"er", "n1", "pa", "tt", "er", "n2",
+            "pa", "tt", "er", "n3", "suf", "fi", "x"};
+      char idU1 = 'e';
+      assertChildLeafNode(internalU1V1W1_T1_R1S1_Q1_O1P1_L1M1N1, idU1,
+            elementsU1, "U1");
+      String[] elementsT1_R1S1_Q1_O1P1_L1M1N1 = new String[] {"tt", "er",
+            "n1pa"};
+      char idT1_R1S1_Q1_O1P1_L1M1N1 = 't';
+      internalT1_R1S1_Q1_O1P1_L1M1N1 = getChildNode(
+            internalU1V1W1_T1_R1S1_Q1_O1P1_L1M1N1, idT1_R1S1_Q1_O1P1_L1M1N1);
+      assertInternalNode(internalT1_R1S1_Q1_O1P1_L1M1N1,
+            idT1_R1S1_Q1_O1P1_L1M1N1, elementsT1_R1S1_Q1_O1P1_L1M1N1, 12, 21, 4,
+            9);
+      assertChildLeafNode(internalT1_R1S1_Q1_O1P1_L1M1N1, idT1, elementsT1,
+            "T1");
+      assertInternalNode(internalR1S1_Q1_O1P1_L1M1N1, idR1S1_Q1_O1P1_L1M1N1,
+            elementsR1S1_Q1_O1P1_L1M1N1, 10, 19, 2, 4);
+      assertInternalNode(internalR1S1, idR1S1, elementsR1S1, 6, 8, 2, 5);
+      assertChildLeafNode(internalR1S1, idR1, elementsR1, "R1");
+      assertChildLeafNode(internalR1S1, idS1, elementsS1, "S1");
+      internalQ1_O1P1_L1M1N1 = getChildNode(internalR1S1_Q1_O1P1_L1M1N1,
+            idQ1_O1P1_L1M1N1);
+      assertInternalNode(internalQ1_O1P1_L1M1N1, idQ1_O1P1_L1M1N1,
+            elementsQ1_O1P1_L1M1N1, 6, 15, 2, 5);
+      assertChildLeafNode(internalQ1_O1P1_L1M1N1, idQ1, elementsQ1, "Q1");
+      internalO1P1_L1M1N1 = getChildNode(internalQ1_O1P1_L1M1N1, idO1P1_L1M1N1);
+      assertInternalNode(internalO1P1_L1M1N1, idO1P1_L1M1N1,
+            elementsO1P1_L1M1N1, 7, 12);
+      assertInternalNode(internalO1P1, idO1P1Q1, elementsO1P1Q1, 6, 7);
+      assertChildLeafNode(internalO1P1, idO1, elementsO1, "O1");
+      assertChildLeafNode(internalO1P1, idP1, elementsP1, "P1");
+      assertInternalNode(internalL1M1N1, idL1M1N1, elementsL1M1N1, 5, 10, 2, 5);
+      assertChildLeafNode(internalL1M1N1, idL1, elementsL1, "L1");
+      assertChildLeafNode(internalL1M1N1, idM1, elementsM1, "M1");
+      assertChildLeafNode(internalL1M1N1, idN1, elementsN1, "N1");
+      assertInternalNode(internalK1_I1J1_F1G1H1_D1E1_ZA1B1C1,
+            idK1_I1J1_F1G1H1_D1E1_ZA1B1C1, elementsK1_I1J1_F1G1H1_D1E1_ZA1B1C1,
+            1, 16);
+      assertChildLeafNode(internalK1_I1J1_F1G1H1_D1E1_ZA1B1C1, idK1, elementsK1,
+            "K1");
+      assertInternalNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1,
+            idI1J1_F1G1H1_D1E1_ZA1B1C1, elementsI1J1_F1G1H1_D1E1_ZA1B1C1,
+            14, 15, 2, 9);
+      assertChildLeafNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1, idI1, elementsI1,
+      "I1");
+      assertChildLeafNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1, idJ1, elementsJ1,
+            "J1");
+      assertInternalNode(internalF1G1H1_D1E1_ZA1B1C1, idF1G1H1_D1E1_ZA1B1C1,
+            elementsF1G1H1_D1E1_ZA1B1C1, 7, 7, 3, 10);
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idF1, elementsF1, "F1");
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idG1, elementsG1, "G1");
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idH1, elementsH1, "H1");
+      internalD1E1_ZA1B1C1 = getChildNode(internalF1G1H1_D1E1_ZA1B1C1,
+            idD1E1_ZA1B1C1);
+      assertInternalNode(internalD1E1_ZA1B1C1, idD1E1_ZA1B1C1,
+            elementsD1E1_ZA1B1C1, 3, 3, 2, 6);
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idD1, elementsD1, "D1");
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idE1, elementsE1, "E1");
+      assertInternalNode(internalZA1B1C1, idZA1B1C1, elementsZA1B1C1, 2, 2);
+      assertChildLeafNode(internalZA1B1C1, idZ, elementsZ, "Z");
+      assertChildLeafNode(internalZA1B1C1, idA1, elementsA1, "A1");
+      assertChildLeafNode(internalZA1B1C1, idB1, elementsB1, "B1");
+      assertChildLeafNode(internalZA1B1C1, idC1, elementsC1, "C1");
+      assertInternalNode(internalXY, idXY, elementsXY, 1, 15);
+      assertChildLeafNode(internalXY, idX, elementsX, "X");
+      assertChildLeafNode(internalXY, idY, elementsY, "Y");
+      internalVW_TU_RS_PQ_MNO_JKL_CDEFG = getChildNode(internalFromC,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG);
+      assertInternalNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG, elementsVW_TU_RS_PQ_MNO_JKL_CDEFG, 12,
+            18, 4, 8);
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idV, elementsV,
+      "V");
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idW, elementsW,
+            "W");
+      assertInternalNode(internalTU_RS_PQ_MNO_JKL_CDEFG, '1',
+            elementsTU_RS_PQ_MNO_JKL_CDEFG, 9, 9, 3, 3);
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idT, elementsT, "T");
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idU, elementsU, "U");
+      assertInternalNode(internalRS_PQ_MNO_JKL_CDEFG, idRS_PQ_MNO_JKL_CDEDFG,
+            elementsRS_PQ_MNO_JKL_CDEFG,9, 9);
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idR, elementsR, "R");
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idS, elementsS, "S");
+      assertInternalNode(internalPQ_MNO_JKL_CDEFG, idPQ_MNO_JKL_CDEFG,
+            elementsPQ_MNO_JKL_CDEFG, 7, 7);    
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idP, elementsP, "P");
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idQ, elementsQ, "Q");
+      assertInternalNode(internalMNO_JKL_CDEFG, idMNO_JKL_CDEFG,
+            elementsMNO_JKL_CDEFG, 5, 5);
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idM, elementsM, "M");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idN, elementsN, "N");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idO, elementsO, "O");
+      assertInternalNode(internalJKL_CDEFG, idJKL_CDEFG, elementsJKL_CDEFG, 3,
+            3, 2, 2);
+      assertChildLeafNode(internalJKL_CDEFG, idJ, elementsJ, "J");
+      assertChildLeafNode(internalJKL_CDEFG, idK, elementsK, "K");
+      assertChildLeafNode(internalJKL_CDEFG, idL, elementsL, "L");
+      assertInternalNode(internalCDEFG, idCDEFG, elementsCDEFG, 2, 2);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      assertChildLeafNode(internalCDEFG, idH, elementsH, "H");
+      
+      // insert V1
+      tree.insert("pre.fi.xapapapa.pa.tt.erpa.pa.tt.er.n1.pa.tt.er.n2.pa.tt." +
+            "er.n3suf.fi.x", "V1");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 27, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      assertInternalNode(internalFromC, idFromC, elementsFromC, 3, 27, 1, 10);
+      assertInternalNode(internalU1V1W1_T1_R1S1_Q1_O1P1_L1M1N1, 'a',
+            new String[] {"apapapa", "pa", "tt", "erpa"}, 16, 25);
+      assertChildLeafNode(internalU1V1W1_T1_R1S1_Q1_O1P1_L1M1N1, idU1,
+            elementsU1, "U1");
+      String[] elementsV1 = new String[] {"pa", "tt", "er", "n1", "pa", "tt",
+            "er", "n2", "pa", "tt", "er", "n3suf", "fi", "x"};
+      char idV1 = 'p';
+      assertChildLeafNode(internalU1V1W1_T1_R1S1_Q1_O1P1_L1M1N1, idV1,
+            elementsV1, "V1");
+      assertInternalNode(internalT1_R1S1_Q1_O1P1_L1M1N1,
+            idT1_R1S1_Q1_O1P1_L1M1N1, elementsT1_R1S1_Q1_O1P1_L1M1N1, 12, 21, 4,
+            9);
+      assertChildLeafNode(internalT1_R1S1_Q1_O1P1_L1M1N1, idT1, elementsT1,
+            "T1");
+      assertInternalNode(internalR1S1_Q1_O1P1_L1M1N1, idR1S1_Q1_O1P1_L1M1N1,
+            elementsR1S1_Q1_O1P1_L1M1N1, 10, 19, 2, 4);
+      assertInternalNode(internalR1S1, idR1S1, elementsR1S1, 6, 8, 2, 5);
+      assertChildLeafNode(internalR1S1, idR1, elementsR1, "R1");
+      assertChildLeafNode(internalR1S1, idS1, elementsS1, "S1");
+      internalQ1_O1P1_L1M1N1 = getChildNode(internalR1S1_Q1_O1P1_L1M1N1,
+            idQ1_O1P1_L1M1N1);
+      assertInternalNode(internalQ1_O1P1_L1M1N1, idQ1_O1P1_L1M1N1,
+            elementsQ1_O1P1_L1M1N1, 6, 15, 2, 5);
+      assertChildLeafNode(internalQ1_O1P1_L1M1N1, idQ1, elementsQ1, "Q1");
+      internalO1P1_L1M1N1 = getChildNode(internalQ1_O1P1_L1M1N1, idO1P1_L1M1N1);
+      assertInternalNode(internalO1P1_L1M1N1, idO1P1_L1M1N1,
+            elementsO1P1_L1M1N1, 7, 12);
+      assertInternalNode(internalO1P1, idO1P1Q1, elementsO1P1Q1, 6, 7);
+      assertChildLeafNode(internalO1P1, idO1, elementsO1, "O1");
+      assertChildLeafNode(internalO1P1, idP1, elementsP1, "P1");
+      assertInternalNode(internalL1M1N1, idL1M1N1, elementsL1M1N1, 5, 10, 2, 5);
+      assertChildLeafNode(internalL1M1N1, idL1, elementsL1, "L1");
+      assertChildLeafNode(internalL1M1N1, idM1, elementsM1, "M1");
+      assertChildLeafNode(internalL1M1N1, idN1, elementsN1, "N1");
+      assertInternalNode(internalK1_I1J1_F1G1H1_D1E1_ZA1B1C1,
+            idK1_I1J1_F1G1H1_D1E1_ZA1B1C1, elementsK1_I1J1_F1G1H1_D1E1_ZA1B1C1,
+            1, 16);
+      assertChildLeafNode(internalK1_I1J1_F1G1H1_D1E1_ZA1B1C1, idK1, elementsK1,
+            "K1");
+      assertInternalNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1,
+            idI1J1_F1G1H1_D1E1_ZA1B1C1, elementsI1J1_F1G1H1_D1E1_ZA1B1C1,
+            14, 15, 2, 9);
+      assertChildLeafNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1, idI1, elementsI1,
+      "I1");
+      assertChildLeafNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1, idJ1, elementsJ1,
+            "J1");
+      assertInternalNode(internalF1G1H1_D1E1_ZA1B1C1, idF1G1H1_D1E1_ZA1B1C1,
+            elementsF1G1H1_D1E1_ZA1B1C1, 7, 7, 3, 10);
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idF1, elementsF1, "F1");
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idG1, elementsG1, "G1");
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idH1, elementsH1, "H1");
+      internalD1E1_ZA1B1C1 = getChildNode(internalF1G1H1_D1E1_ZA1B1C1,
+            idD1E1_ZA1B1C1);
+      assertInternalNode(internalD1E1_ZA1B1C1, idD1E1_ZA1B1C1,
+            elementsD1E1_ZA1B1C1, 3, 3, 2, 6);
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idD1, elementsD1, "D1");
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idE1, elementsE1, "E1");
+      assertInternalNode(internalZA1B1C1, idZA1B1C1, elementsZA1B1C1, 2, 2);
+      assertChildLeafNode(internalZA1B1C1, idZ, elementsZ, "Z");
+      assertChildLeafNode(internalZA1B1C1, idA1, elementsA1, "A1");
+      assertChildLeafNode(internalZA1B1C1, idB1, elementsB1, "B1");
+      assertChildLeafNode(internalZA1B1C1, idC1, elementsC1, "C1");
+      assertInternalNode(internalXY, idXY, elementsXY, 1, 15);
+      assertChildLeafNode(internalXY, idX, elementsX, "X");
+      assertChildLeafNode(internalXY, idY, elementsY, "Y");
+      internalVW_TU_RS_PQ_MNO_JKL_CDEFG = getChildNode(internalFromC,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG);
+      assertInternalNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG, elementsVW_TU_RS_PQ_MNO_JKL_CDEFG, 12,
+            18, 4, 8);
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idV, elementsV,
+      "V");
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idW, elementsW,
+            "W");
+      assertInternalNode(internalTU_RS_PQ_MNO_JKL_CDEFG, '1',
+            elementsTU_RS_PQ_MNO_JKL_CDEFG, 9, 9, 3, 3);
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idT, elementsT, "T");
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idU, elementsU, "U");
+      assertInternalNode(internalRS_PQ_MNO_JKL_CDEFG, idRS_PQ_MNO_JKL_CDEDFG,
+            elementsRS_PQ_MNO_JKL_CDEFG,9, 9);
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idR, elementsR, "R");
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idS, elementsS, "S");
+      assertInternalNode(internalPQ_MNO_JKL_CDEFG, idPQ_MNO_JKL_CDEFG,
+            elementsPQ_MNO_JKL_CDEFG, 7, 7);    
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idP, elementsP, "P");
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idQ, elementsQ, "Q");
+      assertInternalNode(internalMNO_JKL_CDEFG, idMNO_JKL_CDEFG,
+            elementsMNO_JKL_CDEFG, 5, 5);
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idM, elementsM, "M");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idN, elementsN, "N");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idO, elementsO, "O");
+      assertInternalNode(internalJKL_CDEFG, idJKL_CDEFG, elementsJKL_CDEFG, 3,
+            3, 2, 2);
+      assertChildLeafNode(internalJKL_CDEFG, idJ, elementsJ, "J");
+      assertChildLeafNode(internalJKL_CDEFG, idK, elementsK, "K");
+      assertChildLeafNode(internalJKL_CDEFG, idL, elementsL, "L");
+      assertInternalNode(internalCDEFG, idCDEFG, elementsCDEFG, 2, 2);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      assertChildLeafNode(internalCDEFG, idH, elementsH, "H");
+      
+      // insert W1
+      tree.insert("pre.fi.xapapapa.pa.tt.erpa.minimal.length.mismatch", "W1");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 27, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      assertInternalNode(internalFromC, idFromC, elementsFromC, 3, 27, 1, 10);
+      assertInternalNode(internalU1V1W1_T1_R1S1_Q1_O1P1_L1M1N1, 'a',
+            new String[] {"apapapa", "pa", "tt", "erpa"}, 7, 25);
+      assertChildLeafNode(internalU1V1W1_T1_R1S1_Q1_O1P1_L1M1N1, idU1,
+            elementsU1, "U1");
+      assertChildLeafNode(internalU1V1W1_T1_R1S1_Q1_O1P1_L1M1N1, idV1,
+            elementsV1, "V1");
+      String[] elementsW1 = new String[] {"minimal", "length", "mismatch"};
+      char idW1 = 'm';
+      assertChildLeafNode(internalU1V1W1_T1_R1S1_Q1_O1P1_L1M1N1, idW1,
+            elementsW1, "W1");
+      assertInternalNode(internalT1_R1S1_Q1_O1P1_L1M1N1,
+            idT1_R1S1_Q1_O1P1_L1M1N1, elementsT1_R1S1_Q1_O1P1_L1M1N1, 12, 21, 4,
+            9);
+      assertChildLeafNode(internalT1_R1S1_Q1_O1P1_L1M1N1, idT1, elementsT1,
+            "T1");
+      assertInternalNode(internalR1S1_Q1_O1P1_L1M1N1, idR1S1_Q1_O1P1_L1M1N1,
+            elementsR1S1_Q1_O1P1_L1M1N1, 10, 19, 2, 4);
+      assertInternalNode(internalR1S1, idR1S1, elementsR1S1, 6, 8, 2, 5);
+      assertChildLeafNode(internalR1S1, idR1, elementsR1, "R1");
+      assertChildLeafNode(internalR1S1, idS1, elementsS1, "S1");
+      internalQ1_O1P1_L1M1N1 = getChildNode(internalR1S1_Q1_O1P1_L1M1N1,
+            idQ1_O1P1_L1M1N1);
+      assertInternalNode(internalQ1_O1P1_L1M1N1, idQ1_O1P1_L1M1N1,
+            elementsQ1_O1P1_L1M1N1, 6, 15, 2, 5);
+      assertChildLeafNode(internalQ1_O1P1_L1M1N1, idQ1, elementsQ1, "Q1");
+      internalO1P1_L1M1N1 = getChildNode(internalQ1_O1P1_L1M1N1, idO1P1_L1M1N1);
+      assertInternalNode(internalO1P1_L1M1N1, idO1P1_L1M1N1,
+            elementsO1P1_L1M1N1, 7, 12);
+      assertInternalNode(internalO1P1, idO1P1Q1, elementsO1P1Q1, 6, 7);
+      assertChildLeafNode(internalO1P1, idO1, elementsO1, "O1");
+      assertChildLeafNode(internalO1P1, idP1, elementsP1, "P1");
+      assertInternalNode(internalL1M1N1, idL1M1N1, elementsL1M1N1, 5, 10, 2, 5);
+      assertChildLeafNode(internalL1M1N1, idL1, elementsL1, "L1");
+      assertChildLeafNode(internalL1M1N1, idM1, elementsM1, "M1");
+      assertChildLeafNode(internalL1M1N1, idN1, elementsN1, "N1");
+      assertInternalNode(internalK1_I1J1_F1G1H1_D1E1_ZA1B1C1,
+            idK1_I1J1_F1G1H1_D1E1_ZA1B1C1, elementsK1_I1J1_F1G1H1_D1E1_ZA1B1C1,
+            1, 16);
+      assertChildLeafNode(internalK1_I1J1_F1G1H1_D1E1_ZA1B1C1, idK1, elementsK1,
+            "K1");
+      assertInternalNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1,
+            idI1J1_F1G1H1_D1E1_ZA1B1C1, elementsI1J1_F1G1H1_D1E1_ZA1B1C1,
+            14, 15, 2, 9);
+      assertChildLeafNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1, idI1, elementsI1,
+      "I1");
+      assertChildLeafNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1, idJ1, elementsJ1,
+            "J1");
+      assertInternalNode(internalF1G1H1_D1E1_ZA1B1C1, idF1G1H1_D1E1_ZA1B1C1,
+            elementsF1G1H1_D1E1_ZA1B1C1, 7, 7, 3, 10);
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idF1, elementsF1, "F1");
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idG1, elementsG1, "G1");
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idH1, elementsH1, "H1");
+      internalD1E1_ZA1B1C1 = getChildNode(internalF1G1H1_D1E1_ZA1B1C1,
+            idD1E1_ZA1B1C1);
+      assertInternalNode(internalD1E1_ZA1B1C1, idD1E1_ZA1B1C1,
+            elementsD1E1_ZA1B1C1, 3, 3, 2, 6);
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idD1, elementsD1, "D1");
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idE1, elementsE1, "E1");
+      assertInternalNode(internalZA1B1C1, idZA1B1C1, elementsZA1B1C1, 2, 2);
+      assertChildLeafNode(internalZA1B1C1, idZ, elementsZ, "Z");
+      assertChildLeafNode(internalZA1B1C1, idA1, elementsA1, "A1");
+      assertChildLeafNode(internalZA1B1C1, idB1, elementsB1, "B1");
+      assertChildLeafNode(internalZA1B1C1, idC1, elementsC1, "C1");
+      assertInternalNode(internalXY, idXY, elementsXY, 1, 15);
+      assertChildLeafNode(internalXY, idX, elementsX, "X");
+      assertChildLeafNode(internalXY, idY, elementsY, "Y");
+      internalVW_TU_RS_PQ_MNO_JKL_CDEFG = getChildNode(internalFromC,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG);
+      assertInternalNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG, elementsVW_TU_RS_PQ_MNO_JKL_CDEFG, 12,
+            18, 4, 8);
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idV, elementsV,
+      "V");
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idW, elementsW,
+            "W");
+      assertInternalNode(internalTU_RS_PQ_MNO_JKL_CDEFG, '1',
+            elementsTU_RS_PQ_MNO_JKL_CDEFG, 9, 9, 3, 3);
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idT, elementsT, "T");
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idU, elementsU, "U");
+      assertInternalNode(internalRS_PQ_MNO_JKL_CDEFG, idRS_PQ_MNO_JKL_CDEDFG,
+            elementsRS_PQ_MNO_JKL_CDEFG,9, 9);
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idR, elementsR, "R");
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idS, elementsS, "S");
+      assertInternalNode(internalPQ_MNO_JKL_CDEFG, idPQ_MNO_JKL_CDEFG,
+            elementsPQ_MNO_JKL_CDEFG, 7, 7);    
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idP, elementsP, "P");
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idQ, elementsQ, "Q");
+      assertInternalNode(internalMNO_JKL_CDEFG, idMNO_JKL_CDEFG,
+            elementsMNO_JKL_CDEFG, 5, 5);
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idM, elementsM, "M");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idN, elementsN, "N");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idO, elementsO, "O");
+      assertInternalNode(internalJKL_CDEFG, idJKL_CDEFG, elementsJKL_CDEFG, 3,
+            3, 2, 2);
+      assertChildLeafNode(internalJKL_CDEFG, idJ, elementsJ, "J");
+      assertChildLeafNode(internalJKL_CDEFG, idK, elementsK, "K");
+      assertChildLeafNode(internalJKL_CDEFG, idL, elementsL, "L");
+      assertInternalNode(internalCDEFG, idCDEFG, elementsCDEFG, 2, 2);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      assertChildLeafNode(internalCDEFG, idH, elementsH, "H");
+      
+      // insert X1
+      tree.insert("pre.fi.xapapa.tt.er.n1.pa.tt.er.n2pa.tt.er.n3.suf.fi.x",
+            "X1");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 27, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      assertInternalNode(internalFromC, idFromC, elementsFromC, 3, 27, 1, 10);
+      Node internalX1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1 = getChildNode(
+            internalFromC, 'a');
+      assertInternalNode(internalX1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1, 'a',
+            new String[] {"apapa"}, 7, 25, 5, 7);
+      String[] elementsX1 = new String[] {"", "tt", "er", "n1", "pa", "tt",
+            "er", "n2pa", "tt", "er", "n3", "suf", "fi", "x"};
+      char idX1 = KeyPart.KEY_ELEMENT_END;
+      assertChildLeafNode(internalX1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1, idX1,
+            elementsX1, "X1");
+      String[] elementsU1V1W1_T1_R1S1_Q1_O1P1_L1M1N1 = new String[] {"pa", "pa",
+            "tt", "erpa"};
+      char idU1V1W1_T1_R1S1_Q1_O1P1_L1M1N1 = 'p';
+      internalU1V1W1_T1_R1S1_Q1_O1P1_L1M1N1 = getChildNode(
+            internalX1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1,
+            idU1V1W1_T1_R1S1_Q1_O1P1_L1M1N1);
+      assertInternalNode(internalU1V1W1_T1_R1S1_Q1_O1P1_L1M1N1,
+            idU1V1W1_T1_R1S1_Q1_O1P1_L1M1N1,
+            elementsU1V1W1_T1_R1S1_Q1_O1P1_L1M1N1, 7, 25);
+      assertChildLeafNode(internalU1V1W1_T1_R1S1_Q1_O1P1_L1M1N1, idU1,
+            elementsU1, "U1");
+      assertChildLeafNode(internalU1V1W1_T1_R1S1_Q1_O1P1_L1M1N1, idV1,
+            elementsV1, "V1");
+      assertChildLeafNode(internalU1V1W1_T1_R1S1_Q1_O1P1_L1M1N1, idW1,
+            elementsW1, "W1");
+      assertInternalNode(internalT1_R1S1_Q1_O1P1_L1M1N1,
+            idT1_R1S1_Q1_O1P1_L1M1N1, elementsT1_R1S1_Q1_O1P1_L1M1N1, 12, 21, 4,
+            9);
+      assertChildLeafNode(internalT1_R1S1_Q1_O1P1_L1M1N1, idT1, elementsT1,
+            "T1");
+      assertInternalNode(internalR1S1_Q1_O1P1_L1M1N1, idR1S1_Q1_O1P1_L1M1N1,
+            elementsR1S1_Q1_O1P1_L1M1N1, 10, 19, 2, 4);
+      assertInternalNode(internalR1S1, idR1S1, elementsR1S1, 6, 8, 2, 5);
+      assertChildLeafNode(internalR1S1, idR1, elementsR1, "R1");
+      assertChildLeafNode(internalR1S1, idS1, elementsS1, "S1");
+      internalQ1_O1P1_L1M1N1 = getChildNode(internalR1S1_Q1_O1P1_L1M1N1,
+            idQ1_O1P1_L1M1N1);
+      assertInternalNode(internalQ1_O1P1_L1M1N1, idQ1_O1P1_L1M1N1,
+            elementsQ1_O1P1_L1M1N1, 6, 15, 2, 5);
+      assertChildLeafNode(internalQ1_O1P1_L1M1N1, idQ1, elementsQ1, "Q1");
+      internalO1P1_L1M1N1 = getChildNode(internalQ1_O1P1_L1M1N1, idO1P1_L1M1N1);
+      assertInternalNode(internalO1P1_L1M1N1, idO1P1_L1M1N1,
+            elementsO1P1_L1M1N1, 7, 12);
+      assertInternalNode(internalO1P1, idO1P1Q1, elementsO1P1Q1, 6, 7);
+      assertChildLeafNode(internalO1P1, idO1, elementsO1, "O1");
+      assertChildLeafNode(internalO1P1, idP1, elementsP1, "P1");
+      assertInternalNode(internalL1M1N1, idL1M1N1, elementsL1M1N1, 5, 10, 2, 5);
+      assertChildLeafNode(internalL1M1N1, idL1, elementsL1, "L1");
+      assertChildLeafNode(internalL1M1N1, idM1, elementsM1, "M1");
+      assertChildLeafNode(internalL1M1N1, idN1, elementsN1, "N1");
+      assertInternalNode(internalK1_I1J1_F1G1H1_D1E1_ZA1B1C1,
+            idK1_I1J1_F1G1H1_D1E1_ZA1B1C1, elementsK1_I1J1_F1G1H1_D1E1_ZA1B1C1,
+            1, 16);
+      assertChildLeafNode(internalK1_I1J1_F1G1H1_D1E1_ZA1B1C1, idK1, elementsK1,
+            "K1");
+      assertInternalNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1,
+            idI1J1_F1G1H1_D1E1_ZA1B1C1, elementsI1J1_F1G1H1_D1E1_ZA1B1C1,
+            14, 15, 2, 9);
+      assertChildLeafNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1, idI1, elementsI1,
+      "I1");
+      assertChildLeafNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1, idJ1, elementsJ1,
+            "J1");
+      assertInternalNode(internalF1G1H1_D1E1_ZA1B1C1, idF1G1H1_D1E1_ZA1B1C1,
+            elementsF1G1H1_D1E1_ZA1B1C1, 7, 7, 3, 10);
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idF1, elementsF1, "F1");
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idG1, elementsG1, "G1");
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idH1, elementsH1, "H1");
+      internalD1E1_ZA1B1C1 = getChildNode(internalF1G1H1_D1E1_ZA1B1C1,
+            idD1E1_ZA1B1C1);
+      assertInternalNode(internalD1E1_ZA1B1C1, idD1E1_ZA1B1C1,
+            elementsD1E1_ZA1B1C1, 3, 3, 2, 6);
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idD1, elementsD1, "D1");
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idE1, elementsE1, "E1");
+      assertInternalNode(internalZA1B1C1, idZA1B1C1, elementsZA1B1C1, 2, 2);
+      assertChildLeafNode(internalZA1B1C1, idZ, elementsZ, "Z");
+      assertChildLeafNode(internalZA1B1C1, idA1, elementsA1, "A1");
+      assertChildLeafNode(internalZA1B1C1, idB1, elementsB1, "B1");
+      assertChildLeafNode(internalZA1B1C1, idC1, elementsC1, "C1");
+      assertInternalNode(internalXY, idXY, elementsXY, 1, 15);
+      assertChildLeafNode(internalXY, idX, elementsX, "X");
+      assertChildLeafNode(internalXY, idY, elementsY, "Y");
+      internalVW_TU_RS_PQ_MNO_JKL_CDEFG = getChildNode(internalFromC,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG);
+      assertInternalNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG, elementsVW_TU_RS_PQ_MNO_JKL_CDEFG, 12,
+            18, 4, 8);
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idV, elementsV,
+      "V");
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idW, elementsW,
+            "W");
+      assertInternalNode(internalTU_RS_PQ_MNO_JKL_CDEFG, '1',
+            elementsTU_RS_PQ_MNO_JKL_CDEFG, 9, 9, 3, 3);
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idT, elementsT, "T");
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idU, elementsU, "U");
+      assertInternalNode(internalRS_PQ_MNO_JKL_CDEFG, idRS_PQ_MNO_JKL_CDEDFG,
+            elementsRS_PQ_MNO_JKL_CDEFG,9, 9);
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idR, elementsR, "R");
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idS, elementsS, "S");
+      assertInternalNode(internalPQ_MNO_JKL_CDEFG, idPQ_MNO_JKL_CDEFG,
+            elementsPQ_MNO_JKL_CDEFG, 7, 7);    
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idP, elementsP, "P");
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idQ, elementsQ, "Q");
+      assertInternalNode(internalMNO_JKL_CDEFG, idMNO_JKL_CDEFG,
+            elementsMNO_JKL_CDEFG, 5, 5);
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idM, elementsM, "M");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idN, elementsN, "N");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idO, elementsO, "O");
+      assertInternalNode(internalJKL_CDEFG, idJKL_CDEFG, elementsJKL_CDEFG, 3,
+            3, 2, 2);
+      assertChildLeafNode(internalJKL_CDEFG, idJ, elementsJ, "J");
+      assertChildLeafNode(internalJKL_CDEFG, idK, elementsK, "K");
+      assertChildLeafNode(internalJKL_CDEFG, idL, elementsL, "L");
+      assertInternalNode(internalCDEFG, idCDEFG, elementsCDEFG, 2, 2);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      assertChildLeafNode(internalCDEFG, idH, elementsH, "H");
+      
+      // insert Y1
+      tree.insert("pre.fi.xapa.tt.er.n1.pa.tt.er.n2pa.tt.er.n3.suf.fi.x", "Y1");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 27, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      assertInternalNode(internalFromC, idFromC, elementsFromC, 3, 27, 1, 10);
+      Node internalY1_X1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1 = getChildNode(
+            internalFromC, 'a');
+      assertInternalNode(internalY1_X1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1, 'a',
+            new String[] {"apa"}, 7, 25, 3, 7);
+      String[] elementsY1 = new String[] {"", "tt", "er", "n1", "pa", "tt",
+            "er", "n2pa", "tt", "er", "n3", "suf", "fi", "x"};
+      char idY1 = KeyPart.KEY_ELEMENT_END;
+      assertChildLeafNode(internalY1_X1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1, idY1,
+            elementsY1, "Y1");
+      String[] elementsX1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1 = new String[] {"pa"};
+      char idX1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1 = 'p';
+      internalX1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1 = getChildNode(
+            internalY1_X1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1,
+            idX1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1);
+      assertInternalNode(internalX1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1,
+            idX1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1,
+            elementsX1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1, 7, 25, 2, 4);
+      assertChildLeafNode(internalX1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1, idX1,
+            elementsX1, "X1");
+      assertInternalNode(internalU1V1W1_T1_R1S1_Q1_O1P1_L1M1N1,
+            idU1V1W1_T1_R1S1_Q1_O1P1_L1M1N1,
+            elementsU1V1W1_T1_R1S1_Q1_O1P1_L1M1N1, 7, 25);
+      assertChildLeafNode(internalU1V1W1_T1_R1S1_Q1_O1P1_L1M1N1, idU1,
+            elementsU1, "U1");
+      assertChildLeafNode(internalU1V1W1_T1_R1S1_Q1_O1P1_L1M1N1, idV1,
+            elementsV1, "V1");
+      assertChildLeafNode(internalU1V1W1_T1_R1S1_Q1_O1P1_L1M1N1, idW1,
+            elementsW1, "W1");
+      assertInternalNode(internalT1_R1S1_Q1_O1P1_L1M1N1,
+            idT1_R1S1_Q1_O1P1_L1M1N1, elementsT1_R1S1_Q1_O1P1_L1M1N1, 12, 21, 4,
+            9);
+      assertChildLeafNode(internalT1_R1S1_Q1_O1P1_L1M1N1, idT1, elementsT1,
+            "T1");
+      assertInternalNode(internalR1S1_Q1_O1P1_L1M1N1, idR1S1_Q1_O1P1_L1M1N1,
+            elementsR1S1_Q1_O1P1_L1M1N1, 10, 19, 2, 4);
+      assertInternalNode(internalR1S1, idR1S1, elementsR1S1, 6, 8, 2, 5);
+      assertChildLeafNode(internalR1S1, idR1, elementsR1, "R1");
+      assertChildLeafNode(internalR1S1, idS1, elementsS1, "S1");
+      internalQ1_O1P1_L1M1N1 = getChildNode(internalR1S1_Q1_O1P1_L1M1N1,
+            idQ1_O1P1_L1M1N1);
+      assertInternalNode(internalQ1_O1P1_L1M1N1, idQ1_O1P1_L1M1N1,
+            elementsQ1_O1P1_L1M1N1, 6, 15, 2, 5);
+      assertChildLeafNode(internalQ1_O1P1_L1M1N1, idQ1, elementsQ1, "Q1");
+      internalO1P1_L1M1N1 = getChildNode(internalQ1_O1P1_L1M1N1, idO1P1_L1M1N1);
+      assertInternalNode(internalO1P1_L1M1N1, idO1P1_L1M1N1,
+            elementsO1P1_L1M1N1, 7, 12);
+      assertInternalNode(internalO1P1, idO1P1Q1, elementsO1P1Q1, 6, 7);
+      assertChildLeafNode(internalO1P1, idO1, elementsO1, "O1");
+      assertChildLeafNode(internalO1P1, idP1, elementsP1, "P1");
+      assertInternalNode(internalL1M1N1, idL1M1N1, elementsL1M1N1, 5, 10, 2, 5);
+      assertChildLeafNode(internalL1M1N1, idL1, elementsL1, "L1");
+      assertChildLeafNode(internalL1M1N1, idM1, elementsM1, "M1");
+      assertChildLeafNode(internalL1M1N1, idN1, elementsN1, "N1");
+      assertInternalNode(internalK1_I1J1_F1G1H1_D1E1_ZA1B1C1,
+            idK1_I1J1_F1G1H1_D1E1_ZA1B1C1, elementsK1_I1J1_F1G1H1_D1E1_ZA1B1C1,
+            1, 16);
+      assertChildLeafNode(internalK1_I1J1_F1G1H1_D1E1_ZA1B1C1, idK1, elementsK1,
+            "K1");
+      assertInternalNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1,
+            idI1J1_F1G1H1_D1E1_ZA1B1C1, elementsI1J1_F1G1H1_D1E1_ZA1B1C1,
+            14, 15, 2, 9);
+      assertChildLeafNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1, idI1, elementsI1,
+      "I1");
+      assertChildLeafNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1, idJ1, elementsJ1,
+            "J1");
+      assertInternalNode(internalF1G1H1_D1E1_ZA1B1C1, idF1G1H1_D1E1_ZA1B1C1,
+            elementsF1G1H1_D1E1_ZA1B1C1, 7, 7, 3, 10);
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idF1, elementsF1, "F1");
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idG1, elementsG1, "G1");
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idH1, elementsH1, "H1");
+      internalD1E1_ZA1B1C1 = getChildNode(internalF1G1H1_D1E1_ZA1B1C1,
+            idD1E1_ZA1B1C1);
+      assertInternalNode(internalD1E1_ZA1B1C1, idD1E1_ZA1B1C1,
+            elementsD1E1_ZA1B1C1, 3, 3, 2, 6);
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idD1, elementsD1, "D1");
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idE1, elementsE1, "E1");
+      assertInternalNode(internalZA1B1C1, idZA1B1C1, elementsZA1B1C1, 2, 2);
+      assertChildLeafNode(internalZA1B1C1, idZ, elementsZ, "Z");
+      assertChildLeafNode(internalZA1B1C1, idA1, elementsA1, "A1");
+      assertChildLeafNode(internalZA1B1C1, idB1, elementsB1, "B1");
+      assertChildLeafNode(internalZA1B1C1, idC1, elementsC1, "C1");
+      assertInternalNode(internalXY, idXY, elementsXY, 1, 15);
+      assertChildLeafNode(internalXY, idX, elementsX, "X");
+      assertChildLeafNode(internalXY, idY, elementsY, "Y");
+      internalVW_TU_RS_PQ_MNO_JKL_CDEFG = getChildNode(internalFromC,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG);
+      assertInternalNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG, elementsVW_TU_RS_PQ_MNO_JKL_CDEFG, 12,
+            18, 4, 8);
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idV, elementsV,
+      "V");
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idW, elementsW,
+            "W");
+      assertInternalNode(internalTU_RS_PQ_MNO_JKL_CDEFG, '1',
+            elementsTU_RS_PQ_MNO_JKL_CDEFG, 9, 9, 3, 3);
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idT, elementsT, "T");
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idU, elementsU, "U");
+      assertInternalNode(internalRS_PQ_MNO_JKL_CDEFG, idRS_PQ_MNO_JKL_CDEDFG,
+            elementsRS_PQ_MNO_JKL_CDEFG,9, 9);
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idR, elementsR, "R");
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idS, elementsS, "S");
+      assertInternalNode(internalPQ_MNO_JKL_CDEFG, idPQ_MNO_JKL_CDEFG,
+            elementsPQ_MNO_JKL_CDEFG, 7, 7);    
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idP, elementsP, "P");
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idQ, elementsQ, "Q");
+      assertInternalNode(internalMNO_JKL_CDEFG, idMNO_JKL_CDEFG,
+            elementsMNO_JKL_CDEFG, 5, 5);
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idM, elementsM, "M");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idN, elementsN, "N");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idO, elementsO, "O");
+      assertInternalNode(internalJKL_CDEFG, idJKL_CDEFG, elementsJKL_CDEFG, 3,
+            3, 2, 2);
+      assertChildLeafNode(internalJKL_CDEFG, idJ, elementsJ, "J");
+      assertChildLeafNode(internalJKL_CDEFG, idK, elementsK, "K");
+      assertChildLeafNode(internalJKL_CDEFG, idL, elementsL, "L");
+      assertInternalNode(internalCDEFG, idCDEFG, elementsCDEFG, 2, 2);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      assertChildLeafNode(internalCDEFG, idH, elementsH, "H");
+      
+      // insert Z1
+      tree.insert("pre.fi.xap.pa.tt.er.n1pa.tt.er.n2pa.tt.er.n3.suf.fi.x",
+            "Z1");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 27, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      assertInternalNode(internalFromC, idFromC, elementsFromC, 3, 27, 1, 10);
+      String[] elementsZ1A2_Y1_X1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1 =
+         new String[] {"ap"};
+      char idZ1A2_Y1_X1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1 = 'a';
+      Node internalZ1A2_Y1_X1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1 = getChildNode(
+            internalFromC, idZ1A2_Y1_X1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1);
+      assertInternalNode(internalZ1A2_Y1_X1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1,
+            idZ1A2_Y1_X1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1,
+            elementsZ1A2_Y1_X1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1, 7, 25, 2, 7);
+      String[] elementsZ1 = new String[] {"", "pa", "tt", "er", "n1pa", "tt",
+            "er", "n2pa", "tt", "er", "n3", "suf", "fi", "x"};
+      char idZ1 = KeyPart.KEY_ELEMENT_END;
+      assertChildLeafNode(internalZ1A2_Y1_X1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1,
+            idZ1, elementsZ1, "Z1");
+      String[] elementsY1_X1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1 = new String[] {"a"};
+      char idY1_X1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1 = 'a';
+      internalY1_X1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1 = getChildNode(
+            internalZ1A2_Y1_X1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1,
+            idY1_X1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1);
+      assertInternalNode(internalY1_X1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1,
+            idY1_X1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1,
+            elementsY1_X1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1, 7, 25, 1, 5);
+      assertChildLeafNode(internalY1_X1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1, idY1,
+            elementsY1, "Y1");
+      assertInternalNode(internalX1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1,
+            idX1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1,
+            elementsX1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1, 7, 25, 2, 4);
+      assertChildLeafNode(internalX1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1, idX1,
+            elementsX1, "X1");
+      assertInternalNode(internalU1V1W1_T1_R1S1_Q1_O1P1_L1M1N1,
+            idU1V1W1_T1_R1S1_Q1_O1P1_L1M1N1,
+            elementsU1V1W1_T1_R1S1_Q1_O1P1_L1M1N1, 7, 25);
+      assertChildLeafNode(internalU1V1W1_T1_R1S1_Q1_O1P1_L1M1N1, idU1,
+            elementsU1, "U1");
+      assertChildLeafNode(internalU1V1W1_T1_R1S1_Q1_O1P1_L1M1N1, idV1,
+            elementsV1, "V1");
+      assertChildLeafNode(internalU1V1W1_T1_R1S1_Q1_O1P1_L1M1N1, idW1,
+            elementsW1, "W1");
+      assertInternalNode(internalT1_R1S1_Q1_O1P1_L1M1N1,
+            idT1_R1S1_Q1_O1P1_L1M1N1, elementsT1_R1S1_Q1_O1P1_L1M1N1, 12, 21, 4,
+            9);
+      assertChildLeafNode(internalT1_R1S1_Q1_O1P1_L1M1N1, idT1, elementsT1,
+            "T1");
+      assertInternalNode(internalR1S1_Q1_O1P1_L1M1N1, idR1S1_Q1_O1P1_L1M1N1,
+            elementsR1S1_Q1_O1P1_L1M1N1, 10, 19, 2, 4);
+      assertInternalNode(internalR1S1, idR1S1, elementsR1S1, 6, 8, 2, 5);
+      assertChildLeafNode(internalR1S1, idR1, elementsR1, "R1");
+      assertChildLeafNode(internalR1S1, idS1, elementsS1, "S1");
+      internalQ1_O1P1_L1M1N1 = getChildNode(internalR1S1_Q1_O1P1_L1M1N1,
+            idQ1_O1P1_L1M1N1);
+      assertInternalNode(internalQ1_O1P1_L1M1N1, idQ1_O1P1_L1M1N1,
+            elementsQ1_O1P1_L1M1N1, 6, 15, 2, 5);
+      assertChildLeafNode(internalQ1_O1P1_L1M1N1, idQ1, elementsQ1, "Q1");
+      internalO1P1_L1M1N1 = getChildNode(internalQ1_O1P1_L1M1N1, idO1P1_L1M1N1);
+      assertInternalNode(internalO1P1_L1M1N1, idO1P1_L1M1N1,
+            elementsO1P1_L1M1N1, 7, 12);
+      assertInternalNode(internalO1P1, idO1P1Q1, elementsO1P1Q1, 6, 7);
+      assertChildLeafNode(internalO1P1, idO1, elementsO1, "O1");
+      assertChildLeafNode(internalO1P1, idP1, elementsP1, "P1");
+      assertInternalNode(internalL1M1N1, idL1M1N1, elementsL1M1N1, 5, 10, 2, 5);
+      assertChildLeafNode(internalL1M1N1, idL1, elementsL1, "L1");
+      assertChildLeafNode(internalL1M1N1, idM1, elementsM1, "M1");
+      assertChildLeafNode(internalL1M1N1, idN1, elementsN1, "N1");
+      assertInternalNode(internalK1_I1J1_F1G1H1_D1E1_ZA1B1C1,
+            idK1_I1J1_F1G1H1_D1E1_ZA1B1C1, elementsK1_I1J1_F1G1H1_D1E1_ZA1B1C1,
+            1, 16);
+      assertChildLeafNode(internalK1_I1J1_F1G1H1_D1E1_ZA1B1C1, idK1, elementsK1,
+            "K1");
+      assertInternalNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1,
+            idI1J1_F1G1H1_D1E1_ZA1B1C1, elementsI1J1_F1G1H1_D1E1_ZA1B1C1,
+            14, 15, 2, 9);
+      assertChildLeafNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1, idI1, elementsI1,
+      "I1");
+      assertChildLeafNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1, idJ1, elementsJ1,
+            "J1");
+      assertInternalNode(internalF1G1H1_D1E1_ZA1B1C1, idF1G1H1_D1E1_ZA1B1C1,
+            elementsF1G1H1_D1E1_ZA1B1C1, 7, 7, 3, 10);
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idF1, elementsF1, "F1");
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idG1, elementsG1, "G1");
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idH1, elementsH1, "H1");
+      internalD1E1_ZA1B1C1 = getChildNode(internalF1G1H1_D1E1_ZA1B1C1,
+            idD1E1_ZA1B1C1);
+      assertInternalNode(internalD1E1_ZA1B1C1, idD1E1_ZA1B1C1,
+            elementsD1E1_ZA1B1C1, 3, 3, 2, 6);
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idD1, elementsD1, "D1");
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idE1, elementsE1, "E1");
+      assertInternalNode(internalZA1B1C1, idZA1B1C1, elementsZA1B1C1, 2, 2);
+      assertChildLeafNode(internalZA1B1C1, idZ, elementsZ, "Z");
+      assertChildLeafNode(internalZA1B1C1, idA1, elementsA1, "A1");
+      assertChildLeafNode(internalZA1B1C1, idB1, elementsB1, "B1");
+      assertChildLeafNode(internalZA1B1C1, idC1, elementsC1, "C1");
+      assertInternalNode(internalXY, idXY, elementsXY, 1, 15);
+      assertChildLeafNode(internalXY, idX, elementsX, "X");
+      assertChildLeafNode(internalXY, idY, elementsY, "Y");
+      internalVW_TU_RS_PQ_MNO_JKL_CDEFG = getChildNode(internalFromC,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG);
+      assertInternalNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG, elementsVW_TU_RS_PQ_MNO_JKL_CDEFG, 12,
+            18, 4, 8);
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idV, elementsV,
+      "V");
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idW, elementsW,
+            "W");
+      assertInternalNode(internalTU_RS_PQ_MNO_JKL_CDEFG, '1',
+            elementsTU_RS_PQ_MNO_JKL_CDEFG, 9, 9, 3, 3);
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idT, elementsT, "T");
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idU, elementsU, "U");
+      assertInternalNode(internalRS_PQ_MNO_JKL_CDEFG, idRS_PQ_MNO_JKL_CDEDFG,
+            elementsRS_PQ_MNO_JKL_CDEFG,9, 9);
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idR, elementsR, "R");
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idS, elementsS, "S");
+      assertInternalNode(internalPQ_MNO_JKL_CDEFG, idPQ_MNO_JKL_CDEFG,
+            elementsPQ_MNO_JKL_CDEFG, 7, 7);    
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idP, elementsP, "P");
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idQ, elementsQ, "Q");
+      assertInternalNode(internalMNO_JKL_CDEFG, idMNO_JKL_CDEFG,
+            elementsMNO_JKL_CDEFG, 5, 5);
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idM, elementsM, "M");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idN, elementsN, "N");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idO, elementsO, "O");
+      assertInternalNode(internalJKL_CDEFG, idJKL_CDEFG, elementsJKL_CDEFG, 3,
+            3, 2, 2);
+      assertChildLeafNode(internalJKL_CDEFG, idJ, elementsJ, "J");
+      assertChildLeafNode(internalJKL_CDEFG, idK, elementsK, "K");
+      assertChildLeafNode(internalJKL_CDEFG, idL, elementsL, "L");
+      assertInternalNode(internalCDEFG, idCDEFG, elementsCDEFG, 2, 2);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      assertChildLeafNode(internalCDEFG, idH, elementsH, "H");
+      
+      // insert A2
+      tree.insert("pre.fi.xapbpa.tt.er.n2.pa.tt.er.n3.suf.fi.x", "A2");
+      assertInternalNode(root, KeyPart.KEY_ELEMENT_END, rootElements, 2, 27, 3,
+            5);
+      assertChildLeafNode(root, idA, elementsA, "A");
+      assertChildLeafNode(root, idB, elementsB, "B");
+      assertInternalNode(internalFromC, idFromC, elementsFromC, 3, 27, 1, 10);
+      assertInternalNode(internalZ1A2_Y1_X1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1,
+            idZ1A2_Y1_X1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1,
+            elementsZ1A2_Y1_X1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1, 7, 25, 2, 7);
+      assertChildLeafNode(internalZ1A2_Y1_X1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1,
+            idZ1, elementsZ1, "Z1");
+      String[] elementsA2 = new String[] {"bpa", "tt", "er", "n2", "pa", "tt",
+            "er", "n3", "suf", "fi", "x"};
+      char idA2 = 'b';
+      assertChildLeafNode(internalZ1A2_Y1_X1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1,
+            idA2, elementsA2, "A2");
+      assertInternalNode(internalY1_X1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1,
+            idY1_X1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1,
+            elementsY1_X1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1, 7, 25, 1, 5);
+      assertChildLeafNode(internalY1_X1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1, idY1,
+            elementsY1, "Y1");
+      assertInternalNode(internalX1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1,
+            idX1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1,
+            elementsX1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1, 7, 25, 2, 4);
+      assertChildLeafNode(internalX1_U1V1W1_T1_R1S1_Q1_O1P1_L1M1N1, idX1,
+            elementsX1, "X1");
+      assertInternalNode(internalU1V1W1_T1_R1S1_Q1_O1P1_L1M1N1,
+            idU1V1W1_T1_R1S1_Q1_O1P1_L1M1N1,
+            elementsU1V1W1_T1_R1S1_Q1_O1P1_L1M1N1, 7, 25);
+      assertChildLeafNode(internalU1V1W1_T1_R1S1_Q1_O1P1_L1M1N1, idU1,
+            elementsU1, "U1");
+      assertChildLeafNode(internalU1V1W1_T1_R1S1_Q1_O1P1_L1M1N1, idV1,
+            elementsV1, "V1");
+      assertChildLeafNode(internalU1V1W1_T1_R1S1_Q1_O1P1_L1M1N1, idW1,
+            elementsW1, "W1");
+      assertInternalNode(internalT1_R1S1_Q1_O1P1_L1M1N1,
+            idT1_R1S1_Q1_O1P1_L1M1N1, elementsT1_R1S1_Q1_O1P1_L1M1N1, 12, 21, 4,
+            9);
+      assertChildLeafNode(internalT1_R1S1_Q1_O1P1_L1M1N1, idT1, elementsT1,
+            "T1");
+      assertInternalNode(internalR1S1_Q1_O1P1_L1M1N1, idR1S1_Q1_O1P1_L1M1N1,
+            elementsR1S1_Q1_O1P1_L1M1N1, 10, 19, 2, 4);
+      assertInternalNode(internalR1S1, idR1S1, elementsR1S1, 6, 8, 2, 5);
+      assertChildLeafNode(internalR1S1, idR1, elementsR1, "R1");
+      assertChildLeafNode(internalR1S1, idS1, elementsS1, "S1");
+      internalQ1_O1P1_L1M1N1 = getChildNode(internalR1S1_Q1_O1P1_L1M1N1,
+            idQ1_O1P1_L1M1N1);
+      assertInternalNode(internalQ1_O1P1_L1M1N1, idQ1_O1P1_L1M1N1,
+            elementsQ1_O1P1_L1M1N1, 6, 15, 2, 5);
+      assertChildLeafNode(internalQ1_O1P1_L1M1N1, idQ1, elementsQ1, "Q1");
+      internalO1P1_L1M1N1 = getChildNode(internalQ1_O1P1_L1M1N1, idO1P1_L1M1N1);
+      assertInternalNode(internalO1P1_L1M1N1, idO1P1_L1M1N1,
+            elementsO1P1_L1M1N1, 7, 12);
+      assertInternalNode(internalO1P1, idO1P1Q1, elementsO1P1Q1, 6, 7);
+      assertChildLeafNode(internalO1P1, idO1, elementsO1, "O1");
+      assertChildLeafNode(internalO1P1, idP1, elementsP1, "P1");
+      assertInternalNode(internalL1M1N1, idL1M1N1, elementsL1M1N1, 5, 10, 2, 5);
+      assertChildLeafNode(internalL1M1N1, idL1, elementsL1, "L1");
+      assertChildLeafNode(internalL1M1N1, idM1, elementsM1, "M1");
+      assertChildLeafNode(internalL1M1N1, idN1, elementsN1, "N1");
+      assertInternalNode(internalK1_I1J1_F1G1H1_D1E1_ZA1B1C1,
+            idK1_I1J1_F1G1H1_D1E1_ZA1B1C1, elementsK1_I1J1_F1G1H1_D1E1_ZA1B1C1,
+            1, 16);
+      assertChildLeafNode(internalK1_I1J1_F1G1H1_D1E1_ZA1B1C1, idK1, elementsK1,
+            "K1");
+      assertInternalNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1,
+            idI1J1_F1G1H1_D1E1_ZA1B1C1, elementsI1J1_F1G1H1_D1E1_ZA1B1C1,
+            14, 15, 2, 9);
+      assertChildLeafNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1, idI1, elementsI1,
+      "I1");
+      assertChildLeafNode(internalI1J1_F1G1H1_D1E1_ZA1B1C1, idJ1, elementsJ1,
+            "J1");
+      assertInternalNode(internalF1G1H1_D1E1_ZA1B1C1, idF1G1H1_D1E1_ZA1B1C1,
+            elementsF1G1H1_D1E1_ZA1B1C1, 7, 7, 3, 10);
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idF1, elementsF1, "F1");
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idG1, elementsG1, "G1");
+      assertChildLeafNode(internalF1G1H1_D1E1_ZA1B1C1, idH1, elementsH1, "H1");
+      internalD1E1_ZA1B1C1 = getChildNode(internalF1G1H1_D1E1_ZA1B1C1,
+            idD1E1_ZA1B1C1);
+      assertInternalNode(internalD1E1_ZA1B1C1, idD1E1_ZA1B1C1,
+            elementsD1E1_ZA1B1C1, 3, 3, 2, 6);
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idD1, elementsD1, "D1");
+      assertChildLeafNode(internalD1E1_ZA1B1C1, idE1, elementsE1, "E1");
+      assertInternalNode(internalZA1B1C1, idZA1B1C1, elementsZA1B1C1, 2, 2);
+      assertChildLeafNode(internalZA1B1C1, idZ, elementsZ, "Z");
+      assertChildLeafNode(internalZA1B1C1, idA1, elementsA1, "A1");
+      assertChildLeafNode(internalZA1B1C1, idB1, elementsB1, "B1");
+      assertChildLeafNode(internalZA1B1C1, idC1, elementsC1, "C1");
+      assertInternalNode(internalXY, idXY, elementsXY, 1, 15);
+      assertChildLeafNode(internalXY, idX, elementsX, "X");
+      assertChildLeafNode(internalXY, idY, elementsY, "Y");
+      internalVW_TU_RS_PQ_MNO_JKL_CDEFG = getChildNode(internalFromC,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG);
+      assertInternalNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG,
+            idVW_TU_RS_PQ_MNO_JKL_CDEFG, elementsVW_TU_RS_PQ_MNO_JKL_CDEFG, 12,
+            18, 4, 8);
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idV, elementsV,
+      "V");
+      assertChildLeafNode(internalVW_TU_RS_PQ_MNO_JKL_CDEFG, idW, elementsW,
+            "W");
+      assertInternalNode(internalTU_RS_PQ_MNO_JKL_CDEFG, '1',
+            elementsTU_RS_PQ_MNO_JKL_CDEFG, 9, 9, 3, 3);
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idT, elementsT, "T");
+      assertChildLeafNode(internalTU_RS_PQ_MNO_JKL_CDEFG, idU, elementsU, "U");
+      assertInternalNode(internalRS_PQ_MNO_JKL_CDEFG, idRS_PQ_MNO_JKL_CDEDFG,
+            elementsRS_PQ_MNO_JKL_CDEFG,9, 9);
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idR, elementsR, "R");
+      assertChildLeafNode(internalRS_PQ_MNO_JKL_CDEFG, idS, elementsS, "S");
+      assertInternalNode(internalPQ_MNO_JKL_CDEFG, idPQ_MNO_JKL_CDEFG,
+            elementsPQ_MNO_JKL_CDEFG, 7, 7);    
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idP, elementsP, "P");
+      assertChildLeafNode(internalPQ_MNO_JKL_CDEFG, idQ, elementsQ, "Q");
+      assertInternalNode(internalMNO_JKL_CDEFG, idMNO_JKL_CDEFG,
+            elementsMNO_JKL_CDEFG, 5, 5);
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idM, elementsM, "M");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idN, elementsN, "N");
+      assertChildLeafNode(internalMNO_JKL_CDEFG, idO, elementsO, "O");
+      assertInternalNode(internalJKL_CDEFG, idJKL_CDEFG, elementsJKL_CDEFG, 3,
+            3, 2, 2);
+      assertChildLeafNode(internalJKL_CDEFG, idJ, elementsJ, "J");
+      assertChildLeafNode(internalJKL_CDEFG, idK, elementsK, "K");
+      assertChildLeafNode(internalJKL_CDEFG, idL, elementsL, "L");
+      assertInternalNode(internalCDEFG, idCDEFG, elementsCDEFG, 2, 2);
+      assertChildLeafNode(internalCDEFG, idC, elementsC, "C");
+      assertChildLeafNode(internalCDEFG, idD, elementsD, "D");
+      assertChildLeafNode(internalCDEFG, idE, elementsE, "E");
+      assertChildLeafNode(internalCDEFG, idF, elementsF, "F");
+      assertChildLeafNode(internalCDEFG, idG, elementsG, "G");
+      assertChildLeafNode(internalCDEFG, idH, elementsH, "H");
+   }
+   
+   /**
+    * Asserts the current tree state as being the expected <code>state</code>.
+    * 
+    * @param state the expected tree state
+    */
+   private void assertTreeState(Class state) throws Exception
+   {
+      assertSame(state, treeStateField.get(tree).getClass());
+   }
+
+   /**
+    * Retrieves the root child node identified by <code>first</code>, and
+    * asserts this child node as a leaf and its data.
+    * 
+    * @param first     the expected first character of the child node key part
+    * @param elements  the expected elements contained in the child node key
+    *                  part
+    * @param value     the expected value contained in the child node
+    */
+   private void assertRootLeafNode(char first, String[] elements,
+         Object value) throws Exception
+   {
+      this.assertLeafNode(getRoot(), first, elements, value);
+   }
+
+   /**
+    * Retrieves the child node of <code>superNode</code>, identified by <code>
+    * first</code>, and asserts this child node as a leaf and its data.
+    * 
+    * @param superNode the node whose child is the leaf node to be asserted
+    * @param first     the expected first character of the child node key part
+    * @param elements  the expected elements contained in the child node key
+    *                  part
+    * @param value     the expected value contained in the child node
+    */
+   private void assertChildLeafNode(Node superNode, char first,
+         String[] elements, Object value) throws Exception
+   {
+      assertLeafNode(getChildNode(superNode, first), first, elements, value);
+   }
+   
+   /**
+    * Asserts the leaf node <code>node</code> data.
+    * 
+    * @param node     the leaf node whose data will be asserted
+    * @param first    the expected first character of the <code>node</code> key
+    *                 part
+    * @param elements the expected elements contained in the <code>node</code>
+    *                 key part
+    * @param value    the expected value contained in <code>node</code>
+    */
+   private void assertLeafNode(Node node, char first, String[] elements,
+         Object value) throws Exception
+   {
+      assertTrue("Node isn't a leaf", node instanceof LeafNode);
+      Util.assertKeyPart(node.keyPart, first, elements);
+      assertSame(value, valueField.get(node));
+   }
+   
+   /**
+    * Asserts the internal node <code>node</code> data.
+    * 
+    * @param node               the internal node whose data will be asserted   
+    * @param first              the expected first character of the <code>node
+    *                           </code> key part
+    * @param elements           the expected elements contained in the <code>
+    *                           node</code> key part
+    * @param ppMinLength        the expected post-prefix minimum length of the
+    *                           <code>node</code> key part
+    * @param ppMaxLength        the expected post-prefix maximum length of the
+    *                           <code>node</code> key part
+    */
+   private void assertInternalNode(Node node, char first, String[] elements,
+         int ppMinLength, int ppMaxLength)
+   {
+      assertTrue(node instanceof InternalNode);
+      Util.assertKeyPart(node.keyPart, first, elements, ppMinLength,
+            ppMaxLength);  
+   }
+   
+   /**
+    * Asserts the internal node <code>node</code> data.
+    * 
+    * @param node               the internal node whose data will be asserted   
+    * @param first              the expected first character of the <code>node
+    *                           </code> key part
+    * @param elements           the expected elements contained in the <code>
+    *                           node</code> key part
+    * @param ppMinLength        the expected post-prefix minimum length of the
+    *                           <code>node</code> key part
+    * @param ppMaxLength        the expected post-prefix maximum length of the
+    *                           <code>node</code> key part
+    * @param elementPPMinLength the expected post-prefix minimum length of the
+    *                           <code>node</code> key part last element
+    * @param elementPPMaxLength the expected post-prefix maximum length of the
+    *                           <code>node</code> key part last element
+    */
+   private void assertInternalNode(Node node, char first, String[] elements,
+         int ppMinLength, int ppMaxLength, int elementPPMinLength,
+         int elementPPMaxLength)
+   {
+      assertTrue("Node isn't a internal node.", node instanceof InternalNode);
+      Util.assertKeyPart(node.keyPart, first, elements, ppMinLength,
+            ppMaxLength, elementPPMinLength, elementPPMaxLength);  
+   }
+   
+   /**
+    * Returns the root of the tree.
+    * 
+    * @return the root of the tree.
+    */
+   private Node getRoot() throws Exception
+   {
+      return (Node) rootField.get(tree);
+   }
+   
+   /**
+    * Returns the child node of <code>node</code>, identified by <code>
+    * childId</code>.
+    * 
+    * @param node    the internal node whose child is to be retrieved
+    * @param childId the identifier of the queried child
+    * @return  the child node identified by <code>childId</code>
+    */
+   private Node getChildNode(Node node, char childId) throws Exception
+   {
+      SlotCollection children = (SlotCollection) childrenField.get(node);
+      children.loadSlot(childId);
+      assertFalse("Slot for '" + childId + "' is empty.",
+            children.isSlotEmpty());
+      return (Node) children.getSlotContent();
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/TreeSearchTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/TreeSearchTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/TreeSearchTest.java	2008-01-03 18:54:24 UTC (rev 68603)
@@ -0,0 +1,1866 @@
+/*
+ * 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.Tree;
+
+import junit.framework.TestCase;
+
+/**
+ * Test of the {@link Tree#search} method.
+ * 
+ * @author Flavia Rainone
+ */
+public class TreeSearchTest extends TestCase
+{
+   Tree tree;
+   
+   public void setUp()
+   {
+      tree = new Tree();
+      tree.insert("com.company.package.Class", "A1");
+      tree.insert("com.company.package.Class1", "B1");
+      tree.insert("com.company.package.Class2", "C1");
+      tree.insert("com.company.package.Class3", "D1");
+      tree.insert("com.company.package.Interface", "E1");
+      tree.insert("com.company.package.Interface1", "F1");
+      tree.insert("com.company.package.Interface2", "G1");
+      tree.insert("com.company.package.impl.InterfaceImpl", "H1");
+      tree.insert("com.company.package.impl.Interface1Impl", "I1");
+      tree.insert("com.company.package.impl.Interface2Impl", "J1");
+      tree.insert("com.company.otherpackage.SomeClass", "K1");
+      tree.insert("com.company.otherpackage.AnotherClass", "L1");
+      tree.insert("com.company.internal.Factory", "M1");
+      tree.insert("com.company.internal.StaticFactory", "N1");
+      tree.insert("com.company.internal.Observer", "O1");
+      tree.insert("com.comp.any.package.Class11", "P1");
+      tree.insert("com.comp.any.package.Class12", "Q1");
+      tree.insert("com.comp.any.package.Class13", "R1");
+      tree.insert("com.comp.any.package.Class20", "S1");
+      tree.insert("com.comp.any.package.Class22", "T1");
+      tree.insert("com.comp.any.package.Class30", "U1");
+      tree.insert("com.comp.any.package.Interface", "V1");
+      tree.insert("com.comp.any.package.Interface1", "W1");
+      tree.insert("com.comp.any.package.Interface2", "X1");
+      tree.insert("com.comp.any.package.impl.InterfaceImpl", "Y1");
+      tree.insert("com.comp.any.package.impl.Interface1Impl", "Z1");
+      tree.insert("com.comp.any.package.impl.Interface2Impl", "A2");
+      tree.insert("com.comp.any.otherpackage.SomeClass", "B2");
+      tree.insert("com.comp.any.otherpackage.AnotherClass", "C2");
+      tree.insert("com.comp.any.internal.Factory", "D2");
+      tree.insert("com.comp.any.internal.StaticFactory", "E2");
+      tree.insert("com.comp.any.internal.Observer", "F2");
+      tree.insert("com.comp.any.internal.package.Observer", "G2");
+      tree.insert("com.comp.any.internal.package.Class", "H2");
+      tree.insert("com.comp.any.internal.package.Interface", "I2");
+      tree.insert("com.comp.any.internal.package.Interfaces", "J2");
+      tree.insert("com.comp.any.internal.package.Caller", "K2");
+      tree.insert("com.comp.any.internal.package.Client", "L2");
+      tree.insert("com.comp.any.internal.package.OtherClass", "M2");
+      tree.insert("net.otherCompany.package.Class", "N2");
+      tree.insert("net.otherCompany.package.Observer", "O2");
+      tree.insert("net.otherCompany.package.Factory", "P2");
+      tree.insert("net.otherCompany.package.Interface", "Q2");
+      tree.insert("net.otherCompany.package.InterfaceImpl", "R2");
+      tree.insert("net.otherCompany.package.Observable", "S2");
+      tree.insert("net.otherCompany.package.package1.Class", "T2");
+      tree.insert("net.otherCompany.package.package1.Observer", "U2");
+      tree.insert("net.otherCompany.package.package1.Factory", "V2");
+      tree.insert("net.otherCompany.package.package1.Interface", "W2");
+      tree.insert("net.otherCompany.package.package1.InterfaceImpl", "X2");
+      tree.insert("net.otherCompany.package.package1.Observable", "Y2");
+      tree.insert("net.otherCompany.package1.Class", "Z2");
+      tree.insert("net.otherCompany.package1.Observer", "A3");
+      tree.insert("net.otherCompany.package1.Factory", "B3");
+      tree.insert("net.otherCompany.package1.Interface", "C3");
+      tree.insert("net.otherCompany.package1.InterfaceImpl", "D3");
+      tree.insert("net.otherCompany.package1.Observable", "E3");
+      tree.insert("net.otherCompany.package.package2.Class", "F3");
+      tree.insert("net.otherCompany.package.package2.Observer", "G3");
+      tree.insert("net.otherCompany.package.package2.Factory", "H3");
+      tree.insert("net.otherCompany.package.package2.Interface", "I3");
+      tree.insert("net.otherCompany.package.package2.InterfaceImpl", "J3");
+      tree.insert("net.otherCompany.package.package2.Observable", "K3");
+      tree.insert("net.otherCompany.package2.Class", "L3");
+      tree.insert("net.otherCompany.package2.Observer", "M3");
+      tree.insert("net.otherCompany.package2.Factory", "N3");
+      tree.insert("net.otherCompany.package2.Interface", "O3");
+      tree.insert("net.otherCompany.package2.InterfaceImpl", "P3");
+      tree.insert("net.otherCompany.package2.Observable", "Q3");
+      tree.insert("net.otherCompany.package3.Class", "R3");
+      tree.insert("net.otherCompany.package3.Observer", "S3");
+      tree.insert("net.otherCompany.package3.Factory", "T3");
+      tree.insert("net.otherCompany.package", "U3");
+      tree.insert("net.otherCompany", "V3");
+      tree.insert("net.yourCompany1", "W3");
+      tree.insert("net.yourCompany12", "X3");
+      tree.insert("net.yourCompany12.Class", "Y3");
+      tree.insert("net.yourCompany11.MyClass", "Z3");
+      tree.insert("net.yourCompany11.MyClass.MyInternalClass", "A4");
+      tree.insert("net.yourCompany11.LastClass", "B4");
+      tree.insert("netonekeyverylongwithonlyoneelement", "C4");
+      tree.insert("netonekekeywithsamenumberofelementa", "D4");
+      tree.insert("netonekekeywithsamenumberofelements", "E4");
+      tree.insert("netonemorekeywithsamenumberofelemes", "F4");
+      tree.insert("netonemoitisnotenoughthenoofkeysyet", "G4");
+      tree.insert("1231231321231323333441414141415", "H4");
+      tree.insert("12312313212311312346717118134134", "I4");
+      tree.insert("17717171717171311312467111919191", "J4");
+      tree.insert("com.net.com.net.com.net.com.netty", "K4");
+      tree.insert("net.com.net.com.net.com.net.communication", "L4");
+      tree.insert("com.pack.com.pack.com.thiscom.pack.net.Client", "M4");
+      tree.insert("com.pack.com.pack.com.thiscom.pack.net.Class.com.pack.net." +
+            "Client", "N4");
+      tree.insert("net.com.packcompackpaaaaaaaaaack.net.com.pack.net.Client",
+            "O4");
+      tree.insert("com.pack.com.pack.com.thiscom.pack.net.ClientAbstract",
+            "P4");
+      tree.insert("com.pack.com.pack.com.thiscom.pack.net.AbstractClient",
+            "Q4");
+      tree.insert("com.abc.abc.abd.abc.abc.abc.ababaaaaaaaaa", "R4");
+      tree.insert("com.abc.abc.abd.abd.abc.abc.ababaaaaaaaaa", "S4");
+      tree.insert("com.abc.abc.abc.abd.abc.abc.ababaaaaaaaaa", "T4");
+      tree.insert("com.abc.abc.abd.mabc.abc.abc.ababaaaaaaaaa", "U4");
+      tree.insert("net.abc.abc.abd.abc.abc.abc.abab", "V4");
+      tree.insert("net.mmm.abc.abd.abc.abc.abc.abdd.abc.abc.ababab", "W4");
+      tree.insert("net.mmm.abc.abd.abc.abc.abc.abd.abc.abc.ababab", "X4");
+   }
+
+   public void testWildcard()
+   {
+      Collection result = tree.search("*");
+      assertEquals(102, result.size());
+      assertContent(result, 'A', 1, 'X', 4);
+   }
+
+   public void testClass()
+   {
+      Collection result = tree.search("*Class*");
+      assertEquals(27, result.size());
+      assertContent(result, 'A', 1, 'D', 1);
+      assertContent(result, 'K', 1, 'L', 1);
+      assertContent(result, 'P', 1, 'U', 1);
+      assertContent(result, 'B', 2, 'C', 2);
+      assertContent(result, new String[] {"H2", "T2", "Z2", "F3", "L3", "R3",
+            "N4"});
+      assertContent(result, 'M', 2, 'N', 2);
+      assertContent(result, 'Y', 3, 'B', 4);
+   }
+
+   public void testComClass()
+   {
+      Collection result = tree.search("com*Class*");
+      assertEquals(17, result.size());
+      assertContent(result, 'A', 1, 'D', 1);
+      assertContent(result, 'K', 1, 'L', 1);
+      assertContent(result, 'P', 1, 'U', 1);
+      assertContent(result, 'B', 2, 'C', 2);
+      assertContent(result, new String[] {"H2", "M2", "N4"});
+   }
+
+   public void testNetClass()
+   {
+      Collection result = tree.search("net*Class*");
+      assertEquals(10, result.size());
+      assertContent(result, new String[] {"N2", "T2", "Z2", "F3", "L3", "R3"});
+      assertContent(result, 'Y', 3, 'B', 4);
+   }
+   
+   public void testClassClass_1()
+   {
+      Collection result = tree.search("*Class*Class*");
+      assertEquals(1, result.size());
+      assertContent(result, "A4");
+   }
+   
+   public void testClassClass_2()
+   {
+      Collection result = tree.search("*Class*Class");
+      assertEquals(1, result.size());
+      assertContent(result, "A4");
+   }
+   
+   public void testInterface_1()
+   {
+      Collection result = tree.search("*Interface*");
+      assertEquals(24, result.size());
+      assertContent(result, 'E', 1, 'J', 1);
+      assertContent(result, 'V', 1, 'A', 2);
+      assertContent(result, 'I', 2, 'J', 2);
+      assertContent(result, 'Q', 2, 'R', 2);
+      assertContent(result, 'W', 2, 'X', 2);
+      assertContent(result, 'C', 3, 'D', 3);
+      assertContent(result, 'I', 3, 'J', 3);
+      assertContent(result, 'O', 3, 'P', 3);
+   }
+
+   public void testInterface_2()
+   {
+      Collection result = tree.search("*Interface");
+      assertEquals(8, result.size());
+      assertContent(result, new String[] {"E1", "V1", "I2", "Q2", "W2", "C3",
+            "I3", "O3"});
+   }
+   
+   public void testComInterface_1()
+   {
+      Collection result = tree.search("com*Interface*");
+      assertEquals(14, result.size());
+      assertContent(result, 'E', 1, 'J', 1);
+      assertContent(result, 'V', 1, 'A', 2);
+      assertContent(result, 'I', 2, 'J', 2);
+   }
+   
+   public void testComInterface_2()
+   {
+      Collection result = tree.search("com*Interface");
+      assertEquals(3, result.size());
+      assertContent(result, new String[] {"E1", "V1", "I2"});
+   }
+
+   public void testNetInterface_1()
+   {
+      Collection result = tree.search("net*Interface*");
+      assertEquals(10, result.size());
+      assertContent(result, 'Q', 2, 'R', 2);
+      assertContent(result, 'W', 2, 'X', 2);
+      assertContent(result, 'C', 3, 'D', 3);
+      assertContent(result, 'I', 3, 'J', 3);
+      assertContent(result, 'O', 3, 'P', 3);
+   }
+
+   public void testNetInterface_2()
+   {
+      Collection result = tree.search("net*Interface");
+      assertEquals(5, result.size());
+      assertContent(result, new String[] {"Q2", "W2", "C3", "I3", "O3"});
+   }
+
+   public void testFactory()
+   {
+      Collection result = tree.search("*Factory");
+      assertEquals(10, result.size());
+      assertContent(result, 'M', 1, 'N', 1);
+      assertContent(result, 'D', 2, 'E', 2);
+      assertContent(result, new String[] {"P2", "V2", "B3", "H3", "N3", "T3"});
+   }
+
+   public void testComFactory()
+   {
+      Collection result = tree.search("com*Factory");
+      assertEquals(4, result.size());
+      assertContent(result, 'M', 1, 'N', 1);
+      assertContent(result, 'D', 2, 'E', 2);
+   }
+
+   public void testNetFactory()
+   {
+      Collection result = tree.search("net*Factory");
+      assertEquals(6, result.size());
+      assertContent(result, new String[] {"P2", "V2", "B3", "H3", "N3", "T3"});
+   }
+   
+   public void testOry()
+   {
+      Collection result = tree.search("*ory");
+      assertEquals(10, result.size());
+      assertContent(result, 'M', 1, 'N', 1);
+      assertContent(result, 'D', 2, 'E', 2);
+      assertContent(result, new String[] {"P2", "V2", "B3", "H3", "N3", "T3"});
+   }
+   
+   public void testOmpany()
+   {
+      Collection result = tree.search("*ompany*");
+      assertEquals(56, result.size());
+      assertContent(result, 'A', 1, 'O', 1);
+      assertContent(result, 'N', 2, 'B', 4);
+   }
+   
+   public void testCompany_1()
+   {
+      Collection result = tree.search("*company*");
+      assertEquals(15, result.size());
+      assertContent(result, 'A', 1, 'O', 1);
+   }
+   
+   public void testCompany_2()
+   {
+      Collection result = tree.search("*Company*");
+      assertEquals(41, result.size());
+      assertContent(result, 'N', 2, 'B', 4);
+   }
+   
+   public void testCompany_3()
+   {
+      Collection result = tree.search("*comp*any*");
+      assertEquals(39, result.size());
+      assertContent(result, 'A', 1, 'M', 2);
+   }
+   public void testOnlyOneElement()
+   {
+      Collection result = tree.search("*onlyoneelement");
+      assertEquals(1, result.size());
+      assertContent(result, "C4");
+   }
+
+   public void testNOnlyOneElement()
+   {
+      Collection result = tree.search("n*onlyoneelement");
+      assertEquals(1, result.size());
+      assertContent(result, "C4");
+   }
+
+   public void testInternal_1()
+   {
+      Collection result = tree.search("*internal*");
+      assertEquals(13, result.size());
+      assertContent(result, 'M', 1, 'O', 1);
+      assertContent(result, 'D', 2, 'M', 2);
+   }
+
+   public void testInternal_2()
+   {
+      Collection result = tree.search("*int*ernal*");
+      assertEquals(13, result.size());
+      assertContent(result, 'M', 1, 'O', 1);
+      assertContent(result, 'D', 2, 'M', 2);
+   }
+   
+   public void testPackageInternal()
+   {
+      Collection result = tree.search("*.package*internal*");
+      assertEquals(0, result.size());
+   }
+   
+   public void testPackagePackage()
+   {
+      Collection result = tree.search("*package*package*");
+      assertEquals(12, result.size());
+      assertContent(result, 'T', 2, 'Y', 2);
+      assertContent(result, 'F', 3, 'K', 3);
+   }
+
+   public void testCompInternalPackage()
+   {
+      Collection result = tree.search("*comp*internal*package*");
+      assertEquals(7, result.size());
+      assertContent(result, 'G', 2, 'M', 2);
+   }
+
+   public void testComm_1()
+   {
+      Collection result = tree.search("comm*");
+      assertEquals(0, result.size());
+   }
+   
+   public void testComm_2()
+   {
+      Collection result = tree.search("comm.*");
+      assertEquals(0, result.size());
+   }
+
+   public void testComm_3()
+   {
+      Collection result = tree.search("*comm*");
+      assertEquals(1, result.size());
+      assertContent(result, "L4");
+   }
+
+   public void testComm_4()
+   {
+      Collection result = tree.search("*comm.*");
+      assertEquals(0, result.size());
+   }
+
+   public void testComm_5()
+   {
+      Collection result = tree.search("*.comm*");
+      assertEquals(1, result.size());
+      assertContent(result, "L4");
+   }
+   
+   public void testAnys_1()
+   {
+      Collection result = tree.search("*any*s");
+      assertEquals(18, result.size());
+      assertContent(result, new String[] {"A1", "H2", "J2", "T2", "Z2", "F3",
+            "L3", "R3"});
+      assertContent(result, 'K', 1, 'L', 1);
+      assertContent(result, 'B', 2, 'C', 2);
+      assertContent(result, 'M', 2, 'N', 2);
+      assertContent(result, 'Y', 3, 'B', 4);
+   }
+   
+   public void testAnys_2()
+   {
+      Collection result = tree.search("*.any.*s");
+      assertEquals(5, result.size());
+      assertContent(result, new String[] {"H2", "J2", "M2"});
+      assertContent(result, 'B', 2, 'C', 2);
+   }
+   
+   public void testS1()
+   {
+      Collection result = tree.search("*s");
+      assertEquals(20, result.size());
+      assertContent(result, new String[] {"A1", "H2", "J2", "T2", "Z2", "F3",
+            "L3", "R3"});
+      assertContent(result, 'K', 1, 'L', 1);
+      assertContent(result, 'B', 2, 'C', 2);
+      assertContent(result, 'M', 2, 'N', 2);
+      assertContent(result, 'Y', 3, 'B', 4);
+      assertContent(result, 'E', 4, 'F', 4);
+
+   }
+   
+   public void testS2()
+   {
+      Collection result = tree.search("*s*");
+      assertEquals(49, result.size());
+      assertContent(result, 'A', 1, 'D', 1);
+      assertContent(result, 'K', 1, 'L', 1);
+      assertContent(result, 'O', 1, 'U', 1);
+      assertContent(result, 'B', 2, 'C', 2);
+      assertContent(result, 'F', 2, 'H', 2);
+      assertContent(result, "J2");
+      assertContent(result, 'M', 2, 'O', 2);
+      assertContent(result, 'S', 2, 'U', 2);
+      assertContent(result, 'Y', 2, 'A', 3);
+      assertContent(result, 'E', 3, 'G', 3);
+      assertContent(result, 'K', 3, 'M', 3);
+      assertContent(result, 'Q', 3, 'S', 3);
+      assertContent(result, 'Y', 3, 'B', 4);
+      assertContent(result, 'D', 4, 'G', 4);
+      assertContent(result, 'M', 4, 'N', 4);
+      assertContent(result, 'P', 4, 'Q', 4);
+   }
+   
+   public void testR_1()
+   {
+      Collection result = tree.search("*r*");
+      assertEquals(76, result.size());
+      assertContent(result, 'E', 1, 'O', 1);
+      assertContent(result, 'V', 1, 'F', 4);
+      assertContent(result, 'P', 4, 'Q', 4);
+   }
+
+   public void testR_2()
+   {
+      Collection result = tree.search("*r");
+      assertEquals(10, result.size());
+      assertContent(result, new String[] {"O1", "K2", "O2", "U2", "A3", "G3",
+            "M3", "S3"});
+      assertContent(result, 'F', 2, 'G', 2);
+   }
+   
+   public void testR_3()
+   {
+      Collection result = tree.search("r*");
+      assertEquals(0, result.size());
+   }
+   
+   public void testCom_1()
+   {
+      Collection result = tree.search("com*");
+      assertEquals(48, result.size());
+      assertContent(result, 'A', 1, 'M', 2);
+      assertContent(result, "K4");
+      assertContent(result, 'M', 4, 'N', 4);
+      assertContent(result, 'P', 4, 'U', 4);
+   }
+   
+   public void testCom_2()
+   {
+      Collection result = tree.search("com.*");
+      assertEquals(48, result.size());
+      assertContent(result, 'A', 1, 'M', 2);
+      assertContent(result, "K4");
+      assertContent(result, 'M', 4, 'N', 4);
+      assertContent(result, 'P', 4, 'U', 4);
+   }
+   
+   public void testCom1_1()
+   {
+      Collection result = tree.search("com*1");
+      assertEquals(4, result.size());
+      assertContent(result, new String[]{"B1", "F1", "P1", "W1"});
+   }
+   
+   public void testCom1_2()
+   {
+      Collection result = tree.search("com*1*");
+      assertEquals(8, result.size());
+      assertContent(result, new String[]{"B1", "F1", "I1", "P1", "Q1", "R1",
+            "W1", "Z1"});
+   }
+
+   public void testCom2_1()
+   {
+      Collection result = tree.search("com*2");
+      assertEquals(5, result.size());
+      assertContent(result, new String[]{"C1", "G1", "T1", "Q1", "X1"});
+   }
+   
+   public void testCom2_2()
+   {
+      Collection result = tree.search("com*2*");
+      assertEquals(8, result.size());
+      assertContent(result, new String[]{"C1", "G1", "J1", "S1", "T1", "Q1",
+            "X1", "A2"});
+   }
+   
+   public void testCom3_1()
+   {
+      Collection result = tree.search("com*3");
+      assertEquals(2, result.size());
+      assertContent(result, new String[]{"D1", "R1"});
+   }
+   
+   public void testCom3_2()
+   {
+      Collection result = tree.search("com*3*");
+      assertEquals(3, result.size());
+      assertContent(result, new String[]{"D1", "R1", "U1"});
+   }
+
+   public void testComs()
+   {
+      Collection result = tree.search("com.*s");
+      assertEquals(8, result.size());
+      assertContent(result, new String[] {"A1", "H2", "J2", "M2"});
+      assertContent(result, 'K', 1, 'L', 1);
+      assertContent(result, 'B', 2, 'C', 2);
+   }
+   
+   public void testComPackage_1()
+   {
+      Collection result = tree.search("com.*package*");
+      assertEquals(33, result.size());
+      assertContent(result, 'A', 1, 'L', 1);
+      assertContent(result, 'P', 1, 'C', 2);
+      assertContent(result, 'G', 2, 'M', 2);
+   }
+   
+   public void testComPackage_2()
+   {
+      Collection result = tree.search("com.*.package.*");
+      assertEquals(29, result.size());
+      assertContent(result, 'A', 1, 'J', 1);
+      assertContent(result, 'P', 1, 'A', 2);
+      assertContent(result, 'G', 2, 'M', 2);
+   }
+   
+   public void testComPackageClass_1()
+   {
+      Collection result = tree.search("com.*.package.Class*");
+      assertEquals(11, result.size());
+      assertContent(result, 'A', 1, 'D', 1);
+      assertContent(result, 'P', 1, 'U', 1);
+      assertContent(result, "H2");
+   }
+   
+   public void testComPackageClass_2()
+   {
+      Collection result = tree.search("com.*.package*Class*");
+      assertEquals(12, result.size());
+      assertContent(result, 'A', 1, 'D', 1);
+      assertContent(result, 'P', 1, 'U', 1);
+      assertContent(result, new String[] {"H2", "M2"});
+   }
+
+   public void testComPackageClass_3()
+   {
+      Collection result = tree.search("com.*package.*Class*");
+      assertEquals(16, result.size());
+      assertContent(result, 'A', 1, 'D', 1);
+      assertContent(result, 'K', 1, 'L', 1);
+      assertContent(result, 'P', 1, 'U', 1);
+      assertContent(result, 'B', 2, 'C', 2);
+      assertContent(result, new String[] {"H2", "M2"});
+   }
+
+   public void testComPackageClass_4()
+   {
+      Collection result = tree.search("com.*.package.*.Class*");
+      assertEquals(0, result.size());
+   }
+   
+   public void testComInternal_1()
+   {
+      Collection result = tree.search("com*internal*");
+      assertEquals(13, result.size());
+      assertContent(result, 'M', 1, 'O', 1);
+      assertContent(result, 'D', 2, 'M', 2);
+   }
+
+   public void testComInternal_2()
+   {
+      Collection result = tree.search("com.*.inte*rnal.*.*");
+      assertEquals(7, result.size());
+      assertContent(result, 'G', 2, 'M', 2);
+   }
+
+   public void testComIntnal()
+   {
+      Collection result = tree.search("com.*.int*nal.*.*");
+      assertEquals(7, result.size());
+      assertContent(result, 'G', 2, 'M', 2);
+   }
+   
+   public void testComInternalObserver()
+   {
+      Collection result = tree.search("com*internal*Observer");
+      assertEquals(3, result.size());
+      assertContent(result, "O1");
+      assertContent(result, 'F', 2, 'G', 2);
+   }
+
+   public void testComInternalObs()
+   {
+      Collection result = tree.search("com*internal*Obs*");
+      assertEquals(3, result.size());
+      assertContent(result, "O1");
+      assertContent(result, 'F', 2, 'G', 2);
+   }
+
+   public void testComObserver_1()
+   {
+      Collection result = tree.search("com.*Observer");
+      assertEquals(3, result.size());
+      assertContent(result, "O1");
+      assertContent(result, 'F', 2, 'G', 2);
+   }
+
+   public void testComObserver_2()
+   {
+      Collection result = tree.search("com.*Observer*");
+      assertEquals(3, result.size());
+      assertContent(result, "O1");
+      assertContent(result, 'F', 2, 'G', 2);
+   }
+
+   public void testComObserver_3()
+   {
+      Collection result = tree.search("com.*.Observer*");
+      assertEquals(3, result.size());
+      assertContent(result, "O1");
+      assertContent(result, 'F', 2, 'G', 2);
+   }
+
+   public void testComAnyPackage()
+   {
+      Collection result = tree.search("com*any*package.*");
+      assertEquals(33, result.size());
+      assertContent(result, 'A', 1, 'L', 1);
+      assertContent(result, 'P', 1, 'C', 2);
+      assertContent(result, 'G', 2, 'M', 2);
+   }
+   
+   public void testComAnyAPackageClass()
+   {
+      Collection result = tree.search("com*any*a.package.*Class*");
+      assertEquals(0, result.size());
+   }
+      
+   public void testComAnyPackage1()
+   {
+      Collection result = tree.search("com*any*.package.*1");
+      assertEquals(4, result.size());
+      assertContent(result, new String[] {"B1", "F1", "P1", "W1"});
+   }
+   
+   public void testNet_1()
+   {
+      Collection result = tree.search("net*");
+      assertEquals(51, result.size());
+      assertContent(result, 'N', 2, 'G', 4);
+      assertContent(result, new String[] {"L4", "O4"});
+      assertContent(result, 'V', 4, 'X', 4);
+   }
+   
+   public void testNet_2()
+   {
+      Collection result = tree.search("net.*");
+      assertEquals(46, result.size());
+      assertContent(result, 'N', 2, 'B', 4);
+      assertContent(result, new String[] {"L4", "O4"});
+      assertContent(result, 'V', 4, 'X', 4);
+   }
+   
+   public void testNet1_1()
+   {
+      Collection result = tree.search("net*1");
+      assertEquals(1, result.size());
+      assertContent(result, "W3");
+   }
+   
+   public void testNet1_2()
+   {
+      Collection result = tree.search("net*1*");
+      assertEquals(18, result.size());
+      assertContent(result, 'T', 2, 'E', 3);
+      assertContent(result, 'W', 3, 'B', 4);
+   }
+
+   public void testNet2_1()
+   {
+      Collection result = tree.search("net*2");
+      assertEquals(1, result.size());
+      assertContent(result, "X3");
+   }
+   
+   public void testNet2_2()
+   {
+      Collection result = tree.search("net*2*");
+      assertEquals(14, result.size());
+      assertContent(result, 'F', 3, 'Q', 3);
+      assertContent(result, 'X', 3, 'Y', 3);
+   }
+   
+   public void testNet3_1()
+   {
+      Collection result = tree.search("net*3");
+      assertEquals(0, result.size());
+   }
+
+   public void testNet3_2()
+   {
+      Collection result = tree.search("net*3*");
+      assertEquals(3, result.size());
+      assertContent(result, 'R', 3, 'T', 3);
+   }
+
+   public void testNetY()
+   {
+      Collection result = tree.search("net.y*");
+      assertEquals(6, result.size());
+      assertContent(result, 'W', 3, 'B', 4);
+   }
+   
+   public void testNetO()
+   {
+      Collection result = tree.search("net.o*");
+      assertEquals(35, result.size());
+      assertContent(result, 'N', 2, 'V', 3);
+   }
+   
+   public void testNets()
+   {
+      Collection result = tree.search("net.*s");
+      assertEquals(10, result.size());
+      assertContent(result, new String[] {"N2", "T2", "Z2", "F3",
+            "L3", "R3"});
+      assertContent(result, 'Y', 3, 'B', 4);
+   }
+
+   public void testNetCompany_1()
+   {
+      Collection result = tree.search("net*Company*");
+      assertEquals(41, result.size());
+      assertContent(result, 'N', 2, 'B', 4);
+   }
+   
+   public void testNetCompany_2()
+   {
+      Collection result = tree.search("net*Company.*");
+      assertEquals(34, result.size());
+      assertContent(result, 'N', 2, 'U', 3);
+   }
+   
+   public void testComAnyImpl()
+   {
+      Collection result = tree.search("com*any*impl*");
+      assertEquals(6, result.size());
+      assertContent(result, 'K', 1, 'J', 1);
+      assertContent(result, 'Y', 1, 'A', 2);
+   }
+
+   public void testNetPackageClass_1()
+   {
+      Collection result = tree.search("net.*package*Class*");
+      assertEquals(6, result.size());
+      assertContent(result, new String[] {"N2", "T2", "Z2", "F3", "L3", "R3"});
+   }
+
+   public void testNetPackageClass_2()
+   {
+      Collection result = tree.search("net.*.package*Class*");
+      assertEquals(6, result.size());
+      assertContent(result, new String[] {"N2", "T2", "Z2", "F3", "L3", "R3"});
+   }
+
+   public void testNetPackageClass_3()
+   {
+      Collection result = tree.search("net.*.package.*Class*");
+      assertEquals(3, result.size());
+      assertContent(result, new String[] {"N2", "T2", "F3"});
+   }
+
+   public void testNetPackageClass_4()
+   {
+      Collection result = tree.search("net.*.package*Class");
+      assertEquals(6, result.size());
+      assertContent(result, new String[] {"N2", "T2", "Z2", "F3", "L3", "R3"});
+   }
+   
+   public void testNetInternal()
+   {
+      Collection result = tree.search("net*internal*");
+      assertEquals(0, result.size());
+   }
+   
+   public void testNetObserver_1()
+   {
+      Collection result = tree.search("net*Observer");
+      assertEquals(6, result.size());
+      assertContent(result, new String[] {"O2", "U2", "A3", "G3", "M3", "S3"});
+   }
+
+   public void testNetObserver_2()
+   {
+      Collection result = tree.search("net*Observer*");
+      assertEquals(6, result.size());
+      assertContent(result, new String[] {"O2", "U2", "A3", "G3", "M3", "S3"});
+   }
+   
+   public void testNetObservable()
+   {
+      Collection result = tree.search("net*Observable");
+      assertEquals(5, result.size());
+      assertContent(result, new String[] {"S2", "Y2", "E3", "K3", "Q3"});
+   }
+
+   public void testNetObs()
+   {
+      Collection result = tree.search("net*Obs*");
+      assertEquals(11, result.size());
+      assertContent(result, new String[] {"O2", "S2", "U2", "Y2", "A3", "E3",
+            "G3", "K3", "M3", "Q3", "S3"});
+   }
+
+   public void test1_1()
+   {
+      Collection result = tree.search("*1");
+      assertEquals(6, result.size());
+      assertContent(result, new String[] {"B1", "F1", "P1", "W1", "W3", "J4"});
+   }
+
+   public void test1_2()
+   {
+      Collection result = tree.search("*1*");
+      assertEquals(29, result.size());
+      assertContent(result, new String[] {"B1", "F1", "I1", "P1", "W1", "Z1"});
+      assertContent(result, 'Q', 1, 'R', 1);
+      assertContent(result, 'T', 2, 'E', 3);
+      assertContent(result, 'W', 3, 'B', 4);
+      assertContent(result, 'H', 4, 'J', 4);
+   }
+
+   public void test1_3()
+   {
+      Collection result = tree.search("1*");
+      assertEquals(3, result.size());
+      assertContent(result, 'H', 4, 'J', 4);
+   }
+
+   public void test1_4()
+   {
+      Collection result = tree.search("1");
+      assertEquals(0, result.size());
+   }
+   
+   public void test2_1()
+   {
+      Collection result = tree.search("*2");
+      assertEquals(6, result.size());
+      assertContent(result, new String[] {"C1", "G1", "Q1", "T1", "X1", "X3"});
+   }
+
+   public void test2_2()
+   {
+      Collection result = tree.search("*2*");
+      assertEquals(25, result.size());
+      assertContent(result, new String[] {"C1", "G1", "J1", "Q1", "X1", "A2"});
+      assertContent(result, 'S', 1, 'T', 1);
+      assertContent(result, 'F', 3, 'Q', 3);
+      assertContent(result, 'X', 3, 'Y', 3);
+      assertContent(result, 'H', 4, 'J', 4);
+   }
+
+   public void test2_3()
+   {
+      Collection result = tree.search("2*");
+      assertEquals(0, result.size());
+   }
+
+   public void test2_4()
+   {
+      Collection result = tree.search("2");
+      assertEquals(0, result.size());
+   }
+   
+   public void test3_1()
+   {
+      Collection result = tree.search("*3");
+      assertEquals(2, result.size());
+      assertContent(result, new String[] {"D1", "R1"});
+   }
+
+   public void test3_2()
+   {
+      Collection result = tree.search("*3*");
+      assertEquals(9, result.size());
+      assertContent(result, new String[] {"D1", "R1", "U1"});
+      assertContent(result, 'R', 3, 'T', 3);
+      assertContent(result, 'H', 4, 'J', 4);
+   }
+
+   public void test3_3()
+   {
+      Collection result = tree.search("3*");
+      assertEquals(0, result.size());
+   }
+
+   public void test3_4()
+   {
+      Collection result = tree.search("3");
+      assertEquals(0, result.size());
+   }
+
+   public void test1312()
+   {
+      Collection result = tree.search("*13*12*");
+      assertEquals(3, result.size());
+      assertContent(result, 'H', 4, 'J', 4);
+   }
+
+   public void test1712()
+   {
+      Collection result = tree.search("*17*12*");
+      assertEquals(1, result.size());
+      assertContent(result, "J4");
+   }
+
+   public void test123132123132333()
+   {
+      Collection result = tree.search("1*23132123132333*");
+      assertEquals(1, result.size());
+      assertContent(result, "H4");
+   }
+   
+   public void testComNetComNetCom_1()
+   {
+      Collection result = tree.search("*com.net.com.net.com*");
+      assertEquals(2, result.size());
+      assertContent(result, 'K', 4, 'L', 4);
+   }
+
+   public void testComNetComNetCom_2()
+   {
+      Collection result = tree.search("ne*com.net.com.net.com*");
+      assertEquals(1, result.size());
+      assertContent(result, "L4");
+   }
+   
+   public void testComNetComNetCom_3()
+   {
+      Collection result = tree.search("com*com.net.com.net.com*");
+      assertEquals(1, result.size());
+      assertContent(result, "K4");
+   }
+
+   
+   public void testComNetComNetCom_4()
+   {
+      Collection result = tree.search("com.net.com.net.com*");
+      assertEquals(1, result.size());
+      assertContent(result, "K4");
+   }
+
+   public void testComNetComNetCom_5()
+   {
+      Collection result = tree.search("*com.net.com.net.com");
+      assertEquals(0, result.size());
+   }
+   
+   public void testComNetComNetComNetCom_1()
+   {
+      Collection result = tree.search("*com.net.com.net.com.net.com*");
+      assertEquals(2, result.size());
+      assertContent(result, 'K', 4, 'L', 4);
+   }
+
+   public void testComNetComNetComNetCom_2()
+   {
+      Collection result = tree.search("c*com.net.com.net.com.net.com*");
+      assertEquals(0, result.size());
+   }
+
+   public void testComNetComNetComNetCom_3()
+   {
+      Collection result = tree.search("net*com.net.com.net.com.net.com*");
+      assertEquals(1, result.size());
+      assertContent(result, "L4");
+   }
+
+   public void testComNetComNetComNetCom_4()
+   {
+      Collection result = tree.search("com.net.com.net.com.net.com*");
+      assertEquals(1, result.size());
+      assertContent(result, "K4");
+   }
+
+   public void testComNetComNetComNetCom_5()
+   {
+      Collection result = tree.search("*com.net.com.net.com.net.com");
+      assertEquals(0, result.size());
+   }
+   
+   public void testNetComNetCNetComNet1()
+   {
+      Collection result = tree.search("*net.com.net.c*net.com.net*");
+      assertEquals(2, result.size());
+      assertContent(result, 'K', 4, 'L', 4);
+   }
+
+   public void testNetComNetCNetComNet2()
+   {
+      Collection result = tree.search("com*net.com.net.c*net.com.net*");
+      assertEquals(1, result.size());
+      assertContent(result, "K4");
+   }
+
+   public void testNetComNetCNetComNet3()
+   {
+      Collection result = tree.search("n*net.com.net.c*net.com.net*");
+      assertEquals(0, result.size());
+   }
+
+   public void testNetComNetCNetComNet4()
+   {
+      Collection result = tree.search("net.com.net.c*net.com.net*");
+      assertEquals(1, result.size());
+      assertContent(result, "L4");
+   }
+
+   public void testNetComNetCNetComNet5()
+   {
+      Collection result = tree.search("*net.com.net.c*net.com.net");
+      assertEquals(0, result.size());
+   }
+   
+   public void testComPackNetClient1()
+   {
+      Collection result = tree.search("*com.pack.net.Client*");
+      assertEquals(4, result.size());
+      assertContent(result, 'M', 4, 'P', 4);
+   }
+
+   public void testComPackNetClient2()
+   {
+      Collection result = tree.search("com.pack.net.Client*");
+      assertEquals(0, result.size());
+   }
+
+   public void testComPackNetClient3()
+   {
+      Collection result = tree.search("*com.pack.net.Client");
+      assertEquals(3, result.size());
+      assertContent(result, 'M', 4, 'O', 4);
+   }
+
+   public void testComComPackNetClient1()
+   {
+      Collection result = tree.search("com*com.pack.net.Client*");
+      assertEquals(3, result.size());
+      assertContent(result, 'M', 4, 'N', 4);
+      assertContent(result, "P4");
+   }
+
+   public void testComComPackNetClient2()
+   {
+      Collection result = tree.search("com*com.pack.net.Client");
+      assertEquals(2, result.size());
+      assertContent(result, 'M', 4, 'N', 4);
+   }
+
+   public void testNetComPackNetClient1()
+   {
+      Collection result = tree.search("net*com.pack.net.Client*");
+      assertEquals(1, result.size());
+      assertContent(result, "O4");
+   }
+   
+   public void testNetComPackNetClient2()
+   {
+      Collection result = tree.search("net*com.pack.net.Client");
+      assertEquals(1, result.size());
+      assertContent(result, "O4");
+   }
+
+   public void testComPackCom1()
+   {
+      Collection result = tree.search("*com.pack.com*");
+      assertEquals(4, result.size());
+      assertContent(result, 'M', 4, 'N', 4);
+      assertContent(result, 'P', 4, 'Q', 4);
+   }
+
+   public void testComPackCom2()
+   {
+      Collection result = tree.search("*.com.pack.com.*");
+      assertEquals(4, result.size());
+      assertContent(result, 'M', 4, 'N', 4);
+      assertContent(result, 'P', 4, 'Q', 4);
+   }
+
+   public void testAbcAbdAbc()
+   {
+      Collection result = tree.search("*abc.abd.abc*");
+      assertEquals(5, result.size());
+      assertContent(result, new String[]{"R4", "T4"});
+      assertContent(result, 'V', 4, 'X', 4);
+   }
+
+   public void testComAbcAbdAbc()
+   {
+      Collection result = tree.search("com*abc.abd.abc*");
+      assertEquals(2, result.size());
+      assertContent(result, new String[]{"R4", "T4"});
+   }
+
+   public void testComAbcAbdAbcB()
+   {
+      Collection result = tree.search("com*abc.abd.abc*b");
+      assertEquals(0, result.size());
+   }
+
+   public void testComAbcAbdAbcA()
+   {
+      Collection result = tree.search("com*abc.abd.abc*a");
+      assertEquals(2, result.size());
+      assertContent(result, new String[]{"R4", "T4"});
+   }
+
+   public void testNetAbcAbdAbc()
+   {
+      Collection result = tree.search("net*abc.abd.abc*");
+      assertEquals(3, result.size());
+      assertContent(result, 'V', 4, 'X', 4);
+   }
+
+   public void testNetAbcAbdAbcB()
+   {
+      Collection result = tree.search("net*abc.abd.abc*b");
+      assertEquals(3, result.size());
+      assertContent(result, 'V', 4, 'X', 4);
+   }
+   
+   public void testNetAbcAbdAbcA()
+   {
+      Collection result = tree.search("net*abc.abd.abc*a");
+      assertEquals(0, result.size());
+   }
+   
+   public void testAbcAbcAbdAbcAbcAbcAba_1()
+   {
+      Collection result = tree.search("*abc.abc.abd.abc.abc.abc.aba*");
+      assertEquals(2, result.size());
+      assertContent(result, new String[]{"R4", "V4"});
+   }
+   
+   public void testAbcAbcAbdAbcAbcAbcAba_2()
+   {
+      Collection result = tree.search("*abc.abc.ab*d.abc.abc.abc.aba*");
+      assertEquals(2, result.size());
+      assertContent(result, new String[]{"R4", "V4"});
+   }
+
+   public void testAbcAbcAbdAbcAbcAba_1()
+   {
+      Collection result = tree.search("*abc.abc.abd.abc.abc.aba*");
+      assertEquals(2, result.size());
+      assertContent(result, new String[] {"T4", "X4"});
+   }
+
+   public void testAbcAbcAbdAbcAbcAba_2()
+   {
+      Collection result = tree.search("*abc.abc.ab*d.abc.abc.aba*");
+      assertEquals(4, result.size());
+      assertContent(result, 'S', 4, 'T', 4);
+      assertContent(result, 'W', 4, 'X', 4);
+   }
+   
+   public void testComAbcAbcAbdAbcAbcAbcAba_1()
+   {
+      Collection result = tree.search("com*abc.abc.abd.abc.abc.abc.aba*");
+      assertEquals(1, result.size());
+      assertContent(result, "R4");
+   }
+   
+   public void testComAbcAbcAbdAbcAbcAbcAba2()
+   {
+      Collection result = tree.search("com*abc.abc.ab*d.abc.abc.abc.aba*");
+      assertEquals(1, result.size());
+      assertContent(result, "R4");
+   }
+   
+   public void testComAbcAbcAbdAbcAbcAbcAbaA1()
+   {
+      Collection result = tree.search("com*abc.abc.abd.abc.abc.abc.aba*a");
+      assertEquals(1, result.size());
+      assertContent(result, "R4");
+   }
+   
+   public void testComAbcAbcAbdAbcAbcAbcAbaA2()
+   {
+      Collection result = tree.search("com*abc.abc.ab*d.abc.abc.abc.aba*a");
+      assertEquals(1, result.size());
+      assertContent(result, "R4");
+   }
+   
+   public void testComAbcAbcAbdAbcAbcAbcAbaB1()
+   {
+      Collection result = tree.search("com*abc.abc.abd.abc.abc.abc.aba*b");
+      assertEquals(0, result.size());
+   }
+   
+   public void testComAbcAbcAbdAbcAbcAbcAbaB2()
+   {
+      Collection result = tree.search("com*abc.abc.ab*d.abc.abc.abc.aba*b");
+      assertEquals(0, result.size());
+   }
+   
+   public void testNetAbcAbcAbdAbcAbcAbcAba1()
+   {
+      Collection result = tree.search("net*abc.abc.abd.abc.abc.abc.aba*");
+      assertEquals(1, result.size());
+      assertContent(result, "V4");
+   }
+   
+   public void testNetAbcAbcAbdAbcAbcAbcAba2()
+   {
+      Collection result = tree.search("net*abc.abc.ab*d.abc.abc.abc.aba*");
+      assertEquals(1, result.size());
+      assertContent(result, "V4");
+   }
+   
+   public void testNetAbcAbcAbdAbcAbcAbcAbaA1()
+   {
+      Collection result = tree.search("net*abc.abc.abd.abc.abc.abc.aba*a");
+      assertEquals(0, result.size());
+   }
+   
+   public void testNetAbcAbcAbdAbcAbcAbcAbaA2()
+   {
+      Collection result = tree.search("net*abc.abc.ab*d.abc.abc.abc.aba*a");
+      assertEquals(0, result.size());
+   }
+   
+   public void testNetAbcAbcAbdAbcAbcAbcAbaB1()
+   {
+      Collection result = tree.search("net*abc.abc.abd.abc.abc.abc.aba*b");
+      assertEquals(1, result.size());
+      assertContent(result, "V4");
+   }
+   
+   public void testNetAbcAbcAbdAbcAbcAbcAbaB2()
+   {
+      Collection result = tree.search("net*abc.abc.ab*d.abc.abc.abc.aba*b");
+      assertEquals(1, result.size());
+      assertContent(result, "V4");
+   }
+
+   public void testAbab()
+   {
+      Collection result = tree.search("*abab*");
+      assertEquals(7, result.size());
+      assertContent(result, 'R', 4, 'X', 4);
+   }
+
+   public void testComAbab()
+   {
+      Collection result = tree.search("com*abab*");
+      assertEquals(4, result.size());
+      assertContent(result, 'R', 4, 'U', 4);
+   }
+
+   public void testComAbabA()
+   {
+      Collection result = tree.search("com*abab*a");
+      assertEquals(4, result.size());
+      assertContent(result, 'R', 4, 'U', 4);
+   }
+
+   public void testComAbabB()
+   {
+      Collection result = tree.search("com*abab*b");
+      assertEquals(0, result.size());
+   }
+
+   public void testNetAbab()
+   {
+      Collection result = tree.search("net*abab*");
+      assertEquals(3, result.size());
+      assertContent(result, 'V', 4, 'X', 4);
+   }
+
+   public void testNetAbabA()
+   {
+      Collection result = tree.search("net*abab*a");
+      assertEquals(0, result.size());
+   }
+
+   public void testNetAbabB()
+   {
+      Collection result = tree.search("net*abab*b");
+      assertEquals(2, result.size());
+      assertContent(result, 'W', 4, 'X', 4);
+   }
+
+   public void testAbcAbcAbdAbdAbcAbcAba()
+   {
+      Collection result = tree.search("*abc.abc.abd*abd.abc.abc.aba*");
+      assertEquals(1, result.size());
+      assertContent(result, "S4");
+   }
+   
+   public void testComAbcAbcAbdAbdAbcAbcAba()
+   {
+      Collection result = tree.search("com*abc.abc.abd*abd.abc.abc.aba*");
+      assertEquals(1, result.size());
+      assertContent(result, "S4");
+   }
+
+   public void testComAbcAbcAbdAbdAbcAbcAbaA()
+   {
+      Collection result = tree.search("com*abc.abc.abd*abd.abc.abc.aba*a");
+      assertEquals(1, result.size());
+      assertContent(result, "S4");
+   }
+
+   public void testComAbcAbcAbdAbdAbcAbcAbaB()
+   {
+      Collection result = tree.search("com*abc.abc.abd*abd.abc.abc.aba*b");
+      assertEquals(0, result.size());
+   }
+   
+   public void testNetAbcAbcAbdAbdAbcAbcAba()
+   {
+      Collection result = tree.search("net*abc.abc.abd*abd.abc.abc.aba*");
+      assertEquals(0, result.size());
+   }
+
+   public void testNetAbcAbcAbdAbdAbcAbcAbaA()
+   {
+      Collection result = tree.search("net*abc.abc.abd*abd.abc.abc.aba*a");
+      assertEquals(0, result.size());
+   }
+
+   public void testNetAbcAbcAbdAbdAbcAbcAbaB()
+   {
+      Collection result = tree.search("net*abc.abc.abd*abd.abc.abc.aba*b");
+      assertEquals(0, result.size());
+   }
+
+   public void testMmAbcAbdAbcAbcAba()
+   {
+      Collection result = tree.search("*mm*abc.abd.abc*abc.aba*");
+      assertEquals(2, result.size());
+      assertContent(result, 'W', 4, 'X', 4);
+   }
+
+   public void testComMmAbcAbdAbcAbcAba()
+   {
+      Collection result = tree.search("com*mm*abc.abd.abc*abc.aba*");
+      assertEquals(0, result.size());
+   }
+   public void testComMmAbcAbdAbcAbcAbaA()
+   {
+      Collection result = tree.search("com*mm*abc.abd.abc*abc.aba*a");
+      assertEquals(0, result.size());
+   }
+   
+   public void testComMmAbcAbdAbcAbcAbaB()
+   {
+      Collection result = tree.search("com*mm*abc.abd.abc*abc.aba*b");
+      assertEquals(0, result.size());
+   }
+   
+   public void testNetMmAbcAbdAbcAbcAba()
+   {
+      Collection result = tree.search("net*mm*abc.abd.abc*abc.aba*");
+      assertEquals(2, result.size());
+      assertContent(result, 'W', 4, 'X', 4);
+   }
+   
+   public void testNetMmAbcAbdAbcAbcAbaA()
+   {
+      Collection result = tree.search("net*mm*abc.abd.abc*abc.aba*a");
+      assertEquals(0, result.size());
+   }
+   
+   public void testNetMmAbcAbdAbcAbcAbaB()
+   {
+      Collection result = tree.search("net*mm*abc.abd.abc*abc.aba*b");
+      assertEquals(2, result.size());
+      assertContent(result, 'W', 4, 'X', 4);
+   }
+   
+   public void testM()
+   {
+      Collection result = tree.search("*m*");
+      assertEquals(98, result.size());
+      assertContent(result, 'A', 1, 'G', 4);
+      assertContent(result, 'K', 4, 'U', 4);
+      assertContent(result, 'W', 4, 'X', 4);
+   }
+
+   public void testComM()
+   {
+      Collection result = tree.search("com*m*");
+      assertEquals(45, result.size());
+      assertContent(result, 'A', 1, 'M', 2);
+      assertContent(result, new String[] {"K4", "U4"});
+      assertContent(result, 'M', 4, 'N', 4);
+      assertContent(result, 'P', 4, 'Q', 4);
+   }
+
+   public void testComMA()
+   {
+      Collection result = tree.search("com*m*a");
+      assertEquals(1, result.size());
+      assertContent(result, "U4");
+   }
+
+   public void testComMB()
+   {
+      Collection result = tree.search("com*m*b");
+      assertEquals(0, result.size());
+   }
+
+   public void testNetM()
+   {
+      Collection result = tree.search("net*m*");
+      assertEquals(50, result.size());
+      assertContent(result, 'N', 2, 'G', 4);
+      assertContent(result, new String[] {"L4", "O4"});
+      assertContent(result, 'W', 4, 'X', 4);
+   }
+
+   public void testNetMA()
+   {
+      Collection result = tree.search("net*m*a");
+      assertEquals(1, result.size());
+      assertContent(result, "D4");
+   }
+
+   public void testNetMB()
+   {
+      Collection result = tree.search("net*m*b");
+      assertEquals(2, result.size());
+      assertContent(result, 'W', 4, 'X', 4);
+   }
+   
+   public void testMm()
+   {
+      Collection result = tree.search("*mm*");
+      assertEquals(3, result.size());
+      assertContent(result, "L4");
+      assertContent(result, 'W', 4, 'X', 4);
+   }
+   
+   public void testComMm()
+   {
+      Collection result = tree.search("com*mm*");
+      assertEquals(0, result.size());
+   }
+
+   public void testComMmA()
+   {
+      Collection result = tree.search("com*mm*a");
+      assertEquals(0, result.size());
+   }
+   
+   public void testComMmB()
+   {
+      Collection result = tree.search("com*mm*b");
+      assertEquals(0, result.size());
+   }
+   
+   public void testNetMm()
+   {
+      Collection result = tree.search("net*mm*");
+      assertEquals(3, result.size());
+      assertContent(result, "L4");
+      assertContent(result, 'W', 4, 'X', 4);
+   }
+   
+   public void testNetMmA()
+   {
+      Collection result = tree.search("net*mm*a");
+      assertEquals(0, result.size());
+   }
+   
+   public void testNetMmB()
+   {
+      Collection result = tree.search("net*mm*b");
+      assertEquals(2, result.size());
+      assertContent(result, 'W', 4, 'X', 4);
+   }
+
+   public void testTwoOrMoreElements()
+   {
+      Collection result = tree.search("*.*");
+      assertEquals(94, result.size());
+      assertContent(result, 'A', 1, 'B', 4);
+      assertContent(result, 'K', 1, 'X', 4);
+   }
+
+   public void testThreeOrMoreElements()
+   {
+      Collection result = tree.search("*.*.*");
+      assertEquals(91, result.size());
+      assertContent(result, 'A', 1, 'U', 3);
+      assertContent(result, 'Y', 3, 'B', 4);
+      assertContent(result, 'K', 4, 'X', 4);
+   }
+
+   public void testFourOrMoreElements()
+   {
+      Collection result = tree.search("*.*.*.*");
+      assertEquals(87, result.size());
+      assertContent(result, 'A', 1, 'T', 3);
+      assertContent(result, "A4");
+      assertContent(result, 'K', 4, 'X', 4);
+   }
+
+   public void testFiveOrMoreElements()
+   {
+      Collection result = tree.search("*.*.*.*.*");
+      assertEquals(53, result.size()); 
+      assertContent(result, 'H', 1, 'J', 1);
+      assertContent(result, 'P', 1, 'M', 2);
+      assertContent(result, 'T', 2, 'Y', 2);
+      assertContent(result, 'F', 3, 'K', 3);
+      assertContent(result, 'K', 4, 'X', 4);
+   }
+
+   public void testSixOrMoreElements()
+   {
+      Collection result = tree.search("*.*.*.*.*.*");
+      assertEquals(24, result.size());
+      assertContent(result, 'Y', 1, 'A', 2);
+      assertContent(result, 'G', 2, 'M', 2);
+      assertContent(result, 'K', 4, 'X', 4);
+   }
+
+   public void testSevenOrMoreElements()
+   {
+      Collection result = tree.search("*.*.*.*.*.*.*");
+      assertEquals(14, result.size());
+      assertContent(result, 'K', 4, 'X', 4);
+   }
+
+   public void testEightOrMoreElements()
+   {
+      Collection result = tree.search("*.*.*.*.*.*.*.*");
+      assertEquals(14, result.size());
+      assertContent(result, 'K', 4, 'X', 4);
+   }
+
+   public void testNineOrMoreElements()
+   {
+      Collection result = tree.search("*.*.*.*.*.*.*.*.*");
+      assertEquals(6, result.size());
+      assertContent(result, 'M', 4, 'N', 4);
+      assertContent(result, 'P', 4, 'Q', 4);
+      assertContent(result, 'W', 4, 'X', 4);
+   }
+
+   public void testTenOrMoreElements()
+   {
+      Collection result = tree.search("*.*.*.*.*.*.*.*.*.*");
+      assertEquals(3, result.size());
+      assertContent(result, "N4");
+      assertContent(result, 'W', 4, 'X', 4);
+   }
+
+   public void testElevenOrMoreElements()
+   {
+      Collection result = tree.search("*.*.*.*.*.*.*.*.*.*.*");
+      assertEquals(3, result.size());
+      assertContent(result, "N4");
+      assertContent(result, 'W', 4, 'X', 4);
+   }
+
+   public void testTwelveOrMoreElements()
+   {
+      Collection result = tree.search("*.*.*.*.*.*.*.*.*.*.*.*");
+      assertEquals(1, result.size());
+      assertContent(result, "N4");
+   }
+
+   public void testThirteenOrMoreElements()
+   {
+      Collection result = tree.search("*.*.*.*.*.*.*.*.*.*.*.*.*");
+      assertEquals(1, result.size());
+      assertContent(result, "N4");
+   }
+
+   public void testFourteenOrMoreElements()
+   {
+      Collection result = tree.search("*.*.*.*.*.*.*.*.*.*.*.*.*.*");
+      assertEquals(0, result.size());
+   }
+
+   public void testComCompanyPackageClass3()
+   {
+      Collection result = tree.search("com.company.package.Class3");
+      assertEquals(1, result.size());
+      assertContent(result, "D1");
+   }
+
+   public void testComCompanyPackageImplInterface1Impl()
+   {
+      Collection result = tree.search(
+            "com.company.package.impl.Interface1Impl");
+      assertEquals(1, result.size());
+      assertContent(result, "I1");
+   }
+
+   public void testComCompanyInternalStaticFactory()
+   {
+      Collection result = tree.search("com.company.internal.StaticFactory");
+      assertEquals(1, result.size());
+      assertContent(result, "N1");
+   }
+
+   public void testComCompAnyPackageClass30()
+   {
+      Collection result = tree.search("com.comp.any.package.Class30");
+      assertEquals(1, result.size());
+      assertContent(result, "U1");
+   }
+
+   public void testComCompAnyInternalPackageInterface()
+   {
+      Collection result = tree.search(
+            "com.comp.any.internal.package.Interface");
+      assertEquals(1, result.size());
+      assertContent(result, "I2");
+   }
+
+   public void testComCompAnyInternalPackageCaller()
+   {
+      Collection result = tree.search("com.comp.any.internal.package.Caller");
+      assertEquals(1, result.size());
+      assertContent(result, "K2");
+   }
+
+   public void testNetOtherCompanyPackageObservable()
+   {
+      Collection result = tree.search("net.otherCompany.package.Observable");
+      assertEquals(1, result.size());
+      assertContent(result, "S2");
+   }
+
+   public void testNetOtherCompanyPackagePackage1Interface()
+   {
+      Collection result = tree.search(
+            "net.otherCompany.package.package1.Interface");
+      assertEquals(1, result.size());
+      assertContent(result, "W2");
+   }
+
+   public void testNetOtherCompanyPackagePackage1InterfaceImpl()
+   {
+      Collection result = tree.search(
+            "net.otherCompany.package.package1.InterfaceImpl");
+      assertEquals(1, result.size());
+      assertContent(result, "X2");
+   }
+
+   public void testNetOtherCompanyPackagePackage2Factory()
+   {
+      Collection result = tree.search(
+            "net.otherCompany.package.package2.Factory");
+      assertEquals(1, result.size());
+      assertContent(result, "H3");
+   }
+
+   public void testNetOtherCompanyPackage3Factory()
+   {
+      Collection result = tree.search("net.otherCompany.package3.Factory");
+      assertEquals(1, result.size());
+      assertContent(result, "T3");
+   }
+
+   public void testNetOtherCompanyPackage()
+   {
+      Collection result = tree.search("net.otherCompany.package");
+      assertEquals(1, result.size());
+      assertContent(result, "U3");
+   }
+   
+   public void testNetYourCompany1()
+   {
+      Collection result = tree.search("net.yourCompany1");
+      assertEquals(1, result.size());
+      assertContent(result, "W3");
+   }
+
+   public void testNetYourCompany12Class()
+   {
+      Collection result = tree.search("net.yourCompany12.Class");
+      assertEquals(1, result.size());
+      assertContent(result, "Y3");
+   }
+
+   public void testNetComPackcompackpaaaaaaaaaackNetComPackNetClient()
+   {
+      Collection result = tree.search(
+            "net.com.packcompackpaaaaaaaaaack.net.com.pack.net.Client");
+      assertEquals(1, result.size());
+      assertContent(result, "O4");
+   }
+
+   public void testNetonemoitisnotenoughthenoofkeysyet()
+   {
+      Collection result = tree.search("netonemoitisnotenoughthenoofkeysyet");
+      assertEquals(1, result.size());
+      assertContent(result, "G4");
+   }
+   
+   public void test12312313212311312346717118134134()
+   {
+      Collection result = tree.search("12312313212311312346717118134134");
+      assertEquals(1, result.size());
+      assertContent(result, "I4");
+   }
+
+   public void test17717171717171311312467111919191()
+   {
+      Collection result = tree.search("17717171717171311312467111919191");
+      assertEquals(1, result.size());
+      assertContent(result, "J4");
+   }
+
+   public void testComAbcAbcAbcAbdAbcAbcAbabaaaaaaaaa()
+   {
+      Collection result = tree.search(
+            "com.abc.abc.abc.abd.abc.abc.ababaaaaaaaaa");
+      assertEquals(1, result.size());
+      assertContent(result, "T4");
+   }
+
+   public void testNetMmmAbcAbdAbcAbcAbcAbddAbcAbcAbabab()
+   {
+      Collection result = tree.search(
+            "net.mmm.abc.abd.abc.abc.abc.abdd.abc.abc.ababab");
+      assertEquals(1, result.size());
+      assertContent(result, "W4");
+   }
+
+   public void testNetOtherCompanyInternalClass()
+   {
+      Collection result = tree.search("net.otherCompany.internal.Class");
+      assertEquals(0, result.size());
+   }
+
+   public void testYourCompany()
+   {
+      Collection result = tree.search("yourCompany");
+      assertEquals(0, result.size());
+   }
+
+   public void test12312313212311312346717118134135()
+   {
+      Collection result = tree.search("12312313212311312346717118134135");
+      assertEquals(0, result.size());
+   }
+   
+   public void testComAbcAbcAbdMabcAbcAbcAbabaaaaaaaa()
+   {
+      Collection result = tree.search(
+            "com.abc.abc.abd.mabc.abc.abc.ababaaaaaaaa");
+      assertEquals(0, result.size());
+   }
+
+   /**
+    * Asserts <code>result</code> contains every element of the interval
+    * formed by <code>start</code> concatenated with <code>startNumber</code>
+    * and <code>end</code> concatenated with <code>endNumber</code>.
+    * 
+    * @param result      the search result
+    * @param start       the character that defines the lower limit of the
+    *                    interval
+    * @param startNumber the number that defines the lower limit of the interval
+    * @param end         the character that defines the upper limit of the
+    *                    interval
+    * @param endNumber   the number that defines the upper limit of the interval
+    */
+   private void assertContent(Collection result, char start, int startNumber,
+         char end, int endNumber)
+   {
+      for (int i = startNumber; i <= endNumber; i++)
+      {
+         int cEnd =  (i == endNumber)? end: 'Z';
+         for (char c = start; c <= cEnd; c++)
+         {
+            assertContent(result, String.valueOf(c) + i);
+         }
+      }
+   }
+   
+   /**
+    * Asserts <code>result</code> contains every element of <code>content
+    * </code>.
+    * 
+    * @param result  the search result
+    * @param content the content array whose elements are expected to be
+    *                contained in <code>result</code>
+    */
+   private void assertContent(Collection result, String[] content)
+   {
+      for (int i = 0; i < content.length; i++)
+      {
+         assertContent(result, content[i]);
+      }
+   }
+   
+   /**
+    * Asserts <code>result</code> contains <code>content</code>.
+    * 
+    * @param result  the search result
+    * @param content the content that is expected to be contained in <code>
+    *                result</code>
+    */
+   private void assertContent(Collection result, String content)
+   {
+      assertTrue("Result doesn't contain " + content,
+            result.contains(content));
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/Util.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/Util.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/Util.java	2008-01-03 18:54:24 UTC (rev 68603)
@@ -0,0 +1,204 @@
+/*
+ * 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.ExtendedLengthRange;
+import org.jboss.aop.joinpoint.graph.tree.KeyPart;
+import org.jboss.aop.joinpoint.graph.tree.search.match.LengthRange;
+
+import junit.framework.TestCase;
+
+/**
+ * Contains key part assertions that are common to more than one test.
+ * 
+ * @author Flavia Rainone
+ */
+public class Util
+{
+   /**
+    * Asserts <code>keyPart</code> expected internal data knowing that <code>
+    * keyPart</code> is expected to have one or more suffixes and to have a
+    * last element incomplete.
+    * 
+    * @param keyPart            the key part whose internal data will be
+    *                           asserted
+    * @param first              the expected first character of <code>keyPart
+    *                           </code>
+    * @param elements           the expected elements of <code>keyPart</code>
+    * @param ppMinLength        the expected value of the post-prefix minimum
+    *                           length
+    * @param ppMaxLength        the expected value of the post-prefix maximum
+    *                           length
+    * @param elementPPMinLength the expected value of the last element
+    *                           post-prefix minimum length
+    * @param elementPPMaxLength the expected value of the last element
+    *                           post-prefix maximum length
+    */
+   public static void assertKeyPart(KeyPart keyPart, char first,
+         String[] elements, int ppMinLength, int ppMaxLength,
+         int elementPPMinLength, int elementPPMaxLength)
+   {
+      Util.assertKeyPart(keyPart, first, elements, false);
+      assertLengthRange(keyPart.getLengthRange(), elements.length, ppMinLength,
+            ppMaxLength, elements[elements.length - 1].length(),
+            elementPPMinLength, elementPPMaxLength);
+   }
+   
+   /**
+    * Asserts <code>keyPart</code> expected internal data knowing that <code>
+    * keyPart</code> is expected to have one or more suffixes and to have a last
+    * element complete.
+    * 
+    * @param keyPart             the key part whose internal data will be
+    *                            asserted
+    * @param first               the expected first character of <code>keyPart
+    *                            </code>
+    * @param elements            the expected elements of <code>keyPart</code>
+    * @param postPrefixMinLength the expected value of the post-prefix minimum
+    *                            length
+    * @param postPrefixMaxLength the expected value of the post-prefix maximum
+    *                            length
+    */
+   public static void assertKeyPart(KeyPart keyPart, char first,
+         String[] elements, int postPrefixMinLength, int postPrefixMaxLength)
+   {
+      assertKeyPart(keyPart, first, elements, true);
+      assertLengthRange(keyPart.getLengthRange(), elements.length,
+            postPrefixMinLength, postPrefixMaxLength, "keyPart");
+   }
+   
+   /**
+    * Assserts <code>keyPart</code> internal data knowing that <code>keyPart
+    * </code> is expected to be a key part without suffixes.
+    * 
+    * @param keyPart  the key part whose internal data will be asserted
+    * @param first    the expected first character of <code>keyPart</code>
+    * @param elements the expected elements of <code>keyPart</code>
+    */
+   public static void assertKeyPart(KeyPart keyPart, char first,
+         String[] elements)
+   {
+      assertKeyPart(keyPart, first, elements, elements.length, elements.length);
+   }
+   
+   /**
+    * Asserts the expected data contained in <code>lengthRange</code>, knowing
+    * that it is expected to be not an instance of <code>ExtendedLengthRange
+    * </code>.
+    * 
+    * @param lengthRange         the length range whose data will be asserted
+    * @param length              the length of the key part associated with
+    *                            <code>lengthRange</code>
+    * @param postPrefixMinLength the post-prefix minimum length of the key part
+    *                            associated with <code>lengthRange</code> 
+    * @param postPrefixMaxLength the post-prefix maximum length of the key part
+    *                            associated with <code>lengthRange</code>
+    */
+   public static void assertLengthRange(LengthRange lengthRange, int length,
+         int postPrefixMinLength, int postPrefixMaxLength)
+   {
+      assertLengthRange(lengthRange, length, postPrefixMinLength,
+            postPrefixMaxLength, "keyPart");
+   }
+   
+   /**
+    * Asserts the expected data contained in <code>lengthRange</code>, knowing
+    * that it is expected to be an instance of <code>ExtendedLengthRange</code>.
+    * 
+    * @param lengthRange        the length range whose data will be asserted
+    * @param length             the length of the key part associated with
+    *                           <code>lengthRange</code>
+    * @param ppMinLength        the post-prefix minimum length of the key part
+    *                           associated with <code>lengthRange</code> 
+    * @param ppMaxLength        the post-prefix maximum length of the key part
+    *                           associated with <code>lengthRange</code>
+    * @param elementLength      the length of the last element of the key part
+    *                           associated with <code>lenghtRange</code>
+    * @param elementPPMinLength the post-prefix minimum length of the last
+    *                           element of the key part associated with <code>
+    *                           lengthRange</code>
+    * @param elementPPMaxLength the post-prefix maximum length of the last
+    *                           element of the key part associated with <code>
+    *                           lengthRange</code>
+    */
+   public static void assertLengthRange(LengthRange lengthRange, int length,
+         int ppMinLength, int ppMaxLength, int elementLength,
+         int elementPPMinLength, int elementPPMaxLength)
+   {
+      assertLengthRange(lengthRange, length, ppMinLength, ppMaxLength,
+            "keyPart");
+      LengthRange elementLengthRange =
+         ((ExtendedLengthRange) lengthRange).getElementLengthRange();
+      assertLengthRange(elementLengthRange, elementLength, elementPPMinLength,
+            elementPPMaxLength, "element");
+   }
+   
+   /**
+    * Asserts <code>keyPart</code> expected internal data.
+    * 
+    * @param keyPart      the key part whose internal data will be asserted
+    * @param first        the expected first character of <code>keyPart</code>
+    * @param elements     the expected elements of <code>keyPart</code>
+    * @param lastComplete the expected value of <code>
+    *                     keyPart.isLastElementComplete()</code>
+    */
+   private static void assertKeyPart(KeyPart keyPart, char first,
+         String[] elements, boolean lastComplete)
+   {
+      TestCase.assertEquals(first, keyPart.getFirstCharacter());
+      TestCase.assertEquals(elements.length, keyPart.getKeyElements().length);
+      for (int i = 0; i < elements.length; i++)
+      {
+         TestCase.assertEquals(elements[i], keyPart.getKeyElements()[i]);
+      }
+      TestCase.assertEquals("Last element is not complete", lastComplete,
+            keyPart.isLastElementComplete());
+      TestCase.assertEquals(!lastComplete,
+            keyPart.getLengthRange() instanceof ExtendedLengthRange);
+   }
+   
+   /**
+    * Asserts the expected data contained in <code>lengthRange</code>.
+    * 
+    * @param lengthRange         the length range whose data will be asserted
+    * @param length              the length of the key part associated with
+    *                            <code>lengthRange</code>
+    * @param postPrefixMinLength the post-prefix minimum length of the key part
+    *                            associated with <code>lengthRange</code> 
+    * @param postPrefixMaxLength the post-prefix maximum length of the key part
+    *                            associated with <code>lengthRange</code>
+    *                            
+    * @param target description of the target of <code>lengthRange</code>
+    */
+   private static void assertLengthRange(LengthRange lengthRange, int length,
+         int postPrefixMinLength, int postPrefixMaxLength, String target)
+   {
+      TestCase.assertEquals("Wrong " + target + " length", length,
+            lengthRange.getLength());
+      TestCase.assertEquals("Wrong " + target +
+            " length range post prefix minimum length",
+            postPrefixMinLength, lengthRange.getPostPrefixMinLength());
+      TestCase.assertEquals("Wrong " + target +
+            " length range post prefix maximum length",
+            postPrefixMaxLength, lengthRange.getPostPrefixMaxLength());
+   }
+}
\ No newline at end of file

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

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/insertion/InsertionKeyTestCase.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/insertion/InsertionKeyTestCase.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/insertion/InsertionKeyTestCase.java	2008-01-03 18:54:24 UTC (rev 68603)
@@ -0,0 +1,141 @@
+/*
+ * 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;
+import org.jboss.aop.joinpoint.graph.tree.Util;
+import org.jboss.aop.joinpoint.graph.tree.insertion.InsertionKey;
+
+import junit.framework.TestCase;
+
+/**
+ * Test of the {@link InsertionKey} class
+ * 
+ * @author Flavia Rainone
+ */
+public class InsertionKeyTestCase extends TestCase
+{
+   private InsertionKey insertionKey;
+   
+   public void setUp()
+   {
+      insertionKey = new InsertionKey("a.key.to.be.inserted.on.the.tree");
+   }
+   
+   public void testInsertionComplete()
+   {
+      KeyPart keyPart = new KeyPart("a.key.to.be.inserted.on.the.tree");
+      assertEquals(keyPart, insertionKey.extractCommonPrefix(keyPart));
+      assertEquals(InsertionKey.INSERTION_COMPLETE, insertionKey.getNextChar());
+   }
+   
+   public void testToKeyPart()
+   {
+      KeyPart keyPart = insertionKey.toKeyPart();
+      Util.assertKeyPart(keyPart, 'a', new String[] {"a", "key", "to",
+            "be", "inserted", "on", "the", "tree"});
+   }
+   
+   public void testPrefixExtraction()
+   {
+      KeyPart keyPart = new KeyPart("a.different.key.part");
+      KeyPart prefixKeyPart = insertionKey.extractCommonPrefix(keyPart);
+      Util.assertKeyPart(keyPart, 'd',
+            new String[] {"different", "key", "part"});
+      Util.assertKeyPart(prefixKeyPart, 'a', new String[]{"a"}, 4, 4);
+      assertEquals('k', insertionKey.getNextChar());
+      KeyPart insertionKeyPart = insertionKey.toKeyPart();
+      Util.assertKeyPart(insertionKeyPart, 'k', new String[] {"key",
+            "to", "be", "inserted", "on", "the", "tree"});
+   }
+   
+   public void testPrefixExtraction2()
+   {
+      KeyPart keyPart = new KeyPart("all.key.part");
+      KeyPart prefixKeyPart = insertionKey.extractCommonPrefix(keyPart);
+      Util.assertKeyPart(keyPart, 'l', new String[] {"ll", "key",
+            "part"});
+      Util.assertKeyPart(prefixKeyPart, 'a', new String[]{"a"}, 3, 3, 3, 3);
+      assertEquals(KeyPart.KEY_ELEMENT_END, insertionKey.getNextChar());
+      KeyPart insertionKeyPart = insertionKey.toKeyPart();
+      Util.assertKeyPart(insertionKeyPart, KeyPart.KEY_ELEMENT_END,
+            new String[] {"", "key", "to", "be", "inserted", "on", "the",
+            "tree"});
+      
+      keyPart = new KeyPart(".key.to.be.thrown.away");
+      prefixKeyPart = insertionKey.extractCommonPrefix(keyPart);
+      Util.assertKeyPart(keyPart, 't',
+            new String[] {"thrown", "away"});
+      Util.assertKeyPart(prefixKeyPart, KeyPart.KEY_ELEMENT_END,
+            new String[]{"", "key", "to", "be"}, 6, 6);
+      assertEquals('i', insertionKey.getNextChar());
+      insertionKeyPart = insertionKey.toKeyPart();
+      Util.assertKeyPart(insertionKeyPart, 'i',
+            new String[] {"inserted", "on", "the", "tree"});
+   }
+   
+   public void testPrefixExtraction3()
+   {
+      KeyPart keyPart = new KeyPart("a.key.to.be.inserted.on.the.tree123");
+      KeyPart target = keyPart.extractPrefixPart(7, 4);
+      Util.assertKeyPart(target, 'a', new String[] {"a", "key", "to", "be",
+            "inserted", "on", "the", "tree"}, 8, 8, 7, 7);
+      assertSame(target, insertionKey.extractCommonPrefix(target));
+      assertEquals(KeyPart.KEY_ELEMENT_END, insertionKey.getNextChar());
+      KeyPart insertionKeyPart = insertionKey.toKeyPart();
+      Util.assertKeyPart(insertionKeyPart, KeyPart.KEY_ELEMENT_END,
+            new String[] {""});
+   }
+   
+   public void testPrefixExtraction4()
+   {
+      KeyPart keyPart = new KeyPart("a.key.to.be.inserted.on.the.tree");
+      assertSame(keyPart, insertionKey.extractCommonPrefix(keyPart));
+      assertEquals(InsertionKey.INSERTION_COMPLETE, insertionKey.getNextChar());
+      assertSame(KeyPart.EMPTY_KEY_END, insertionKey.toKeyPart());
+      assertEquals(KeyPart.EMPTY_KEY_END,
+            insertionKey.extractCommonPrefix(KeyPart.EMPTY_KEY_END));
+   }
+   
+   public void testPrefixExtraction5()
+   {
+      KeyPart keyPart = new KeyPart("a.key.to.be.inserted.on.the.tree");
+      KeyPart prefixPart = keyPart.extractPrefixPart(0, 1);
+      Util.assertKeyPart(prefixPart, 'a', new String[]{"a"}, 8, 8, 1, 1);
+      assertSame(prefixPart, insertionKey.extractCommonPrefix(prefixPart));
+      assertEquals(KeyPart.KEY_ELEMENT_END, insertionKey.getNextChar());
+      Util.assertKeyPart(insertionKey.toKeyPart(),
+            KeyPart.KEY_ELEMENT_END, new String[] {"", "key", "to", "be",
+         "inserted", "on", "the", "tree"});
+   }
+   
+   public void testPrefixExtraction6()
+   {
+      KeyPart keyPart = new KeyPart("a.key.to.be.inserted.on.the.tree");
+      KeyPart prefixPart = keyPart.extractPrefixPart(1, 1);
+      Util.assertKeyPart(prefixPart, 'a', new String[]{"a", "k"}, 8, 8, 3, 3);
+      assertSame(prefixPart, insertionKey.extractCommonPrefix(prefixPart));
+      assertEquals('e', insertionKey.getNextChar());
+      Util.assertKeyPart(insertionKey.toKeyPart(), 'e',
+            new String[] {"ey", "to", "be", "inserted", "on", "the", "tree"});
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/AllTests.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/AllTests.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/AllTests.java	2008-01-03 18:54:24 UTC (rev 68603)
@@ -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;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * Test suite that contains all test cases of this package.
+ * 
+ * @author Flavia Rainone
+ */
+public class AllTests
+{
+
+   public static Test suite()
+   {
+      TestSuite suite = new TestSuite("Test for org.jboss.aop.joinpoint.graph.tree.search");
+      //$JUnit-BEGIN$
+      suite.addTestSuite(SearchKeyTest.class);
+      suite.addTest(org.jboss.aop.joinpoint.graph.tree.search.common.AllTests.suite());
+      suite.addTest(org.jboss.aop.joinpoint.graph.tree.search.element.AllTests.suite());
+      suite.addTest(org.jboss.aop.joinpoint.graph.tree.search.match.AllTests.suite());
+      suite.addTest(org.jboss.aop.joinpoint.graph.tree.search.part.AllTests.suite());
+      //$JUnit-END$
+      return suite;
+   }
+
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/SearchKeyTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/SearchKeyTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/SearchKeyTest.java	2008-01-03 18:54:24 UTC (rev 68603)
@@ -0,0 +1,2358 @@
+/*
+ * 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.Flags;
+import org.jboss.aop.joinpoint.graph.tree.search.SearchKey;
+
+import junit.framework.TestCase;
+
+/**
+ * Test of the {@link SearchKey} class.
+ * 
+ * @author Flavia Rainone
+ */
+public class SearchKeyTest extends TestCase
+{
+   public void testOneElOneTarget()
+   {
+      // setup scenario
+      KeyPart keyPart = new KeyPart("anyExpression");
+      // test search key
+      SearchKey searchKey = new SearchKey("anyExpression");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testOneElBrokenTarget1()
+   {
+      // setup scenario
+      KeyPart keyPart2 = new KeyPart("anyExpression");
+      KeyPart keyPart1 = keyPart2.extractPrefixPart(0, 3);
+      // test search key
+      SearchKey searchKey = new SearchKey("anyExpression");
+      assertEquals('E', searchKey.matches(keyPart1));
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart2));
+   }
+   
+   public void testOneElBrokenTarget2()
+   {
+      // setup scenario
+      KeyPart keyPart3 = new KeyPart("anyExpression");
+      KeyPart keyPart2 = keyPart3.extractPrefixPart(0, 6);
+      KeyPart keyPart1 = keyPart2.extractPrefixPart(0, 1);
+      // test search key
+      SearchKey searchKey = new SearchKey("anyExpression");
+      assertEquals('n', searchKey.matches(keyPart1));
+      assertEquals('r', searchKey.matches(keyPart2));
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart3));
+   }
+   
+   public void testOneElEmptyKeyEnd()
+   {
+      // setup scenario
+      KeyPart keyPart1 = new KeyPart("anyExpression");
+      KeyPart keyPart2 = new KeyPart("longSuffix");
+      keyPart1.newSuffix(keyPart2);
+      // test search key
+      SearchKey searchKey = new SearchKey("anyExpression");
+      assertEquals(KeyPart.KEY_ELEMENT_END, searchKey.matches(keyPart1));
+      assertEquals(Flags.POSITIVE, searchKey.matches(KeyPart.EMPTY_KEY_END));
+   }
+   
+
+   public void testOneElElemEnd()
+   {
+      // setup scenario
+      KeyPart keyPart2 = new KeyPart("anyExpression");
+      KeyPart keyPart1 = keyPart2.extractPrefixPart(0, 13);
+      // test search key
+      SearchKey searchKey = new SearchKey("anyExpression");
+      assertEquals(KeyPart.KEY_ELEMENT_END, searchKey.matches(keyPart1));
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart2));
+   }
+   
+   public void testOneElNegative1()
+   {
+      // setup scenario
+      KeyPart keyPart = new KeyPart("differentExpression");
+      // test search key
+      SearchKey searchKey = new SearchKey("anyExpression");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testOneElNegative2()
+   {
+      // test search key
+      SearchKey searchKey = new SearchKey("anyExpression");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(KeyPart.EMPTY_KEY_END));
+   }
+
+   public void testOneElNegative3()
+   {
+      // setup scenario
+      KeyPart keyPart = new KeyPart("");
+      // test search key
+      SearchKey searchKey = new SearchKey("anyExpression");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testOneElSuffixBrokenTarget()
+   {
+      // setup scenario
+      KeyPart keyPart14 = new KeyPart(
+            "averyveryveryloooongoneelementexpressonanyExpression");
+      KeyPart keyPart13 = keyPart14.extractPrefixPart(0, 26);
+      KeyPart keyPart15 = new KeyPart(
+            "anotherDifferentSuffixEndingWithanyExpression");
+      keyPart13.newSuffix(keyPart15);
+      KeyPart keyPart16 = new KeyPart("obviouslyOneSuffixLongWithAMismatch");
+      keyPart13.newSuffix(keyPart16);
+      KeyPart keyPart3 = keyPart13.extractPrefixPart(0, 19);
+      KeyPart keyPart11 = new KeyPart(
+            "somethingveryveryeryveryrelationshipanyExpression");
+      KeyPart keyPart10 = keyPart11.extractPrefixPart(0, 36);
+      KeyPart keyPart12 = new KeyPart("unyExpression");
+      keyPart10.newSuffix(keyPart12);
+      KeyPart keyPart4 = keyPart10.extractPrefixPart(0, 24);
+      KeyPart keyPart5 = new KeyPart("abcdefghijklanyExpression");
+      keyPart4.newSuffix(keyPart5);
+      KeyPart keyPart7 = new KeyPart("mnopqrstuvxyzanyExpressio");
+      KeyPart keyPart6 = keyPart7.extractPrefixPart(0, 6);
+      KeyPart keyPart8 = new KeyPart("anyanyanyExpression");
+      keyPart6.newSuffix(keyPart8);
+      KeyPart keyPart9 = new KeyPart("bcdefganyExpression");
+      keyPart6.newSuffix(keyPart9);
+      keyPart4.newSuffix(keyPart6);
+      keyPart3.newSuffix(keyPart4);
+      KeyPart keyPart1 = keyPart3.extractPrefixPart(0, 10);
+      KeyPart keyPart2 = new KeyPart(
+            "abcdefghijklmnopqrstuvwxyzobviousmismatchagain");
+      keyPart1.newSuffix(keyPart2);
+
+      // test search key
+      
+      SearchKey searchKey = new SearchKey("*anyExpression");
+      
+      assertEquals(Flags.ALL, searchKey.matches(keyPart1));
+      
+      SearchKey searchKey1 = searchKey.getWildcardInstance();
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.NEGATIVE, searchKey1.matches(keyPart2));
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.ALL, searchKey1.matches(keyPart3));
+      
+      SearchKey searchKey2 = searchKey1.getWildcardInstance();
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.ALL, searchKey2.matches(keyPart4));
+      
+      SearchKey searchKey3 = searchKey2.getWildcardInstance();
+      searchKey2.prepareWildcardInstance(searchKey3);
+      assertEquals(Flags.POSITIVE, searchKey3.matches(keyPart5));
+      searchKey2.prepareWildcardInstance(searchKey3);
+      assertEquals(Flags.ALL, searchKey3.matches(keyPart6));
+      
+      SearchKey searchKey4 = searchKey3.getWildcardInstance();
+      searchKey3.prepareWildcardInstance(searchKey4);
+      assertEquals(Flags.NEGATIVE, searchKey4.matches(keyPart7));
+      searchKey3.prepareWildcardInstance(searchKey4);
+      assertEquals(Flags.POSITIVE, searchKey4.matches(keyPart8));
+      searchKey3.prepareWildcardInstance(searchKey4);
+      assertEquals(Flags.POSITIVE, searchKey4.matches(keyPart9));
+      
+      searchKey3 = searchKey2.getWildcardInstance();
+      searchKey2.prepareWildcardInstance(searchKey3);
+      assertEquals('a', searchKey3.matches(keyPart10));      
+      assertEquals(Flags.POSITIVE, searchKey3.matches(keyPart11));
+      
+      searchKey2 = searchKey1.getWildcardInstance();
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.ALL, searchKey2.matches(keyPart13));
+      
+      searchKey3 = searchKey2.getWildcardInstance();
+      searchKey2.prepareWildcardInstance(searchKey3);
+      assertEquals(Flags.POSITIVE, searchKey3.matches(keyPart14));
+      searchKey2.prepareWildcardInstance(searchKey3);
+      assertEquals(Flags.POSITIVE, searchKey3.matches(keyPart15));
+      searchKey2.prepareWildcardInstance(searchKey3);
+      assertEquals(Flags.NEGATIVE, searchKey3.matches(keyPart16));
+   }
+   
+   public void testNoPatternOneTarget1()
+   {
+      // setup scenario
+      KeyPart keyPart = new KeyPart("anyExpression");
+      // test search key
+      SearchKey searchKey = new SearchKey("any*Expression");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testNoPatternOneTarget2()
+   {
+      // setup scenario
+      KeyPart keyPart = new KeyPart("anyXXXXXXExpression");
+      // test search key
+      SearchKey searchKey = new SearchKey("any*Expression");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testNoPatternOneTarget3()
+   {
+      // setup scenario
+      KeyPart keyPart = new KeyPart("anyXXXXXXExpression");
+      // test search key
+      SearchKey searchKey = new SearchKey("any*Expression");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+
+   public void testNoPatternOneTarget4()
+   {
+      // setup scenario
+      KeyPart keyPart = new KeyPart("any.Expression");
+      // test search key
+      SearchKey searchKey = new SearchKey("any*Expression");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+
+   public void testNoPatternOneTarget5()
+   {
+      // setup scenario
+      KeyPart keyPart = new KeyPart("any.blabla.Expression");
+      // test search key
+      SearchKey searchKey = new SearchKey("any*Expression");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testNoPatternOneTarget6()
+   {
+      // setup scenario
+      KeyPart keyPart = new KeyPart(
+            "anythingthat.garbage.garbage.garbage.somePrefixExpression");
+      // test search key
+      SearchKey searchKey = new SearchKey("any*Expression");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testNoPatternBrokenTarget1()
+   {
+      // setup scenario
+      KeyPart keyPart2 = new KeyPart("anyXXXXXXExpression");
+      KeyPart keyPart1 = keyPart2.extractPrefixPart(0, 10);
+      // test search key
+      SearchKey searchKey = new SearchKey("any*Expression");
+      assertEquals('x', searchKey.matches(keyPart1));
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart2));
+   }
+   
+   public void testNoPatternBrokenTarget2()
+   {
+      // setup scenario
+      SearchKey searchKey = new SearchKey("any*Expression");
+      KeyPart keyPart2 = new KeyPart("any.Expression");
+      KeyPart keyPart1 = keyPart2.extractPrefixPart(1, 0);
+      KeyPart keyPart4 = new KeyPart("anyanyanyanyanyExpresExpression");
+      KeyPart keyPart3 = keyPart4.extractPrefixPart(0, 28);
+      KeyPart keyPart5 = new KeyPart("");
+      keyPart3.newSuffix(keyPart5);
+      keyPart1.newSuffix(keyPart3);
+      // test search key
+      assertEquals(Flags.ALL, searchKey.matches(keyPart1));
+      SearchKey searchKey1 = searchKey.getWildcardInstance();
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.POSITIVE, searchKey1.matches(keyPart2));
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals('i', searchKey1.matches(keyPart3));
+      assertEquals(Flags.POSITIVE, searchKey1.matches(keyPart4));
+   }
+   
+   public void testNoPatternBrokenTarget3()
+   {
+      // setup scenario
+      KeyPart keyPart2 = new KeyPart("any.Expression");
+      KeyPart keyPart1 = keyPart2.extractPrefixPart(1, 0);
+      KeyPart keyPart4 = new KeyPart("anyanyanyanyanyExpresExpression");
+      KeyPart keyPart3 = keyPart4.extractPrefixPart(0, 28);
+      KeyPart keyPart5 = new KeyPart("");
+      keyPart3.newSuffix(keyPart5);
+      keyPart1.newSuffix(keyPart3);
+      // test search key
+      SearchKey searchKey = new SearchKey("any.*Expression");
+      assertEquals(Flags.ALL, searchKey.matches(keyPart1));
+      SearchKey searchKey1 = searchKey.getWildcardInstance();
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.POSITIVE, searchKey1.matches(keyPart2));
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals('i', searchKey1.matches(keyPart3));
+      assertEquals(Flags.POSITIVE, searchKey1.matches(keyPart4));
+   }
+   
+   public void testNoPatternNegative1()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("any.Expression");
+      // bb
+      SearchKey searchKey = new SearchKey("any.*.Expression");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testNoPatternNegative2()
+   {
+      // aa
+      KeyPart keyPart2 = new KeyPart("any.Expression");
+      KeyPart keyPart1 = keyPart2.extractPrefixPart(0, 1);
+      KeyPart keyPart3 = new KeyPart("something");
+      keyPart1.newSuffix(keyPart3);
+      // bb
+      SearchKey searchKey = new SearchKey("any.*.Expression");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(keyPart1));
+   }
+   
+   public void testEmptyPrefixPatternOneTarget1()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("any.thinganExpression");
+      // bb
+      SearchKey searchKey = new SearchKey("any*.thing*anExpression");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testEmptyPrefixPatternOneTarget2()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("any.anyany.thinganExpression");
+      // bb
+      SearchKey searchKey = new SearchKey("any*.thing*anExpression");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testEmptyPrefixPatternOneTarget3()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart(
+            "any.anyany.thing.anexp.anexp.aaaanExpression");
+      // bb
+      SearchKey searchKey = new SearchKey("any*.thing*anExpression");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testEmptyPrefixPatternBrokenTarget()
+   {
+      // aa
+      KeyPart keyPart3 = new KeyPart("any.any.any.thin.any.thing.anExpression");
+      KeyPart keyPart2 = keyPart3.extractPrefixPart(3, 0);
+      KeyPart keyPart1 = keyPart2.extractPrefixPart(2, 1);
+      KeyPart keyPart4 = new KeyPart(".thinganExpression");
+      keyPart1.newSuffix(keyPart4);
+      keyPart2.newSuffix(KeyPart.EMPTY_KEY_END);
+      
+      // bb
+      
+      SearchKey searchKey = new SearchKey("any*.thing*anExpression");      
+      
+      assertEquals(Flags.ALL, searchKey.matches(keyPart1));
+      
+      SearchKey searchKey1 = searchKey.getWildcardInstance();
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.POSITIVE, searchKey1.matches(keyPart4));
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.ALL, searchKey1.matches(keyPart2));
+    
+      SearchKey searchKey2 = searchKey1.getWildcardInstance();
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.POSITIVE, searchKey2.matches(keyPart3));
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.NEGATIVE, searchKey2.matches(KeyPart.EMPTY_KEY_END));
+   }
+   
+   public void testEmptyPrefixPatternNegative1()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("anythinganExpression");
+      // bb
+      SearchKey searchKey = new SearchKey("any*.thing*anExpression");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testEmptyPrefixPatternNegative2()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("anyadsaafsa.asdthinganExpression");
+      // bb
+      SearchKey searchKey = new SearchKey("any*.thing*anExpression");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(keyPart));
+   }
+
+   public void testEmptyPrefixPatternNegative3()
+   {
+      // bb
+      SearchKey searchKey = new SearchKey("any*.thing*anExpression");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(KeyPart.EMPTY_KEY_END));
+   }
+
+   public void testEmptyPrefixPatternNegative4()
+   {
+      // bb
+      SearchKey searchKey = new SearchKey("any*.thing*anExpression");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(new KeyPart("")));
+   }
+   
+   public void testEmptySuffixPatternOneTarget1()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("apattern.that.has.Wildcards");
+      // bb
+      SearchKey searchKey = new SearchKey("a*pattern.that.*has.Wildcards");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testEmptySuffixPatternOneTarget2()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("apattern.that.anything.anyhas.Wildcards");
+      // bb
+      SearchKey searchKey = new SearchKey("a*pattern.that.*has.Wildcards");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testEmptySuffixPatternBrokenTarget1()
+   {
+      // aa
+      KeyPart keyPart3 = new KeyPart("apattern.that.anything.anyhas.Wildcards");
+      KeyPart keyPart2 = keyPart3.extractPrefixPart(2, 2);
+      KeyPart keyPart1 = keyPart2.extractPrefixPart(0, 0);
+      KeyPart keyPart5 = new KeyPart("banewpatternthathaswildcards");
+      keyPart1.newSuffix(keyPart5);
+      KeyPart keyPart4 = new KeyPart("ing.has.Xildcards");
+      keyPart2.newSuffix(keyPart4);
+      
+      // bb
+      
+      SearchKey searchKey = new SearchKey("a*pattern.that.*has.Wildcards");
+
+      assertEquals('a', searchKey.matches(keyPart1));
+      assertEquals(Flags.ALL, searchKey.matches(keyPart2));
+      
+      SearchKey searchKey1 = searchKey.getWildcardInstance();
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.POSITIVE, searchKey1.matches(keyPart3));
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.NEGATIVE, searchKey1.matches(keyPart4));
+   }
+   
+   public void testEmptySuffixPatternBrokenTarget2()
+   {
+      // aa
+      KeyPart keyPart3 = new KeyPart("apattern.that.anything.anyhas.Wildcards");
+      KeyPart keyPart2 = keyPart3.extractPrefixPart(2, 2);
+      KeyPart keyPart1 = keyPart2.extractPrefixPart(0, 0);
+      KeyPart keyPart5 = new KeyPart("banewpatternthathaswildcards");
+      keyPart1.newSuffix(keyPart5);
+      KeyPart keyPart4 = new KeyPart("ing.has.Wildcard");
+      keyPart2.newSuffix(keyPart4);
+      
+      // bb
+      
+      SearchKey searchKey = new SearchKey("a*pattern.that.*has.Wildcards");
+      
+      assertEquals('a', searchKey.matches(keyPart1));
+      assertEquals(Flags.ALL, searchKey.matches(keyPart2));
+      
+      SearchKey searchKey1 = searchKey.getWildcardInstance();
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.POSITIVE, searchKey1.matches(keyPart3));
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.NEGATIVE, searchKey1.matches(keyPart4));
+   }
+   
+   public void testEmptySuffixPatternBrokenTarget3()
+   {
+      // aa
+      KeyPart keyPart3 = new KeyPart("apattern.that.anything.anyhas.Wildcards");
+      KeyPart keyPart2 = keyPart3.extractPrefixPart(2, 2);
+      KeyPart keyPart1 = keyPart2.extractPrefixPart(0, 0);
+      KeyPart keyPart5 = new KeyPart("banewpatternthathaswildcards");
+      keyPart1.newSuffix(keyPart5);
+      KeyPart keyPart6 = new KeyPart("ing.has.Wildcardy");
+      keyPart2.newSuffix(keyPart6);
+      KeyPart keyPart4 = keyPart6.extractPrefixPart(2, 8);
+      KeyPart keyPart7 = new KeyPart("i");
+      keyPart4.newSuffix(keyPart7);
+      
+      // bb
+      
+      SearchKey searchKey = new SearchKey("a*pattern.that.*has.Wildcards");
+
+      assertEquals('a', searchKey.matches(keyPart1));
+      assertEquals(Flags.ALL, searchKey.matches(keyPart2));
+      
+      SearchKey searchKey1 = searchKey.getWildcardInstance();
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.POSITIVE, searchKey1.matches(keyPart3));
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals('s', searchKey1.matches(keyPart4));
+   }
+   
+   public void testEmptySuffixPatternBrokenTarget4()
+   {
+      // aa
+      KeyPart keyPart4 = new KeyPart("apattern.that.anyhas.Wildcards");
+      KeyPart keyPart3 = keyPart4.extractPrefixPart(2, 0);
+      KeyPart keyPart2 = keyPart3.extractPrefixPart(1, 1);
+      KeyPart keyPart1 = keyPart2.extractPrefixPart(0, 0);
+      KeyPart keyPart6 = new KeyPart("banewpatternthathaswildcards");
+      keyPart1.newSuffix(keyPart6);
+      KeyPart keyPart5 = new KeyPart("inghas.Wildcards");
+      keyPart3.newSuffix(keyPart5);
+      keyPart2.newSuffix(new KeyPart(""));
+      
+      // bb
+      
+      SearchKey searchKey = new SearchKey("a*pattern.that.*has.Wildcards");
+
+      assertEquals('a', searchKey.matches(keyPart1));
+      assertEquals('h', searchKey.matches(keyPart2));
+      assertEquals(Flags.ALL, searchKey.matches(keyPart3));
+      
+      SearchKey searchKey1 = searchKey.getWildcardInstance();
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.POSITIVE, searchKey1.matches(keyPart4));
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.POSITIVE, searchKey1.matches(keyPart5));
+   }
+   
+   public void testEmptySuffixPatternNegative1()
+   {
+      // bb
+      SearchKey searchKey = new SearchKey("a*pattern.that.*has.Wildcards");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(KeyPart.EMPTY_KEY_END));
+   }
+   
+   
+   public void testEmptySuffixPatternNegative2()
+   {
+      // bb
+      SearchKey searchKey = new SearchKey("a*pattern.that.*has.Wildcards");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(new KeyPart("")));
+   }
+   
+   public void testEmptySuffixPatternNegative3()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("only.three.elements");
+      keyPart = keyPart.extractPrefixPart(2, 1);
+      // bb
+      SearchKey searchKey = new SearchKey("a*pattern.that.*has.Wildcards");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(keyPart));
+   }
+
+   public void testEmptySuffixPatternNegative4()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("only.three.elements");
+      keyPart = keyPart.extractPrefixPart(2, 1);
+      keyPart.newSuffix(new KeyPart("s.i.x.ele.ment.s"));
+      // bb
+      SearchKey searchKey = new SearchKey("a*pattern.that.*has.Wildcards");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testEmptyPrefixSuffixPatternOneTarget1()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("aaa.empty.prefix.suffix.pattern.suffix");
+      // bb
+      SearchKey searchKey = new SearchKey(
+            "aaa*.empty.prefix.suffix.pattern.*suffix");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testEmptyPrefixSuffixPatternOneTarget2()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart(
+            "aaa.empty.prefix.suffix.pattern.abcsuffix");
+      // bb
+      SearchKey searchKey = new SearchKey(
+            "aaa*.empty.prefix.suffix.pattern.*suffix");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testEmptyPrefixSuffixPatternOneTarget3()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart(
+            "aaaabc.empty.prefix.suffix.pattern.abcsuffix");
+      // bb
+      SearchKey searchKey = new SearchKey(
+            "aaa*.empty.prefix.suffix.pattern.*suffix");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testEmptyPrefixSuffixPatternBrokenTarget1()
+   {
+      // aa
+      KeyPart keyPart9 = new KeyPart(
+            "aaaabc.empty.prefix.suffix.pattern.susuffix.suffixsuffix");
+      KeyPart keyPart8  = keyPart9.extractPrefixPart(6, 6);
+      KeyPart keyPart10 = new KeyPart("");
+      keyPart8.newSuffix(keyPart10);
+      KeyPart keyPart7 = keyPart8.extractPrefixPart(6, 0);
+      keyPart7.newSuffix(KeyPart.EMPTY_KEY_END);
+      KeyPart keyPart5 = keyPart7.extractPrefixPart(5, 2);
+      KeyPart keyPart6 = new KeyPart("ffix");
+      keyPart5.newSuffix(keyPart6);
+      KeyPart keyPart1 = keyPart5.extractPrefixPart(5, 1);
+      KeyPart keyPart2 = new KeyPart("affix");
+      keyPart1.newSuffix(keyPart2);
+      KeyPart keyPart3 = new KeyPart("");
+      keyPart1.newSuffix(keyPart3);
+      KeyPart keyPart4 = new KeyPart("abc");
+      keyPart1.newSuffix(keyPart4);
+      
+      // bb
+      
+      SearchKey searchKey = new SearchKey(
+            "aaa*.empty.prefix.suffix.pattern.*suffix");
+      
+      assertEquals(Flags.ALL, searchKey.matches(keyPart1));
+      
+      SearchKey searchKey1 = searchKey.getWildcardInstance();
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.NEGATIVE, searchKey1.matches(keyPart2));
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.NEGATIVE, searchKey1.matches(keyPart3));
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.NEGATIVE, searchKey1.matches(keyPart4));
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.ALL, searchKey1.matches(keyPart5));
+      
+      SearchKey searchKey2 = searchKey1.getWildcardInstance();
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.POSITIVE, searchKey2.matches(keyPart6));
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.ALL, searchKey2.matches(keyPart7));
+      
+      SearchKey searchKey3 = searchKey2.getWildcardInstance();
+      searchKey2.prepareWildcardInstance(searchKey3);
+      assertEquals(Flags.POSITIVE, searchKey3.matches(KeyPart.EMPTY_KEY_END));
+      searchKey2.prepareWildcardInstance(searchKey3);
+      assertEquals(Flags.ALL, searchKey3.matches(keyPart8));
+      
+      SearchKey searchKey4 = searchKey3.getWildcardInstance();
+      searchKey3.prepareWildcardInstance(searchKey4);
+      assertEquals(Flags.POSITIVE, searchKey4.matches(keyPart9));
+      searchKey3.prepareWildcardInstance(searchKey4);
+      assertEquals(Flags.POSITIVE, searchKey4.matches(keyPart10));
+   }
+   
+   public void testEmptyPrefixSuffixPatternBrokenTarget2()
+   {
+      // aa
+      KeyPart keyPart5 = new KeyPart(
+            "aaaabc.empty.prefix.suffix.pattern.suffix");
+      KeyPart keyPart3  = keyPart5.extractPrefixPart(4, 7);
+      KeyPart keyPart4 = new KeyPart("suffix");
+      keyPart3.newSuffix(keyPart4);
+      KeyPart keyPart1 = keyPart3.extractPrefixPart(2, 0);
+      KeyPart keyPart2 = new KeyPart("");
+      keyPart1.newSuffix(keyPart2);
+      // bb
+      SearchKey searchKey = new SearchKey(
+            "aaa*.empty.prefix.suffix.pattern.*suffix");
+      assertEquals('p', searchKey.matches(keyPart1));
+      assertEquals(KeyPart.KEY_ELEMENT_END, searchKey.matches(keyPart3));
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart5));
+   }
+   
+   public void testEmptyPrefixSuffixPatternNegative1()
+   {
+      // bb
+      SearchKey searchKey = new SearchKey(
+            "aaa*.empty.prefix.suffix.pattern.*suffix");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(KeyPart.EMPTY_KEY_END));
+   }
+   
+   public void testEmptyPrefixSuffixPatternNegative2()
+   {
+      // bb
+      SearchKey searchKey = new SearchKey(
+            "aaa*.empty.prefix.suffix.pattern.*suffix");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(new KeyPart("")));
+   }
+   
+   public void testEmptyPrefixSuffixPatternNegative3()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("aaaempty.prefix.suffix.patternsuffix");
+      // bb
+      SearchKey searchKey = new SearchKey(
+            "aaa*.empty.prefix.suffix.pattern.*suffix");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testEmptyPrefixSuffixPatternNegative4()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("aaaempty. empty.prefix.suffixempty." +
+            "empty.prefix.suffix.pattern.anysuffisuffisuffi");
+      // bb
+      SearchKey searchKey = new SearchKey(
+            "aaa*.empty.prefix.suffix.pattern.*suffix");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testDotPatternOneTarget1()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("abc.c");
+      // bb
+      SearchKey searchKey = new SearchKey("abc*.*c");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testDotPatternOneTarget2()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("abccccc.ccccc");
+      // bb
+      SearchKey searchKey = new SearchKey("abc*.*c");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testDotPatternOneTarget3()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("abc.cccc.ccccc");
+      // bb
+      SearchKey searchKey = new SearchKey("abc*.*.*c");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testDotPatternBrokenTarget1()
+   {
+      // aa
+      KeyPart keyPart2 = new KeyPart("abc.c");
+      KeyPart keyPart1 = keyPart2.extractPrefixPart(1, 0);
+      KeyPart keyPart3 = new KeyPart("anything.broken.into.lots.of.elements");
+      keyPart1.newSuffix(keyPart3);
+      KeyPart keyPart5 = new KeyPart(
+            "something.that.is.a.positive.match.for.sure.c");
+      KeyPart keyPart4 = keyPart5.extractPrefixPart(2, 1);
+      keyPart1.newSuffix(keyPart4);
+      KeyPart keyPart6 = new KeyPart("c");
+      KeyPart keyPart7 = new KeyPart("anything.ending.with.c");
+      KeyPart keyPart8 = new KeyPart("negative.match.for.sure");
+      keyPart4.newSuffix(keyPart6);
+      keyPart4.newSuffix(keyPart7);
+      keyPart4.newSuffix(keyPart8);
+      
+      // bb
+      
+      SearchKey searchKey = new SearchKey("abc*.*c");
+      
+      assertEquals(Flags.ALL, searchKey.matches(keyPart1));
+      
+      SearchKey searchKey1 = searchKey.getWildcardInstance();
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.POSITIVE, searchKey1.matches(keyPart2));
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.NEGATIVE, searchKey1.matches(keyPart3));
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.ALL, searchKey1.matches(keyPart4));
+      
+      SearchKey searchKey2 = searchKey1.getWildcardInstance();
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.POSITIVE, searchKey2.matches(keyPart5));
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.POSITIVE, searchKey2.matches(keyPart6));
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.POSITIVE, searchKey2.matches(keyPart7));
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.NEGATIVE, searchKey2.matches(keyPart8));
+   }
+   
+   public void testDotPatternBrokenTarget2()
+   {
+      // aa
+      KeyPart keyPart9 = new KeyPart("abc.c.c.ccccccc");
+      KeyPart keyPart8 = keyPart9.extractPrefixPart(3, 3);
+      KeyPart keyPart10 = new KeyPart("");
+      keyPart8.newSuffix(keyPart10);
+      KeyPart keyPart7 = keyPart8.extractPrefixPart(3, 0);
+      keyPart7.newSuffix(KeyPart.EMPTY_KEY_END);
+      KeyPart keyPart6 = keyPart7.extractPrefixPart(2, 0);
+      keyPart6.newSuffix(KeyPart.EMPTY_KEY_END);
+      KeyPart keyPart3 = keyPart6.extractPrefixPart(1, 1);
+      KeyPart keyPart4 = new KeyPart("abb.bb.b");
+      keyPart3.newSuffix(keyPart4);
+      KeyPart keyPart5 = new KeyPart("c");
+      keyPart3.newSuffix(keyPart5);
+      KeyPart keyPart1 = keyPart3.extractPrefixPart(0, 3);
+      KeyPart keyPart2 = new KeyPart("c");
+      keyPart1.newSuffix(keyPart2);
+      
+      // bb
+      
+      SearchKey searchKey = new SearchKey("abc*.*c");
+
+      assertEquals(Flags.ALL, searchKey.matches(keyPart1));
+      
+      SearchKey searchKey1 = searchKey.getWildcardInstance();
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.NEGATIVE, searchKey1.matches(keyPart2));
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.ALL, searchKey1.matches(keyPart3));
+      
+      SearchKey searchKey2 = searchKey1.getWildcardInstance();
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.NEGATIVE, searchKey2.matches(keyPart4));
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.POSITIVE, searchKey2.matches(keyPart5));
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.ALL, searchKey2.matches(keyPart6));
+      
+      SearchKey searchKey3 = searchKey2.getWildcardInstance();
+      searchKey2.prepareWildcardInstance(searchKey3);
+      assertEquals(Flags.POSITIVE, searchKey3.matches(KeyPart.EMPTY_KEY_END));
+      searchKey2.prepareWildcardInstance(searchKey3);
+      assertEquals(Flags.ALL, searchKey3.matches(keyPart7));
+      
+      SearchKey searchKey4 = searchKey3.getWildcardInstance();
+      searchKey3.prepareWildcardInstance(searchKey4);
+      assertEquals(Flags.POSITIVE, searchKey4.matches(KeyPart.EMPTY_KEY_END));
+      searchKey3.prepareWildcardInstance(searchKey4);
+      assertEquals(Flags.ALL, searchKey4.matches(keyPart8));
+
+      SearchKey searchKey5 = searchKey4.getWildcardInstance();
+      searchKey4.prepareWildcardInstance(searchKey5);
+      assertEquals(Flags.POSITIVE, searchKey5.matches(keyPart9));
+      searchKey4.prepareWildcardInstance(searchKey5);
+      assertEquals(Flags.POSITIVE, searchKey5.matches(keyPart10));
+   }
+   
+   public void testDotPatternNegative1()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("abcc");
+      // bb
+      SearchKey searchKey = new SearchKey("abc*.*c");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testDotPatternNegative2()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("");
+      // bb
+      SearchKey searchKey = new SearchKey("abc*.*c");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testDotPatternNegative3()
+   {
+      // bb
+      SearchKey searchKey = new SearchKey("abc*.*c");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(KeyPart.EMPTY_KEY_END));
+   }
+   
+   public void testDotPatternNegative4()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("abc.c.c.d");
+      // bb
+      SearchKey searchKey = new SearchKey("abc*.*c");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testDotPatternNegative5()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("abc.a");
+      // bb
+      SearchKey searchKey = new SearchKey("abc*.*c");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testCompletePatternOneTarget1()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("acomplete.pat.terncomps");
+      // bb
+      SearchKey searchKey = new SearchKey("a*complete.pat.terncomp*s");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testCompletePatternOneTarget2()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("a.complete.pat.terncomp.s");
+      // bb
+      SearchKey searchKey = new SearchKey("a*complete.pat.terncomp*s");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+
+   public void testCompletePatternOneTarget3()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("a.complete.pat.terncomp.s");
+      // bb
+      SearchKey searchKey = new SearchKey("a*complete.pat.terncomp*s");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+
+   public void testCompletePatternOneTarget4()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart(
+            "anythingcomplete.pat.terncomp.aabbbbbbbbbbbccccc.yes");
+      // bb
+      SearchKey searchKey = new SearchKey("a*complete.pat.terncomp*s");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+
+   
+   public void testCompletePatternBrokenTarget()
+   {
+      // aa
+      KeyPart keyPart8 = new KeyPart("anythingcomplete.pat.terncompycs");
+      KeyPart keyPart7 = keyPart8.extractPrefixPart(2, 10);
+      KeyPart keyPart10 = new KeyPart("omplete.pat.terncomplycs");
+      KeyPart keyPart9 = keyPart10.extractPrefixPart(1, 0);
+      keyPart7.newSuffix(keyPart9);
+      KeyPart keyPart11 = new KeyPart("comp.completepat.terncomplycs");
+      keyPart9.newSuffix(keyPart11);
+      KeyPart keyPart4 = keyPart7.extractPrefixPart(2, 8);
+      KeyPart keyPart5 = new KeyPart("lete.pat.terncompycatedddddddddddd.sos");
+      keyPart4.newSuffix(keyPart5);
+      KeyPart keyPart6 = new KeyPart("s");
+      keyPart4.newSuffix(keyPart6);
+      KeyPart keyPart1 = keyPart4.extractPrefixPart(1, 3);
+      KeyPart keyPart2 = new KeyPart("completepatterncompyc");
+      keyPart1.newSuffix(keyPart2);
+      KeyPart keyPart3 = new KeyPart(".complete.pat.terncompyc.suffixes");
+      keyPart1.newSuffix(keyPart3);
+      
+      // bb
+      
+      SearchKey searchKey = new SearchKey("a*complete.pat.terncompyc*s");
+
+      assertEquals(Flags.ALL, searchKey.matches(keyPart1));
+      
+      SearchKey searchKey1 = searchKey.getWildcardInstance();
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.NEGATIVE, searchKey1.matches(keyPart2));
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.POSITIVE, searchKey1.matches(keyPart3));
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.ALL, searchKey1.matches(keyPart4));
+      
+      SearchKey searchKey2 = searchKey1.getWildcardInstance();
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.POSITIVE, searchKey2.matches(keyPart5));
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.NEGATIVE, searchKey2.matches(keyPart6));
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.ALL, searchKey2.matches(keyPart7));
+      
+      SearchKey searchKey3 = searchKey2.getWildcardInstance();
+      searchKey2.prepareWildcardInstance(searchKey3);
+      assertEquals(Flags.POSITIVE, searchKey3.matches(keyPart8));
+      searchKey2.prepareWildcardInstance(searchKey3);
+      assertEquals(Flags.ALL, searchKey3.matches(keyPart9));
+      
+      SearchKey searchKey4 = searchKey3.getWildcardInstance();
+      searchKey3.prepareWildcardInstance(searchKey4);
+      assertEquals(Flags.POSITIVE, searchKey4.matches(keyPart10));
+      searchKey3.prepareWildcardInstance(searchKey4);
+      assertEquals(Flags.POSITIVE, searchKey4.matches(keyPart11));
+   }
+   
+   public void testCompletePatternNegative1()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("acomplete.patterns");
+      // bb
+      SearchKey searchKey = new SearchKey("a*complete.pat.tern*s");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testCompletePatternNegative2()
+   {
+      // bb
+      SearchKey searchKey = new SearchKey("a*complete.pat.tern*s");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(KeyPart.EMPTY_KEY_END));
+   }
+   
+   public void testCompletePatternNegative3()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("");
+      // bb
+      SearchKey searchKey = new SearchKey("a*complete.pat.tern*s");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testCompletePatternNegative4()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart(
+            "acomplete.pat.teerncomplete.pat.terncompys");
+      // bb
+      SearchKey searchKey = new SearchKey("a*complete.pat.terncompyc*s");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testDotPrefixOneTarget1()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("a.prefix.patternsuffix");
+      // bb
+      SearchKey searchKey = new SearchKey("a.prefix.*pattern*suffix");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testDotPrefixOneTarget2()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("a.prefix.patternaaaaaaaaaaaaasuffix");
+      // bb
+      SearchKey searchKey = new SearchKey("a.prefix.*pattern*suffix");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+
+   
+   public void testDotPrefixOneTarget3()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("a.prefix.patternaaaaaaaaaaaaa.suffix");
+      // bb
+      SearchKey searchKey = new SearchKey("a.prefix.*pattern*suffix");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+
+   public void testDotPrefixOneTarget4()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart(
+            "a.prefix.patternaaaaaaaaaaaaa.abac.suffix");
+      // bb
+      SearchKey searchKey = new SearchKey("a.prefix.*pattern*suffix");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testDotPrefixBrokenTarget()
+   {
+      // aa
+      KeyPart keyPart9 = new KeyPart("a.prefix.pattern.suffix");
+      KeyPart keyPart8 = keyPart9.extractPrefixPart(3, 3);
+      KeyPart keyPart10 = new KeyPart("suffix");
+      keyPart8.newSuffix(keyPart10);
+      KeyPart keyPart5 = keyPart8.extractPrefixPart(2, 6);
+      KeyPart keyPart6 = new KeyPart("pattern.aaaaa.suffix");
+      keyPart5.newSuffix(keyPart6);
+      KeyPart keyPart7 = new KeyPart("a_suffix");
+      keyPart5.newSuffix(keyPart7);
+      KeyPart keyPart3 = keyPart5.extractPrefixPart(1, 6);
+      KeyPart keyPart4 = new KeyPart("patternsuffix");
+      keyPart3.newSuffix(keyPart4);
+      KeyPart keyPart1 = keyPart3.extractPrefixPart(0, 0);
+      KeyPart keyPart2 = new KeyPart("something.different.from.search.key");
+      keyPart1.newSuffix(keyPart2);
+      
+      // bb
+      
+      SearchKey searchKey = new SearchKey("a.prefix.*pattern*suffix");
+
+      assertEquals('a', searchKey.matches(keyPart1));
+      assertEquals(KeyPart.KEY_ELEMENT_END, searchKey.matches(keyPart3));
+      assertEquals(Flags.ALL, searchKey.matches(keyPart5));
+      
+      SearchKey searchKey1 = searchKey.getWildcardInstance();
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.POSITIVE, searchKey1.matches(keyPart6));
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.NEGATIVE, searchKey1.matches(keyPart7));
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.ALL, searchKey1.matches(keyPart8));
+      
+      SearchKey searchKey2 = searchKey1.getWildcardInstance();
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.POSITIVE, searchKey2.matches(keyPart9));
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.POSITIVE, searchKey2.matches(keyPart10));
+   }
+   
+   public void testDotPrefixNegative1()
+   {
+      // bb
+      SearchKey searchKey = new SearchKey("a.prefix.*pattern*suffix");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(KeyPart.EMPTY_KEY_END));
+   }
+
+   public void testDotPrefixNegative2()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("");
+      // bb
+      SearchKey searchKey = new SearchKey("a.prefix.*pattern*suffix");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(keyPart));
+   }
+
+   public void testDotPrefixNegative3()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("a.prefix.patternsuffixa");
+      // bb
+      SearchKey searchKey = new SearchKey("a.prefix.*pattern*suffix");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testDotPrefixNegative4()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("a.prefixpatternsuffix");
+      // bb
+      SearchKey searchKey = new SearchKey("a.prefix.*pattern*suffix");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testCompletePrefixOneTarget1()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("complete.prefixpatternsuffix");
+      // bb
+      SearchKey searchKey = new SearchKey("complete.prefix*pattern*suffix");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testCompletePrefixOneTarget2()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("complete.prefix.pattern.suffix");
+      // bb
+      SearchKey searchKey = new SearchKey("complete.prefix*pattern*suffix");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testCompletePrefixOneTarget3()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart(
+            "complete.prefixabbbbbbcpatterpatternand.asuffix");
+      // bb
+      SearchKey searchKey = new SearchKey("complete.prefix*pattern*suffix");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testCompletePrefixBrokenTarget()
+   {
+      // aa
+      KeyPart keyPart11 = new KeyPart("complete.prefix.patter.suffix");
+      KeyPart keyPart6 = keyPart11.extractPrefixPart(2, 6);
+      KeyPart keyPart9 = new KeyPart("n.suffix");
+      KeyPart keyPart7 = keyPart9.extractPrefixPart(0, 1);
+      KeyPart keyPart8 = new KeyPart("suffix");
+      keyPart7.newSuffix(keyPart8);
+      keyPart6.newSuffix(keyPart7);
+      KeyPart keyPart10 = new KeyPart("abc.patternsuffix");
+      keyPart6.newSuffix(keyPart10);
+      KeyPart keyPart5 = keyPart6.extractPrefixPart(1, 2);
+      keyPart5.newSuffix(new KeyPart(""));
+      keyPart5.newSuffix(new KeyPart("prefix"));
+      KeyPart keyPart4 = keyPart5.extractPrefixPart(0, 8);
+      keyPart4.newSuffix(new KeyPart("prefixpatternsuffix"));
+      keyPart4.newSuffix(new KeyPart("s.prefixpatternsuffix"));
+      KeyPart keyPart3 = keyPart4.extractPrefixPart(0, 5);
+      keyPart3.newSuffix(new KeyPart("abc"));
+      keyPart3.newSuffix(new KeyPart("some.r.e.a.l.l.y.long.key"));
+      KeyPart keyPart1 = keyPart3.extractPrefixPart(0, 0);
+      KeyPart keyPart2 = new KeyPart("incomplete.prefix.pattern.suffix");
+      keyPart1.newSuffix(keyPart2);
+      
+      // bb
+      
+      SearchKey searchKey = new SearchKey("complete.prefix*pattern*suffix");
+
+      assertEquals('c', searchKey.matches(keyPart1));
+      assertEquals('e', searchKey.matches(keyPart3));
+      assertEquals(KeyPart.KEY_ELEMENT_END, searchKey.matches(keyPart4));
+      assertEquals('e', searchKey.matches(keyPart5));
+      assertEquals(Flags.ALL, searchKey.matches(keyPart6));
+      
+      SearchKey searchKey1 = searchKey.getWildcardInstance();
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.POSITIVE, searchKey1.matches(keyPart10));
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.NEGATIVE, searchKey1.matches(keyPart11));
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.ALL, searchKey1.matches(keyPart7));
+
+      SearchKey searchKey2 = searchKey1.getWildcardInstance();
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.POSITIVE, searchKey2.matches(keyPart8));
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.POSITIVE, searchKey2.matches(keyPart9));
+   }
+   
+   public void testCompletePrefixNegative1()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("complete.prefix.pattern.suffiX");
+      // bb
+      SearchKey searchKey = new SearchKey("complete.prefix*pattern*suffix");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testCompletePrefixNegative2()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("completeprefix.prefixpatternsuffix");
+      // bb
+      SearchKey searchKey = new SearchKey("complete.prefix*pattern*suffix");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testCompletePrefixNegative3()
+   {
+      // bb
+      SearchKey searchKey = new SearchKey("complete.prefix*pattern*suffix");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(KeyPart.EMPTY_KEY_END));
+   }
+
+   public void testCompletePrefixNegative4()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("");
+      // bb
+      SearchKey searchKey = new SearchKey("complete.prefix*pattern*suffix");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(keyPart));
+   }
+
+   public void testEmptyPrefixOneTarget1()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("patpatpatternsuffix");
+      // bb
+      SearchKey searchKey = new SearchKey("*patpatpattern*suffix");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+
+   public void testEmptyPrefixOneTarget2()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("anythingprecedingpatpatpatternsuffix");
+      // bb
+      SearchKey searchKey = new SearchKey("*patpatpattern*suffix");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+
+   public void testEmptyPrefixOneTarget3()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("anything.preceding.apatpatpattern.suffix");
+      // bb
+      SearchKey searchKey = new SearchKey("*patpatpattern*suffix");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+
+   public void testEmptyPrefixOneTarget4()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart(
+            "apatpatpatpat.patpatpattern.ending.with.somesuffix");
+      // bb
+      SearchKey searchKey = new SearchKey("*patpatpattern*suffix");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+
+   public void testEmptyPrefixBrokenTarget1()
+   {
+      // aa
+      KeyPart keyPart2 = new KeyPart("papatpatpatternsuffix");
+      KeyPart keyPart1 = keyPart2.extractPrefixPart(0, 6);
+      KeyPart keyPart3 = new KeyPart("pattern");
+      keyPart1.newSuffix(keyPart3);
+      
+      // bb
+      
+      SearchKey searchKey = new SearchKey("*patpatpattern*suffix");
+      
+      assertEquals(Flags.ALL, searchKey.matches(keyPart1));
+      
+      SearchKey searchKey1 = searchKey.getWildcardInstance();
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.POSITIVE, searchKey1.matches(keyPart2));
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.NEGATIVE, searchKey1.matches(keyPart3));
+   }
+
+   public void testEmptyPrefixBrokenTarget2()
+   {
+      // aa
+      KeyPart keyPart2 = new KeyPart("papatpatpatternsuffix");
+      KeyPart keyPart1 = keyPart2.extractPrefixPart(0, 4);
+      KeyPart keyPart7 = new KeyPart(
+            ".patpatpattern.something.anything.suffix");
+      KeyPart keyPart6 = keyPart7.extractPrefixPart(2, 1);
+      KeyPart keyPart8 = new KeyPart("uffix");
+      keyPart6.newSuffix(keyPart8);
+      KeyPart keyPart3 = keyPart6.extractPrefixPart(2, 0);
+      KeyPart keyPart5 = new KeyPart("abcd.fghij.klmnopqrsuffix");
+      keyPart3.newSuffix(keyPart5);
+      KeyPart keyPart4 = new KeyPart("negativesUfFiX");
+      keyPart3.newSuffix(keyPart4);
+      keyPart1.newSuffix(keyPart3);
+      
+      // bb
+      
+      SearchKey searchKey = new SearchKey("*patpatpattern*suffix");
+      
+      assertEquals(Flags.ALL, searchKey.matches(keyPart1));
+      
+      SearchKey searchKey1 = searchKey.getWildcardInstance();
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.POSITIVE, searchKey1.matches(keyPart2));
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.ALL, searchKey1.matches(keyPart3));
+      
+      SearchKey searchKey2 = searchKey1.getWildcardInstance();
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.NEGATIVE, searchKey2.matches(keyPart4));
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.POSITIVE, searchKey2.matches(keyPart5));
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.ALL, searchKey2.matches(keyPart6));
+      
+      SearchKey searchKey3 = searchKey2.getWildcardInstance();
+      searchKey2.prepareWildcardInstance(searchKey3);
+      assertEquals(Flags.POSITIVE, searchKey3.matches(keyPart7));
+      searchKey2.prepareWildcardInstance(searchKey3);
+      assertEquals(Flags.POSITIVE, searchKey3.matches(keyPart8));
+      searchKey2.prepareWildcardInstance(searchKey3);
+   }
+   
+   public void testEmptyPrefixNegative1()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("anything.preceding.apatpatpatterns.uffix");
+      // bb
+      SearchKey searchKey = new SearchKey("*patpatpattern*suffix");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testEmptyPrefixNegative2()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("anythingpreceding.apatpatterns.uffix");
+      // bb
+      SearchKey searchKey = new SearchKey("*patpatpattern*suffix");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testEmptyPrefixNegative3()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("patpatter.suffix");
+      // bb
+      SearchKey searchKey = new SearchKey("*patpatpattern*suffix");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testEmptyPrefixNegative4()
+   {
+      // bb
+      SearchKey searchKey = new SearchKey("*patpatpattern*suffix");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(KeyPart.EMPTY_KEY_END));
+   }
+
+   public void testEmptyPrefixNegative5()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("");
+      // bb
+      SearchKey searchKey = new SearchKey("*patpatpattern*suffix");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testDotSuffixOneTarget1()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("prefixpattern.suffix");
+      // bb
+      SearchKey searchKey = new SearchKey("prefix*pattern*.suffix");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testDotSuffixOneTarget2()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart(
+            "prefix.some.element.patternnnnnnnnnnnn.suffix");
+      // bb
+      SearchKey searchKey = new SearchKey("prefix*pattern*.suffix");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testDotSuffixOneTarget3()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart(
+            "prefix.pattern.some.elements.sssssssss.suffix");
+      // bb
+      SearchKey searchKey = new SearchKey("prefix*pattern*.suffix");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testDotSuffixBrokenTarget()
+   {
+      // aa
+      KeyPart keyPart9 = new KeyPart("prefixpattern.suffix");
+      KeyPart keyPart8 = keyPart9.extractPrefixPart(0, 13);
+      KeyPart keyPart10 = new KeyPart("suffix");
+      keyPart8.newSuffix(keyPart10);
+      KeyPart keyPart5 = keyPart8.extractPrefixPart(0, 9);
+      KeyPart keyPart6 = new KeyPart("pat.patterpattern.pattern.suffix");
+      keyPart5.newSuffix(keyPart6);
+      KeyPart keyPart7 = new KeyPart("");
+      keyPart5.newSuffix(keyPart7);
+      KeyPart keyPart3 = keyPart5.extractPrefixPart(0, 6);
+      KeyPart keyPart4 = new KeyPart(".patternsuffix");
+      keyPart3.newSuffix(keyPart4);
+      KeyPart keyPart1 = keyPart3.extractPrefixPart(0, 4);
+      KeyPart keyPart2 = new KeyPart("prefix");
+      keyPart1.newSuffix(keyPart2);
+
+      // bb
+      
+      SearchKey searchKey = new SearchKey("prefix*pattern*.suffix");
+      
+      assertEquals('i', searchKey.matches(keyPart1));
+      assertEquals(Flags.ALL, searchKey.matches(keyPart3));
+      
+      SearchKey searchKey1 = searchKey.getWildcardInstance();
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.NEGATIVE, searchKey1.matches(keyPart4));
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.ALL, searchKey1.matches(keyPart5));
+      
+      SearchKey searchKey2 = searchKey1.getWildcardInstance();
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.POSITIVE, searchKey2.matches(keyPart6));
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.NEGATIVE, searchKey2.matches(keyPart7));
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.ALL, searchKey2.matches(keyPart8));
+      
+      SearchKey searchKey3 = searchKey2.getWildcardInstance();
+      searchKey2.prepareWildcardInstance(searchKey3);
+      assertEquals(Flags.POSITIVE, searchKey3.matches(keyPart9));
+      searchKey2.prepareWildcardInstance(searchKey3);
+      assertEquals(Flags.NEGATIVE, searchKey3.matches(keyPart10));
+   }
+   
+   public void testDotSuffixOneNegative1()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("prefixpatternsuffix");
+      // bb
+      SearchKey searchKey = new SearchKey("prefix*pattern*.suffix");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(keyPart));
+   }
+
+   public void testDotSuffixOneNegative2()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart(
+            "prefix.patter.some.elements.sssssssss.suffix");
+      // bb
+      SearchKey searchKey = new SearchKey("prefix*pattern*.suffix");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(keyPart));
+   }
+
+   public void testDotSuffixOneNegative3()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("");
+      // bb
+      SearchKey searchKey = new SearchKey("prefix*pattern*.suffix");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(keyPart));
+   }
+
+   public void testDotSuffixOneNegative4()
+   {
+      // bb
+      SearchKey searchKey = new SearchKey("prefix*pattern*.suffix");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(KeyPart.EMPTY_KEY_END));
+   }
+   
+   public void testCompleteSuffixOneTarget1()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("prefixpatterna.complete.suffix");
+      // bb
+      SearchKey searchKey = new SearchKey("prefix*pattern*a.complete.suffix");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+
+   public void testCompleteSuffixOneTarget2()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("prefixpatterna.complete.suffix");
+      // bb
+      SearchKey searchKey = new SearchKey("prefix*patter*a.complete.suffix");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+
+   public void testCompleteSuffixOneTarget3()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart(
+         "prefix.someelements.pattern.moreelements.a.complete.suffix");
+      // bb
+      SearchKey searchKey = new SearchKey("prefix*pattern*a.complete.suffix");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+
+   public void testCompleteSuffixOneTarget4()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart(
+         "prefix.someelements.pattern.moreelementsa.complete.suffix");
+      // bb
+      SearchKey searchKey = new SearchKey("prefix*pattern*a.complete.suffix");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+
+   public void testCompleteSuffixOneTarget5()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart(
+         "prefix.somepattern.moreelements.a.ca.complete.suffix");
+      // bb
+      SearchKey searchKey = new SearchKey("prefix*pattern*a.complete.suffix");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+
+   public void testCompleteSuffixOneTarget6()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart(
+         "prefixes.somepattern.moreelements.a.ca.complete.suffix");
+      // bb
+      SearchKey searchKey = new SearchKey("prefix*pattern*a.complete.suffix");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testCompleteSuffixBrokenTarget1()
+   {
+      // aa
+      KeyPart keyPart11 = new KeyPart("prefix.patterna.complete.suffix");
+      KeyPart keyPart10 = keyPart11.extractPrefixPart(3, 4);
+      KeyPart keyPart12 = new KeyPart("abc");
+      keyPart10.newSuffix(keyPart12);
+      KeyPart keyPart8 = keyPart10.extractPrefixPart(2, 5);
+      KeyPart keyPart9 = new KeyPart("ate.suffix");
+      keyPart8.newSuffix(keyPart9);
+      KeyPart keyPart6 = keyPart8.extractPrefixPart(2, 0);
+      KeyPart keyPart7 = new KeyPart("acomplete.suffix");
+      keyPart6.newSuffix(keyPart7);
+      KeyPart keyPart4 = keyPart6.extractPrefixPart(1, 8);
+      KeyPart keyPart5 = new KeyPart("somethingelse.ending.withsuffix");
+      keyPart4.newSuffix(keyPart5);
+      KeyPart keyPart1 = keyPart4.extractPrefixPart(1, 7);
+      KeyPart keyPart2 = new KeyPart(".acompletea.complete.suffix");
+      keyPart1.newSuffix(keyPart2);
+      KeyPart keyPart3 = new KeyPart("b.complete.suffix");
+      
+      // bb
+      
+      SearchKey searchKey = new SearchKey("prefix*pattern*a.complete.suffix");
+      
+      assertEquals(Flags.ALL, searchKey.matches(keyPart1));
+      
+      SearchKey searchKey1 = searchKey.getWildcardInstance();
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.POSITIVE, searchKey1.matches(keyPart2));
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.NEGATIVE, searchKey1.matches(keyPart3));
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.ALL, searchKey1.matches(keyPart4));
+      
+      SearchKey searchKey2 = searchKey1.getWildcardInstance();
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.NEGATIVE, searchKey2.matches(keyPart5));
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals('c', searchKey2.matches(keyPart6));
+      assertEquals('e', searchKey2.matches(keyPart8));
+      assertEquals('i', searchKey2.matches(keyPart10));
+      assertEquals(Flags.POSITIVE, searchKey2.matches(keyPart11));
+   }
+   
+   public void testCompleteSuffixBrokenTarget2()
+   {
+      // aa
+      KeyPart keyPart11 = new KeyPart("prefix.patterna.complete.suffix");
+      KeyPart keyPart10 = keyPart11.extractPrefixPart(3, 2);
+      KeyPart keyPart12 = new KeyPart("afix");
+      keyPart10.newSuffix(keyPart12);
+      KeyPart keyPart8 = keyPart10.extractPrefixPart(3, 0);
+      KeyPart keyPart9 = new KeyPart("preffix");
+      keyPart8.newSuffix(keyPart9);
+      KeyPart keyPart6 = keyPart8.extractPrefixPart(1, 6);
+      KeyPart keyPart7 = new KeyPart("pattern.anyend.a.complete.suffix");
+      keyPart6.newSuffix(keyPart7);
+      KeyPart keyPart3 = keyPart6.extractPrefixPart(1, 0);
+      KeyPart keyPart4 = new KeyPart("prefixpattern.complete.suffix");
+      keyPart3.newSuffix(keyPart4);
+      KeyPart keyPart5 = new KeyPart("apatterna.complete.suffix");
+      keyPart3.newSuffix(keyPart5);
+      KeyPart keyPart1 = keyPart3.extractPrefixPart(0, 3);
+      KeyPart keyPart2 = new KeyPart(".acompletea.complete.suffix");
+      keyPart1.newSuffix(keyPart2);
+      
+      // bb
+      
+      SearchKey searchKey = new SearchKey("prefix*pattern*a.complete.suffix");
+      
+      assertEquals('f', searchKey.matches(keyPart1));
+      assertEquals(Flags.ALL, searchKey.matches(keyPart3));
+      
+      SearchKey searchKey1 = searchKey.getWildcardInstance();
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.NEGATIVE, searchKey1.matches(keyPart4));
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.POSITIVE, searchKey1.matches(keyPart5));
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.ALL, searchKey1.matches(keyPart6));
+      
+      SearchKey searchKey2 = searchKey1.getWildcardInstance();
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.POSITIVE, searchKey2.matches(keyPart7));
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals('s', searchKey2.matches(keyPart8));
+      assertEquals('f', searchKey2.matches(keyPart10));
+      assertEquals(Flags.POSITIVE, searchKey2.matches(keyPart11));
+   }
+   
+   public void testCompleteSuffixBrokenTarget3()
+   {
+      // aa
+      KeyPart keyPart12 = new KeyPart("prefix.pattern.very.long.key.filled." +
+            "with.several.different.elements.a.complete.suffix");
+      KeyPart keyPart11 = keyPart12.extractPrefixPart(9, 7);
+      KeyPart keyPart13 = new KeyPart(".diffa.complete.suffix");
+      keyPart11.newSuffix(keyPart13);
+      KeyPart keyPart9 = keyPart11.extractPrefixPart(8, 8);
+      KeyPart keyPart10 = new KeyPart("a.acomplete.a.complete.suffix");
+      keyPart9.newSuffix(keyPart10);
+      KeyPart keyPart7 = keyPart9.extractPrefixPart(6, 0);
+      KeyPart keyPart8 = new KeyPart("a.mismatch.suffix");
+      keyPart7.newSuffix(keyPart8);
+      KeyPart keyPart3 = keyPart7.extractPrefixPart(3, 1);
+      KeyPart keyPart4 = new KeyPart("loooooooooooooooooooong.key.longer.than" +
+            ".the.others.in.the.tree.but.still.ending.with.a.complete.suffix");
+      keyPart3.newSuffix(keyPart4);
+      KeyPart keyPart5 = new KeyPart("dont.think.this.key.will.take.you.to.a." +
+            "positive.match");
+      keyPart3.newSuffix(keyPart5);
+      KeyPart keyPart6 = new KeyPart("continuing.prefix.pattern.very.long." +
+            "key.ending.witha.complete.suffix");
+      keyPart3.newSuffix(keyPart6);
+      KeyPart keyPart1 = keyPart3.extractPrefixPart(0, 6);
+      KeyPart keyPart2 = new KeyPart("not.starting.with.prefix.nor.ending." +
+            "with.acomplete.suffix");
+      keyPart1.newSuffix(keyPart2);
+
+      // bb
+      SearchKey searchKey = new SearchKey("*a.complete.suffix");
+
+      assertEquals(Flags.ALL, searchKey.matches(keyPart1));
+      
+      SearchKey searchKey1 = searchKey.getWildcardInstance();
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.NEGATIVE, searchKey1.matches(keyPart2));
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.ALL, searchKey1.matches(keyPart3));
+      
+      SearchKey searchKey2 = searchKey1.getWildcardInstance();
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.POSITIVE, searchKey2.matches(keyPart4));
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.NEGATIVE, searchKey2.matches(keyPart5));
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.POSITIVE, searchKey2.matches(keyPart6));
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.ALL, searchKey2.matches(keyPart7));
+      
+      SearchKey searchKey3 = searchKey2.getWildcardInstance();
+      searchKey2.prepareWildcardInstance(searchKey3);
+      assertEquals(Flags.NEGATIVE, searchKey3.matches(keyPart8));
+      searchKey2.prepareWildcardInstance(searchKey3);
+      assertEquals(Flags.ALL, searchKey3.matches(keyPart9));
+      
+      SearchKey searchKey4 = searchKey3.getWildcardInstance();
+      searchKey3.prepareWildcardInstance(searchKey4);
+      assertEquals(Flags.POSITIVE, searchKey4.matches(keyPart10));
+      searchKey3.prepareWildcardInstance(searchKey4);
+      assertEquals(Flags.ALL, searchKey4.matches(keyPart11));
+      
+      SearchKey searchKey5 = searchKey4.getWildcardInstance();
+      searchKey4.prepareWildcardInstance(searchKey5);
+      assertEquals(Flags.POSITIVE, searchKey5.matches(keyPart12));
+      searchKey4.prepareWildcardInstance(searchKey5);
+      assertEquals(Flags.POSITIVE, searchKey5.matches(keyPart13));
+   }
+   
+   public void testCompleteSuffixNegative1()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("prefixpattera.complete.suffix");
+      // bb
+      SearchKey searchKey = new SearchKey("prefix*pattern*a.complete.suffix");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testCompleteSuffixNegative2()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("prefixpatternacomplete.suffix");
+      // bb
+      SearchKey searchKey = new SearchKey("prefix*pattern*a.complete.suffix");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testCompleteSuffixNegative3()
+   {
+      // bb
+      SearchKey searchKey = new SearchKey("prefix*pattern*a.complete.suffix");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(KeyPart.EMPTY_KEY_END));
+   }
+   
+   public void testCompleteSuffixNegative4()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("");
+      // bb
+      SearchKey searchKey = new SearchKey("prefix*pattern*a.complete.suffix");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testEmptySuffixOneTarget1()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("prefixpattern");
+      // bb
+      SearchKey searchKey = new SearchKey("prefix*pattern*");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testEmptySuffixOneTarget2()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("prefixpatternsuffix");
+      // bb
+      SearchKey searchKey = new SearchKey("prefix*pattern*");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testEmptySuffixOneTarget3()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("prefixes.somepatterns.any.suffix");
+      // bb
+      SearchKey searchKey = new SearchKey("prefix*pattern*");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+
+   public void testEmptySuffixOneTarget4()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("prefixes.somepatterns");
+      // bb
+      SearchKey searchKey = new SearchKey("prefix*pattern*");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testEmptySuffixBrokenTarget()
+   {
+      // aa
+      KeyPart keyPart10 = new KeyPart("prefixpattern");
+      KeyPart keyPart11 = new KeyPart("suffix");
+      keyPart10.newSuffix(keyPart11);
+      KeyPart keyPart7 = keyPart10.extractPrefixPart(0, 13);
+      KeyPart keyPart8 = new KeyPart("some.suffix");
+      keyPart7.newSuffix(keyPart8);
+      KeyPart keyPart9 = new KeyPart("anysuffix");
+      keyPart7.newSuffix(keyPart9);
+      KeyPart keyPart4 = keyPart7.extractPrefixPart(0, 9);
+      KeyPart keyPart5 = new KeyPart("pattern");
+      keyPart4.newSuffix(keyPart5);
+      KeyPart keyPart6 = new KeyPart(".anypatternendingwithanything");
+      keyPart4.newSuffix(keyPart6);
+      KeyPart keyPart1 = keyPart4.extractPrefixPart(0, 0);
+      KeyPart keyPart2 = new KeyPart("a.negative.match.key.part");
+      keyPart1.newSuffix(keyPart2);
+      KeyPart keyPart3 = new KeyPart("another.negativematch");
+      keyPart1.newSuffix(keyPart3);
+      
+      // bb
+      
+      SearchKey searchKey = new SearchKey("prefix*pattern*");
+
+      assertEquals('p', searchKey.matches(keyPart1));
+      assertEquals(Flags.ALL, searchKey.matches(keyPart4));
+      
+      SearchKey searchKey1 = searchKey.getWildcardInstance();
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.POSITIVE, searchKey1.matches(keyPart5));
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.POSITIVE, searchKey1.matches(keyPart6));
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.ALL, searchKey1.matches(keyPart7));
+
+      SearchKey searchKey2 = searchKey1.getWildcardInstance();
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.POSITIVE, searchKey2.matches(keyPart8));
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.POSITIVE, searchKey2.matches(keyPart9));
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.ALL, searchKey2.matches(keyPart10));
+      
+      SearchKey searchKey3 = searchKey2.getWildcardInstance();
+      searchKey2.prepareWildcardInstance(searchKey3);
+      assertEquals(Flags.POSITIVE, searchKey3.matches(KeyPart.EMPTY_KEY_END));
+      searchKey2.prepareWildcardInstance(searchKey3);
+      assertEquals(Flags.POSITIVE, searchKey3.matches(keyPart11));
+   }
+   
+   public void testEmptySuffixNegative1()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("prefixsuffix");
+      // bb
+      SearchKey searchKey = new SearchKey("prefix*pattern*");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testEmptySuffixNegative2()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("prefixpatter.n");
+      // bb
+      SearchKey searchKey = new SearchKey("prefix*pattern*");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(keyPart));
+   }
+
+   public void testEmptySuffixNegative3()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("prefipattern");
+      // bb
+      SearchKey searchKey = new SearchKey("prefix*pattern*");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(keyPart));
+   }
+
+   public void testEmptySuffixNegative4()
+   {
+      // bb
+      SearchKey searchKey = new SearchKey("prefix*pattern*");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(KeyPart.EMPTY_KEY_END));
+   }
+   
+   public void testEmptySuffixNegative5()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("");
+      // bb
+      SearchKey searchKey = new SearchKey("prefix*pattern*");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testCompleteExpressionOneTarget1()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart(
+         "pre.fi.xpa.tt.er.n1pa.tt.er.n2pa.tt.er.n3suf.fi.x");
+      // bb
+      SearchKey searchKey = new SearchKey(
+            "pre.fi.x*pa.tt.er.n1*pa.tt.er.n2*pa.tt.er.n3*suf.fi.x");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testCompleteExpressionOneTarget2()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart(
+         "pre.fi.x.pa.tt.er.n1.pa.tt.er.n2.pa.tt.er.n3.suf.fi.x");
+      // bb
+      SearchKey searchKey = new SearchKey(
+         "pre.fi.x*pa.tt.er.n1*pa.tt.er.n2*pa.tt.er.n3*suf.fi.x");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testCompleteExpressionOneTarget3()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("pre.fi.xsss.sss.sssspa.tt.er.n1sss.ssss." +
+            "sssspa.tt.er.n2ssss.ssss.sssspa.tt.er.n3ssss.ssss.sssssuf.fi.x");
+      // bb
+      SearchKey searchKey = new SearchKey(
+         "pre.fi.x*pa.tt.er.n1*pa.tt.er.n2*pa.tt.er.n3*suf.fi.x");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testCompleteExpressionOneTarget4()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart(
+         "pre.fi.xabcdpa.tt.er.n1abcdpa.tt.er.n2abcdpa.tt.er.n3abcdsuf.fi.x");
+      // bb
+      SearchKey searchKey = new SearchKey(
+         "pre.fi.x*pa.tt.er.n1*pa.tt.er.n2*pa.tt.er.n3*suf.fi.x");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testCompleteExpressionBrokenTarget()
+   {
+      // aa
+      KeyPart keyPart53 = new KeyPart(
+         "pre.fi.xpa.tt.er.n1pa.tt.er.n2pa.tt.er.n3suf.fi.x");
+      KeyPart keyPart52 = keyPart53.extractPrefixPart(13, 0);
+      keyPart52.newSuffix(new KeyPart("a"));
+      keyPart52.newSuffix(new KeyPart("S"));
+      keyPart52.newSuffix(new KeyPart("w"));
+      keyPart52.newSuffix(new KeyPart("k"));
+      keyPart52.newSuffix(new KeyPart("Q"));
+      KeyPart keyPart51 = keyPart52.extractPrefixPart(12, 1);
+      keyPart51.newSuffix(new KeyPart("a.b"));
+      keyPart51.newSuffix(new KeyPart("c.d"));
+      keyPart51.newSuffix(new KeyPart("e.f"));
+      KeyPart keyPart50 = keyPart51.extractPrefixPart(11, 0);
+      keyPart50.newSuffix(new KeyPart("somea.bc.e"));
+      keyPart50.newSuffix(new KeyPart("fghij.kl.m"));
+      keyPart50.newSuffix(new KeyPart("opqrs.tu.v"));
+      KeyPart keyPart49 = keyPart50.extractPrefixPart(9, 0);
+      keyPart49.newSuffix(new KeyPart("ab.cd.efghi.jk.l"));
+      keyPart49.newSuffix(new KeyPart("mn.op.qrstu.vw.x"));
+      KeyPart keyPart48 = keyPart49.extractPrefixPart(7, 0);
+      keyPart48.newSuffix(new KeyPart("ab.cdef.gh.ij.klmno.pq.r"));
+      keyPart48.newSuffix(new KeyPart("st.uvwx.yz.ab.cdefg.hi.j"));
+      KeyPart keyPart47 = keyPart48.extractPrefixPart(5, 3);
+      keyPart47.newSuffix(new KeyPart("b.cd.ef.ghij.kl.mn.opqrs.tu.v"));
+      keyPart47.newSuffix(new KeyPart("w.xy.za.bcde.fg.hi.jklmn.op.q"));
+      KeyPart keyPart44 = keyPart47.extractPrefixPart(5, 1);
+      KeyPart keyPart45 = new KeyPart("2pa.tt.er.n1pa.tt.er.n3suf.fi.x");
+      keyPart44.newSuffix(keyPart45);
+      KeyPart keyPart46 = new KeyPart(
+            "3papapa.tt.er.npa.tt.er.n1pa.tt.er.n2pa.tt.er.n3suf.fi.x");
+      keyPart44.newSuffix(keyPart46);
+      
+      KeyPart keyPart4 = keyPart44.extractPrefixPart(2, 1);
+      KeyPart keyPart6 = new KeyPart(
+            ".pa.tt.pa.tt.er.n1pa.tt.er.n2pa.tt.er.n3suf.fi.x");
+      KeyPart keyPart5 = keyPart6.extractPrefixPart(1, 0);
+      keyPart5.newSuffix(KeyPart.EMPTY_KEY_END);
+
+      keyPart4.newSuffix(keyPart5);
+      
+      KeyPart keyPart43 = new KeyPart(
+            "something.pa.tt.er.n1.pa.tt.er.n2.pa.tt.er.n3.suf.fi.x");
+      KeyPart keyPart42 = keyPart43.extractPrefixPart(15, 0);
+      keyPart42.newSuffix(new KeyPart("b"));
+      keyPart42.newSuffix(new KeyPart("defgh"));
+      keyPart42.newSuffix(new KeyPart("zap"));
+      KeyPart keyPart41 = keyPart42.extractPrefixPart(14, 1);
+      keyPart41.newSuffix(new KeyPart("a.b"));
+      keyPart41.newSuffix(new KeyPart("defgh.hijkl"));
+      KeyPart keyPart37 = keyPart41.extractPrefixPart(13, 2);
+      KeyPart keyPart38 = new KeyPart("abcdefgh.abc.abc");
+      keyPart37.newSuffix(keyPart38);
+      KeyPart keyPart39 = new KeyPart("hello.worl.d");
+      keyPart37.newSuffix(keyPart39);
+      KeyPart keyPart40 = new KeyPart("s.ome.thing");
+      keyPart37.newSuffix(keyPart40);
+      KeyPart keyPart34 = keyPart37.extractPrefixPart(9, 1);
+      KeyPart keyPart35 = new KeyPart("pa.tt.er.n3suf.fi.x");
+      keyPart34.newSuffix(keyPart35);
+      KeyPart keyPart36 = new KeyPart("cdefghij.pa.tt.er.n3suf.fix");
+      keyPart34.newSuffix(keyPart36);
+      KeyPart keyPart33 = keyPart34.extractPrefixPart(1, 0);
+      keyPart33.newSuffix(KeyPart.EMPTY_KEY_END);
+      
+      keyPart4.newSuffix(keyPart33);
+      
+      KeyPart keyPart32 = new KeyPart("apapapa.pa.tt.erpa.tt.er.n1papaapa.tt." +
+            "er.n2.pa.tt.er.nn.pa.tt.er.n3suf.fi.x");
+      KeyPart keyPart29 = keyPart32.extractPrefixPart(17, 1);
+      KeyPart keyPart30 = new KeyPart("1pa.tt.er.n3.sue.suf.fi.x");
+      keyPart29.newSuffix(keyPart30);
+      KeyPart keyPart31 = new KeyPart("2.suf.fi.x");
+      keyPart29.newSuffix(keyPart31);
+      KeyPart keyPart25 = keyPart29.extractPrefixPart(15, 0);
+      KeyPart keyPart26 = new KeyPart("pa.tt.er.n3suf.fi.x");
+      keyPart26.newSuffix(KeyPart.EMPTY_KEY_END);
+      KeyPart keyPart27 = new KeyPart("");
+      keyPart26.newSuffix(keyPart27);
+      KeyPart keyPart28 = new KeyPart("abc");
+      keyPart26.newSuffix(keyPart28);
+      keyPart25.newSuffix(keyPart26);
+      KeyPart keyPart23 = keyPart25.extractPrefixPart(13, 1);
+      KeyPart keyPart24 = new KeyPart("3suf.fi.x");
+      keyPart23.newSuffix(keyPart24);
+      KeyPart keyPart19 = keyPart23.extractPrefixPart(10, 2);
+      KeyPart keyPart22 = new KeyPart("pa.tt.er.n3.abababa.suf.fi.x");
+      KeyPart keyPart20 = keyPart22.extractPrefixPart(3, 2);
+      KeyPart keyPart21 = new KeyPart("suf.ab.c");
+      keyPart20.newSuffix(keyPart21);
+      keyPart19.newSuffix(keyPart20);
+      KeyPart keyPart17 = keyPart19.extractPrefixPart(6, 4);
+      KeyPart keyPart18 = new KeyPart(".tt.er.n2ABC.pa.tt.er.n3.ABCsuf.fi.x");
+      keyPart17.newSuffix(keyPart18);
+      KeyPart keyPart13 = keyPart17.extractPrefixPart(4, 0);
+      KeyPart keyPart14 = new KeyPart("er.n1.pa.tt.er.n2.pa.tt.er.n3.suf.fi.x");
+      keyPart13.newSuffix(keyPart14);
+      KeyPart keyPart15 = new KeyPart(
+            "pa.tt.er.n1.pa.tt.er.n2.pa.tt.er.n3suf.fi.x");
+      keyPart13.newSuffix(keyPart15);
+      KeyPart keyPart16 = new KeyPart("minimal.length.mismatch");
+      keyPart13.newSuffix(keyPart16);
+      KeyPart keyPart11 = keyPart13.extractPrefixPart(0, 5);
+      KeyPart keyPart12 = new KeyPart(
+            ".tt.er.n1.pa.tt.er.n2pa.tt.er.n3.suf.fi.x");
+      keyPart11.newSuffix(keyPart12);
+      KeyPart keyPart10 = keyPart11.extractPrefixPart(0, 3);
+      keyPart10.newSuffix(keyPart12);
+      KeyPart keyPart7 = keyPart10.extractPrefixPart(0, 2);
+      KeyPart keyPart9 = new KeyPart(
+            ".pa.tt.er.n1pa.tt.er.n2pa.tt.er.n3.suf.fi.x");
+      keyPart7.newSuffix(keyPart9);
+      KeyPart keyPart8 = new KeyPart("apa.tt.er.n2.pa.tt.er.n3.suf.fi.x");
+      keyPart7.newSuffix(keyPart8);
+      
+      keyPart4.newSuffix(keyPart7);
+      
+      KeyPart keyPart3 = keyPart4.extractPrefixPart(1, 2);
+      keyPart3.newSuffix(new KeyPart("anything.el.se"));
+      KeyPart keyPart2 = keyPart3.extractPrefixPart(0, 2);
+      keyPart2.newSuffix(new KeyPart(
+            "fi.xpa.tt.er.n1pa.tt.er.n2pa.tt.er.n3suf.fi.x"));
+      KeyPart keyPart1 = keyPart2.extractPrefixPart(0, 0);
+      keyPart1.newSuffix(new KeyPart("abc.def.ghi.jkl.mno.pqr.stu.vwx.yz"));
+      keyPart1.newSuffix(new KeyPart("short.key"));
+      keyPart1.newSuffix(new KeyPart("zyx.wvu.tsr.qpo.nml.kji.hgf.edc.ab"));
+      
+      // bb
+      
+      SearchKey searchKey = new SearchKey(
+         "pre.fi.x*pa.tt.er.n1*pa.tt.er.n2*pa.tt.er.n3*suf.fi.x");
+      
+      assertEquals('p', searchKey.matches(keyPart1));
+      assertEquals('e', searchKey.matches(keyPart2));
+      assertEquals(KeyPart.KEY_ELEMENT_END, searchKey.matches(keyPart3));
+      assertEquals(Flags.ALL, searchKey.matches(keyPart4));
+      
+      SearchKey searchKey1 = searchKey.getWildcardInstance();
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.ALL, searchKey1.matches(keyPart5));
+      
+      SearchKey searchKey2 = searchKey1.getWildcardInstance();
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.POSITIVE, searchKey2.matches(keyPart6));
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.NEGATIVE, searchKey2.matches(KeyPart.EMPTY_KEY_END));
+      
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.ALL, searchKey1.matches(keyPart7));
+      
+      searchKey2 = searchKey1.getWildcardInstance();
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.NEGATIVE, searchKey2.matches(keyPart8));
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.POSITIVE, searchKey2.matches(keyPart9));
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.ALL, searchKey2.matches(keyPart10));
+      
+      SearchKey searchKey4 = searchKey2.getWildcardInstance();
+      searchKey2.prepareWildcardInstance(searchKey4);
+      assertEquals(Flags.POSITIVE, searchKey4.matches(keyPart12));
+      searchKey2.prepareWildcardInstance(searchKey4);
+      assertEquals(Flags.ALL, searchKey4.matches(keyPart11));
+
+      SearchKey searchKey5 = searchKey4.getWildcardInstance();
+      searchKey4.prepareWildcardInstance(searchKey5);
+      assertEquals(Flags.POSITIVE, searchKey5.matches(keyPart12));
+      searchKey4.prepareWildcardInstance(searchKey5);
+      assertEquals(Flags.ALL, searchKey5.matches(keyPart13));
+      
+      SearchKey searchKey6 = searchKey5.getWildcardInstance();
+      searchKey5.prepareWildcardInstance(searchKey6);
+      assertEquals(Flags.NEGATIVE, searchKey6.matches(keyPart14));
+      searchKey5.prepareWildcardInstance(searchKey6);
+      assertEquals(Flags.POSITIVE, searchKey6.matches(keyPart15));
+      searchKey5.prepareWildcardInstance(searchKey6);
+      assertEquals(Flags.NEGATIVE, searchKey6.matches(keyPart16));
+      searchKey5.prepareWildcardInstance(searchKey6);
+      assertEquals(Flags.ALL, searchKey6.matches(keyPart17));
+      
+      SearchKey searchKey7 = searchKey6.getWildcardInstance();
+      searchKey6.prepareWildcardInstance(searchKey7);
+      assertEquals(Flags.POSITIVE, searchKey7.matches(keyPart18));
+      searchKey6.prepareWildcardInstance(searchKey7);
+      assertEquals(Flags.ALL, searchKey7.matches(keyPart19));
+      
+      SearchKey searchKey8 = searchKey7.getWildcardInstance();
+      searchKey7.prepareWildcardInstance(searchKey8);
+      assertEquals(Flags.ALL, searchKey8.matches(keyPart20));
+      
+      SearchKey searchKey9 = searchKey8.getWildcardInstance();
+      searchKey8.prepareWildcardInstance(searchKey9);
+      assertEquals(Flags.NEGATIVE, searchKey9.matches(keyPart21));
+      searchKey8.prepareWildcardInstance(searchKey9);
+      assertEquals(Flags.POSITIVE, searchKey9.matches(keyPart22));
+      
+      searchKey7.prepareWildcardInstance(searchKey8);
+      assertEquals(Flags.ALL, searchKey8.matches(keyPart23));
+      
+      searchKey9 = searchKey8.getWildcardInstance();
+      searchKey8.prepareWildcardInstance(searchKey9);
+      assertEquals(Flags.POSITIVE, searchKey9.matches(keyPart24));
+      searchKey8.prepareWildcardInstance(searchKey9);
+      assertEquals(Flags.ALL, searchKey9.matches(keyPart25));
+      
+      SearchKey searchKey10 = searchKey9.getWildcardInstance();
+      searchKey9.prepareWildcardInstance(searchKey10);
+      assertEquals(Flags.ALL, searchKey10.matches(keyPart26));
+      
+      SearchKey searchKey11 = searchKey10.getWildcardInstance();
+      searchKey10.prepareWildcardInstance(searchKey11);
+      assertEquals(Flags.POSITIVE, searchKey11.matches(KeyPart.EMPTY_KEY_END));
+      searchKey10.prepareWildcardInstance(searchKey11);
+      assertEquals(Flags.NEGATIVE, searchKey11.matches(keyPart27));
+      searchKey10.prepareWildcardInstance(searchKey11);
+      assertEquals(Flags.NEGATIVE, searchKey11.matches(keyPart28));
+
+      searchKey9.prepareWildcardInstance(searchKey10);
+      assertEquals(Flags.ALL, searchKey10.matches(keyPart29));
+
+      searchKey11 = searchKey10.getWildcardInstance();
+      searchKey10.prepareWildcardInstance(searchKey11);
+      assertEquals(Flags.POSITIVE, searchKey11.matches(keyPart30));
+      searchKey10.prepareWildcardInstance(searchKey11);
+      assertEquals(Flags.NEGATIVE, searchKey11.matches(keyPart31));
+      searchKey10.prepareWildcardInstance(searchKey11);
+      assertEquals(Flags.POSITIVE, searchKey11.matches(keyPart32));
+      
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.ALL, searchKey1.matches(keyPart33));
+      
+      searchKey2 = searchKey1.getWildcardInstance();
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.NEGATIVE, searchKey2.matches(KeyPart.EMPTY_KEY_END));
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.ALL, searchKey2.matches(keyPart34));
+
+      
+      searchKey4 = searchKey2.getWildcardInstance();
+      searchKey2.prepareWildcardInstance(searchKey4);
+      assertEquals(Flags.POSITIVE, searchKey4.matches(keyPart35));
+      searchKey2.prepareWildcardInstance(searchKey4);
+      assertEquals(Flags.NEGATIVE, searchKey4.matches(keyPart36));
+      searchKey2.prepareWildcardInstance(searchKey4);
+      assertEquals(Flags.ALL, searchKey4.matches(keyPart37));
+      
+      searchKey5 = searchKey4.getWildcardInstance();
+      searchKey4.prepareWildcardInstance(searchKey5);
+      assertEquals(Flags.NEGATIVE, searchKey5.matches(keyPart38));
+      searchKey4.prepareWildcardInstance(searchKey5);
+      assertEquals(Flags.NEGATIVE, searchKey5.matches(keyPart39));
+      searchKey4.prepareWildcardInstance(searchKey5);
+      assertEquals(Flags.NEGATIVE, searchKey5.matches(keyPart40));
+      searchKey4.prepareWildcardInstance(searchKey5);
+      assertEquals('i', searchKey5.matches(keyPart41));
+      assertEquals('x', searchKey5.matches(keyPart42));
+      assertEquals(Flags.POSITIVE, searchKey5.matches(keyPart43));
+      
+      searchKey1 = searchKey.getWildcardInstance();
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.ALL, searchKey1.matches(keyPart44));
+      
+      searchKey2 = searchKey1.getWildcardInstance();
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.NEGATIVE, searchKey2.matches(keyPart45));
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.POSITIVE, searchKey2.matches(keyPart46));
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals('a', searchKey2.matches(keyPart47));
+      assertEquals('e', searchKey2.matches(keyPart48));
+      assertEquals('t', searchKey2.matches(keyPart49));
+      assertEquals('n', searchKey2.matches(keyPart50));
+      assertEquals('i', searchKey2.matches(keyPart51));
+      assertEquals('x', searchKey2.matches(keyPart52));
+      assertEquals(Flags.POSITIVE, searchKey2.matches(keyPart53));
+   }
+   
+   public void testCompleteExpressionNegative1()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("prefixpattern1pattern2pattern3suffix");
+      // bb
+      SearchKey searchKey = new SearchKey(
+         "pre.fi.x*pa.tt.er.n1*pa.tt.er.n2*pa.tt.er.n3*suf.fi.x");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(keyPart));
+   }
+
+   public void testCompleteExpressionNegative2()
+   {
+      // bb
+      SearchKey searchKey = new SearchKey(
+         "pre.fi.x*pa.tt.er.n1*pa.tt.er.n2*pa.tt.er.n3*suf.fi.x");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(KeyPart.EMPTY_KEY_END));
+   }
+
+   public void testCompleteExpressionNegative3()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("");
+      // bb
+      SearchKey searchKey = new SearchKey(
+         "pre.fi.x*pa.tt.er.n1*pa.tt.er.n2*pa.tt.er.n3*suf.fi.x");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testWildcardOneTarget1()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("anything");
+      // bb
+      SearchKey searchKey = new SearchKey("*");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testWildcardOneTarget2()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("somethingelse");
+      // bb
+      SearchKey searchKey = new SearchKey("*");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testWildcardOneTarget3()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("a");
+      // bb
+      SearchKey searchKey = new SearchKey("*");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testWildcardOneTarget4()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("more.than.one.element");
+      // bb
+      SearchKey searchKey = new SearchKey("*");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testWildcardOneTarget5()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("two.elements");
+      // bb
+      SearchKey searchKey = new SearchKey("*");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+
+   public void testWildcardOneTarget6()
+   {
+      // aa
+      KeyPart keyPart = new KeyPart("");
+      // bb
+      SearchKey searchKey = new SearchKey("*");
+      assertEquals(Flags.POSITIVE, searchKey.matches(keyPart));
+   }
+   
+   public void testWildcardBrokenTarget()
+   {
+      // aa
+      KeyPart keyPart10 = new KeyPart(
+            "abcd.efgh.abcd.efgh.ijklm.nopqrst.uvwxyz");
+      KeyPart keyPart7 = keyPart10.extractPrefixPart(5, 5);
+      KeyPart keyPart8 = new KeyPart("");
+      keyPart7.newSuffix(keyPart8);
+      KeyPart keyPart9 = new KeyPart("a.b.c");
+      keyPart7.newSuffix(keyPart9);
+      KeyPart keyPart4 = keyPart7.extractPrefixPart(3, 0);
+      keyPart4.newSuffix(KeyPart.EMPTY_KEY_END);
+      KeyPart keyPart5 = new KeyPart(
+            "a.really.re.a.lly.long.k.e.y.longer.than.the.others");
+      keyPart4.newSuffix(keyPart5);
+      KeyPart keyPart6 = new KeyPart("x");
+      keyPart4.newSuffix(keyPart6);
+      KeyPart keyPart1 = keyPart4.extractPrefixPart(0, 0);
+      KeyPart keyPart2 = new KeyPart("different.key");
+      keyPart1.newSuffix(keyPart2);
+      KeyPart keyPart3 = new KeyPart("uvw.x.y.z");
+      keyPart1.newSuffix(keyPart3);
+
+      // bb
+      
+      SearchKey searchKey = new SearchKey("*");
+      
+      assertEquals(Flags.ALL, searchKey.matches(keyPart1));
+      
+      SearchKey searchKey1 = searchKey.getWildcardInstance();
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.POSITIVE, searchKey1.matches(keyPart2));
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.POSITIVE, searchKey1.matches(keyPart3));
+      searchKey.prepareWildcardInstance(searchKey1);
+      assertEquals(Flags.ALL, searchKey1.matches(keyPart4));
+      
+      SearchKey searchKey2 = searchKey1.getWildcardInstance();
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.POSITIVE, searchKey2.matches(KeyPart.EMPTY_KEY_END));
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.POSITIVE, searchKey2.matches(keyPart5));
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.POSITIVE, searchKey2.matches(keyPart6));
+      searchKey1.prepareWildcardInstance(searchKey2);
+      assertEquals(Flags.ALL, searchKey2.matches(keyPart7));
+      
+      
+      SearchKey searchKey3 = searchKey2.getWildcardInstance();
+      searchKey2.prepareWildcardInstance(searchKey3);
+      assertEquals(Flags.POSITIVE, searchKey3.matches(keyPart8));
+      searchKey2.prepareWildcardInstance(searchKey3);
+      assertEquals(Flags.POSITIVE, searchKey3.matches(keyPart9));
+      searchKey2.prepareWildcardInstance(searchKey3);
+      assertEquals(Flags.POSITIVE, searchKey3.matches(keyPart10));
+   }
+   
+   public void testWildcardNegative()
+   {
+      // bb
+      SearchKey searchKey = new SearchKey("*");
+      assertEquals(Flags.NEGATIVE, searchKey.matches(KeyPart.EMPTY_KEY_END));
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/common/AllTests.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/common/AllTests.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/common/AllTests.java	2008-01-03 18:54:24 UTC (rev 68603)
@@ -0,0 +1,45 @@
+/*
+ * 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 junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * Test suite that contains all test cases of this package.
+ * 
+ * @author Flavia Rainone
+ */
+public class AllTests
+{
+
+   public static Test suite()
+   {
+      TestSuite suite = new TestSuite(
+            "Test for org.jboss.aop.joinpoint.graph.tree.search.common");
+      //$JUnit-BEGIN$
+      suite.addTestSuite(PrefixFunctionImplTest.class);
+      suite.addTestSuite(PrefixFunctionLoaderTest.class);
+      //$JUnit-END$
+      return suite;
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/common/PrefixFunctionImplTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/common/PrefixFunctionImplTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/common/PrefixFunctionImplTest.java	2008-01-03 18:54:24 UTC (rev 68603)
@@ -0,0 +1,379 @@
+/*
+ * 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.common.PrefixFunctionImpl;
+import org.jboss.aop.joinpoint.graph.tree.search.common.PrefixFunctionLoader;
+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.KeyPartIndex;
+
+import junit.framework.TestCase;
+
+/**
+ * Test of the {@link PrefixFunctionImpl} class.
+ * 
+ * @author Flavia Rainone
+ */
+public class PrefixFunctionImplTest extends TestCase
+{
+   private int[] zeroValue;
+   
+   public void setUp()
+   {
+      zeroValue = new int[] {0,0};
+   }
+   
+   public void testEmpty()
+   {
+      String[] pattern = new String[] {""};
+      int[][][] expected = new int[][][] {
+            new int[][] {zeroValue},
+            new int[][] {zeroValue}
+      };
+      assertPrefixFunction(pattern, expected);
+   }
+   
+   public void testOneElement()
+   {
+      String[] pattern = new String[] {"ababaabcab"};
+      int[][][] expected = new int[][][] {
+            new int[][] {zeroValue, zeroValue, zeroValue, new int[] {0, 1},
+                  new int[] {0, 2}, new int[] {0, 3}, new int[] {0, 1},
+                  new int[] {0, 2}, zeroValue, new int[] {0, 1},
+                  new int[] {0, 2}},
+           new int[][] {zeroValue}
+      };
+      assertPrefixFunction(pattern, expected);
+   }
+   
+   public void testRepeatSameElement1()
+   {
+      String[] pattern = new String[] {"blabla", "blabla", "blabla"};
+      int[][][] expected = new int[][][] {
+            new int[][] {zeroValue, zeroValue, zeroValue, zeroValue,
+                  new int[] {0, 1}, new int[] {0, 2}, new int[] {0, 3}},
+            new int[][] {zeroValue, new int[] {0, 1}, new int[] {0, 2},
+                  new int[] {0, 3}, new int[] {0, 4}, new int[] {0, 5},
+                  new int[] {0, 6}},
+            new int[][] {new int[] {1, 0}, new int[] {1, 1}, new int[] {1, 2},
+                  new int[] {1, 3}, new int[] {1, 4}, new int[] {1, 5},
+                  new int[] {1, 6}},
+            new int[][] { new int[] {2, 0}}
+      };
+      assertPrefixFunction(pattern, expected);
+   }
+   
+   public void testRepeatSameElement2()
+   {
+      String[] pattern = new String[] {"ababaabcab", "ababaabcab", "ababaabcab",
+            "ababaabcab"};
+      int[][][] expected = new int[][][] {
+            new int[][] {zeroValue, zeroValue, zeroValue, new int[] {0, 1},
+                  new int[] {0, 2}, new int[] {0, 3}, new int[] {0, 1},
+                  new int[] {0, 2}, zeroValue, new int[] {0, 1},
+                  new int[] {0, 2}},
+            new int[][] {zeroValue, new int[] {0, 1}, new int[] {0, 2},
+                  new int[] {0, 3}, new int[] {0, 4}, new int[] {0, 5},
+                  new int[] {0, 6}, new int[] {0, 7}, new int[] {0, 8},
+                  new int[] {0, 9}, new int[] {0, 10}},
+            new int[][] {new int[] {1, 0}, new int[] {1, 1},
+                  new int[] {1, 2}, new int[] {1, 3}, new int[] {1, 4},
+                  new int[] {1, 5}, new int[] {1, 6}, new int[] {1, 7},
+                  new int[] {1, 8}, new int[] {1, 9}, new int[] {1, 10}},
+            new int[][] {new int[] {2, 0}, new int[] {2, 1},
+                        new int[] {2, 2}, new int[] {2, 3}, new int[] {2, 4},
+                        new int[] {2, 5}, new int[] {2, 6}, new int[] {2, 7},
+                        new int[] {2, 8}, new int[] {2, 9}, new int[] {2, 10}},
+            new int[][] {new int[] {3, 0}}
+            
+      };
+      assertPrefixFunction(pattern, expected);
+   }
+   
+   public void testRepeatDifferentElements1()
+   {
+      String[] pattern = new String[] {"aaa", "bb", "aaa", "bb", "aaa", "aaa",
+            "bb", "c", "aaa", "bb"};
+      int[][][] expected = new int[][][] {
+            new int[][] {zeroValue, zeroValue, new int[] {0, 1},
+                  new int[] {0, 2}},
+            new int[][] {zeroValue, zeroValue, zeroValue},
+            new int[][] {zeroValue, new int[] {0, 1}, new int[] {0, 2},
+                  new int[] {0, 3}},
+            new int[][] {new int[] {1, 0}, new int[] {1, 1}, new int[] {1, 2}},
+            new int[][] {new int[] {2, 0}, new int[] {2, 1}, new int[] {2, 2},
+                  new int[] {2, 3}},
+            new int[][] {new int[] {3, 0}, new int[] {0, 1}, new int[] {0, 2},
+                  new int[] {0, 3}},
+            new int[][] {new int[] {1, 0}, new int[] {1, 1}, new int[] {1, 2}},
+            new int[][] {new int[] {2, 0}, zeroValue},
+            new int[][] {zeroValue, new int[] {0, 1}, new int[] {0, 2},
+                  new int[] {0, 3}},
+            new int[][] {new int[] {1, 0}, new int[] {1, 1}, new int[] {1, 2}},
+            new int[][] {new int[] {2, 0}}
+      };
+      assertPrefixFunction(pattern, expected);
+   }
+   
+   public void testRepeatDifferentElements()
+   {
+      String[] pattern = new String[] {"ab", "aba"};
+      int[][][] expected = new int[][][] {
+            new int[][] {zeroValue, zeroValue, zeroValue},
+            new int[][] {zeroValue, new int[] {0, 1}, new int[] {0, 2}, new int[] {0, 1}},
+            new int[][] {zeroValue}
+      };
+      assertPrefixFunction(pattern, expected);
+   }
+   
+   public void testRepeatDifferentElements2()
+   {
+      String[] pattern = new String[] {"abcd", "aba", "abcd", "abcd"};
+      int[][][] expected = new int[][][] {
+            // element 0
+            new int[][] {zeroValue, zeroValue, zeroValue, zeroValue, zeroValue},
+            // element 1
+            new int[][] {zeroValue, new int[] {0, 1}, new int[] {0, 2},
+                  new int[] {0, 1}},
+            // element 2
+            new int[][] {zeroValue, new int[] {0, 1}, new int[] {0, 2},
+                  new int[] {0, 3}, new int[] {0, 4}},
+            // element 3
+            new int[][] {new int[] {1, 0},  new int[] {1, 1}, new int[] {1, 2},
+                  new int[] {0, 3}, new int[] {0, 4}},
+            // end
+            new int[][] {new int[] {1, 0}}
+      };
+      assertPrefixFunction(pattern, expected);
+   }
+   
+   public void testCommonCase1()
+   {
+      String[] pattern = new String[] {"my", "package", "Class", "get"};
+      int[][][] expected = new int[][][] {
+            new int[][] {zeroValue, zeroValue, zeroValue},
+            new int[][] {zeroValue, zeroValue, zeroValue, zeroValue, zeroValue,
+                  zeroValue, zeroValue, zeroValue},
+            new int[][] {zeroValue, zeroValue, zeroValue, zeroValue, zeroValue,
+                  zeroValue},
+            new int[][] {zeroValue, zeroValue, zeroValue, zeroValue},
+            new int[][] {zeroValue}
+      };
+      assertPrefixFunction(pattern, expected);
+   }
+   
+   public void testCommonCase2()
+   {
+      String[] pattern = new String[] {"package", "Class", "put"};
+      int[][][] expected = new int[][][] {
+            new int[][] {zeroValue, zeroValue, zeroValue, zeroValue, zeroValue,
+                  zeroValue, zeroValue, zeroValue},
+            new int[][] {zeroValue, zeroValue, zeroValue, zeroValue, zeroValue,
+                  zeroValue},
+            new int[][] {zeroValue, new int[] {0, 1}, zeroValue, zeroValue},
+            new int[][] {zeroValue}
+      };
+      assertPrefixFunction(pattern, expected);
+   }
+   
+   public void testCommonCase3()
+   {
+      String[] pattern = new String[] {"some", "some", "Pattern"};
+      int[][][] expected = new int[][][] {
+            // element 0
+            new int[][] {zeroValue, zeroValue, zeroValue, zeroValue, zeroValue},
+            // element 1
+            new int[][] {zeroValue, new int[] {0, 1}, new int[] {0, 2},
+                  new int[] {0, 3}, new int[] {0, 4}},
+            // element 2
+            new int[][] {new int[] {1, 0}, zeroValue, zeroValue, zeroValue,
+                  zeroValue, zeroValue, zeroValue, zeroValue},
+            new int[][] {zeroValue}
+      };
+      assertPrefixFunction(pattern, expected);
+   }
+   
+   public void testCommonCase4()
+   {
+      String[] pattern = new String[] {"some", "Class1", "some", "Class"};
+      int[][][] expected = new int[][][] {
+            // element 0
+            new int[][] {zeroValue, zeroValue, zeroValue, zeroValue, zeroValue},
+            // element 1
+            new int[][] {zeroValue, zeroValue, zeroValue, zeroValue,
+                  new int[] {0, 1}, new int[] {0, 1}, zeroValue},
+            // element 2
+            new int[][] {zeroValue, new int[] {0, 1}, new int[] {0, 2},
+                  new int[] {0, 3}, new int[] {0, 4}},
+            // element 3
+            new int[][] {new int[] {1, 0}, new int[] {1, 1}, new int[] {1, 2},
+                  new int[] {1, 3}, new int[] {1, 4}, new int[] {1, 5}},
+            new int[][] {zeroValue}
+      };
+      assertPrefixFunction(pattern, expected);
+   }
+   
+   public void testFirstEmpty1()
+   {
+      String[] pattern = new String[] {"", "anything"};
+      int[][][]  expected = new int[][][] {
+            new int[][] {zeroValue},
+            new int[][] {zeroValue, zeroValue, zeroValue, zeroValue, zeroValue,
+                  zeroValue, zeroValue, zeroValue, zeroValue},
+            new int[][] {new int[] {1, 0}}
+      };
+      assertPrefixFunction(pattern, expected);
+   }
+
+   public void testFirstEmpty2()
+   {
+      String[] pattern = new String[] {"", "any", "thing"};
+      int[][][]  expected = new int[][][] {
+            new int[][] {zeroValue},
+            new int[][] {zeroValue, zeroValue, zeroValue, zeroValue},
+            new int[][] {new int[] {1, 0}, zeroValue, zeroValue, zeroValue,
+                  zeroValue, zeroValue},
+            new int[][] {new int[] {1, 0}}
+      };
+      assertPrefixFunction(pattern, expected);
+   }
+
+   public void testLastEmpty1()
+   {
+      String[] pattern = new String[] {"anything", ""};
+      int[][][]  expected = new int[][][] {
+            new int[][] {zeroValue, zeroValue, zeroValue, zeroValue,
+                  zeroValue, zeroValue, zeroValue, zeroValue, zeroValue},
+            new int[][] {zeroValue},
+            new int[][] {zeroValue}
+      };
+      assertPrefixFunction(pattern, expected);
+   }
+   
+   public void testLastEmpty2()
+   {
+      String[] pattern = new String[] {"anything", "anb", ""};
+      int[][][]  expected = new int[][][] {
+            new int[][] {zeroValue, zeroValue, zeroValue, zeroValue,
+                  zeroValue, zeroValue, zeroValue, zeroValue, zeroValue},
+            new int[][] {zeroValue, new int[] {0, 1}, new int[] {0, 2},
+                  zeroValue},
+            new int[][] {zeroValue},
+            new int[][] {zeroValue}
+      };
+      assertPrefixFunction(pattern, expected);
+   }
+   
+   public void testFirstLastEmpty1()
+   {
+      String[] pattern = new String[] {"", ""};
+      int[][][]  expected = new int[][][] {
+            new int[][] {zeroValue},
+            new int[][] {zeroValue},
+            new int[][] {new int[] {1, 0}}
+      };
+      assertPrefixFunction(pattern, expected);
+   }
+
+   public void testFirstLastEmpty2()
+   {
+      String[] pattern = new String[] {"", "abc", ""};
+      int[][][]  expected = new int[][][] {
+            new int[][] {zeroValue},
+            new int[][] {zeroValue, zeroValue, zeroValue, zeroValue},
+            new int[][] {new int[] {1, 0}},
+            new int[][] {new int[] {1, 0}}
+      };
+      assertPrefixFunction(pattern, expected);
+   }
+
+   public void testFirstLastEmpty3()
+   {
+      String[] pattern = new String[] {"", "abc", "any", "abddd", "abc", ""};
+      int[][][]  expected = new int[][][] {
+            new int[][] {zeroValue},
+            new int[][] {zeroValue, zeroValue, zeroValue, zeroValue},
+            new int[][] {new int[] {1, 0}, new int[] {1, 1}, zeroValue,
+               zeroValue},
+            new int[][] {new int[] {1, 0}, new int[] {1, 1}, new int[] {1, 2},
+               zeroValue, zeroValue, zeroValue},
+            new int[][] {new int[] {1, 0}, new int[] {1, 1}, new int[] {1, 2},
+               new int[] {1,3}},
+            new int[][] {new int[] {2, 0}},
+            new int[][] {new int[] {1, 0}}
+      };
+      assertPrefixFunction(pattern, expected);
+   }
+   
+   public void assertPrefixFunction(String[] patternElements,
+         int[][][] expected)
+   {
+      assertNull(loadFunction(MatcherProfile.SIMPLE, patternElements));
+      assertNull(loadFunction(MatcherProfile.PREFIX, patternElements));
+      PrefixFunction patternPrefixFunction = loadFunction(
+            MatcherProfile.PATTERN, patternElements);
+      PrefixFunction suffixPrefixFunction = loadFunction(MatcherProfile.SUFFIX,
+            patternElements);
+      int j = 0;
+      for (int i = 0; i < patternElements.length; i++)
+      {
+         for (j = 0; j <= patternElements[i].length(); j++)
+         {
+            assertExpectedPrefixFunction(patternPrefixFunction, expected[i][j], i, j);
+            assertExpectedPrefixFunction(suffixPrefixFunction, expected[i][j], i, j);
+         }
+      }
+      assertExpectedPrefixFunction(patternPrefixFunction,
+            expected[patternElements.length - 1][j - 1], patternElements.length, 0);
+      assertExpectedPrefixFunction(suffixPrefixFunction,
+            expected[patternElements.length][0], patternElements.length, 0);
+   }
+   
+   private void assertExpectedPrefixFunction(PrefixFunction prefixFunction,
+         int[] expected, int i, int j)
+   {
+      KeyPartIndex index = new KeyPartIndex();
+      index.applyPrefixFunction(i);
+      index.getElementIndex().applyPrefixFunction(j);
+      prefixFunction.applyTo(index);
+      assertEquals("Wrong expected [" + i + "][" + j + "] key part index:",
+            expected[0], index.getValue());
+      assertEquals("Wrong expected [" + i + "][" + j + "] element index:",
+            expected[1], index.getElementIndex().getValue());
+   }
+   
+   private PrefixFunctionImpl loadFunction(MatcherProfile profile,
+         String patternElements[])
+   {
+      PrefixFunctionLoader loader = PrefixFunctionLoader.
+         getLoaderForProfile(profile);
+      assertSame(loader, PrefixFunctionLoader.getCurrentLoader());
+      loader.prepareForLoading();
+      for (int i = 0; i < patternElements.length; i++)
+      {
+         loader.loadElement(patternElements[i]);
+      }
+      loader.loaded();
+      return (PrefixFunctionImpl) loader.getLoadedFunction();
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/common/PrefixFunctionLoaderTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/common/PrefixFunctionLoaderTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/common/PrefixFunctionLoaderTest.java	2008-01-03 18:54:24 UTC (rev 68603)
@@ -0,0 +1,132 @@
+/*
+ * 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.common.PrefixFunctionLoader;
+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.KeyPartIndex;
+
+import junit.framework.TestCase;
+
+/**
+ * Test of the {@link PrefixFunctionLoader} class.
+ * 
+ * @author Flavia Rainone
+ */
+public class PrefixFunctionLoaderTest extends TestCase
+{
+   public void testGetCurrentLoader()
+   {
+      PrefixFunctionLoader loader = PrefixFunctionLoader.getLoaderForProfile(
+            MatcherProfile.SIMPLE);
+      assertSame(loader, PrefixFunctionLoader.getCurrentLoader());
+      loader = PrefixFunctionLoader.getLoaderForProfile(MatcherProfile.PREFIX);
+      assertSame(loader, PrefixFunctionLoader.getCurrentLoader());
+      loader = PrefixFunctionLoader.getLoaderForProfile(MatcherProfile.PATTERN);
+      assertSame(loader, PrefixFunctionLoader.getCurrentLoader());
+      loader = PrefixFunctionLoader.getLoaderForProfile(MatcherProfile.SUFFIX);
+      assertSame(loader, PrefixFunctionLoader.getCurrentLoader());
+   }
+   
+   public void testLoaderForSimpleProfile()
+   {
+      PrefixFunction prefixFunction = assertPrefixFunctionLoading(
+            MatcherProfile.SIMPLE);
+      assertNull(prefixFunction);
+   }
+
+   public void testLoaderForPrefixProfile()
+   {
+      PrefixFunction prefixFunction = assertPrefixFunctionLoading(
+            MatcherProfile.PREFIX);
+      assertNull(prefixFunction);
+   }
+   
+   public void testLoaderForPatternProfile()
+   {
+      this.assertLoader(MatcherProfile.PATTERN, 0, 2);
+   }
+
+   public void testLoaderForSuffixProfile()
+   {
+      this.assertLoader(MatcherProfile.PATTERN, 0, 2);
+   }
+   
+   /**
+    * Loads the elements: <code>"ababc"</code>, <code>"abac"</code> and <code>
+    * "abdab"</code> and asserts the prefix function returned by the element
+    * loading methods.
+    * 
+    * @param profile the profile to which the prefix function will be loaded
+    * @return the loaded prefix function
+    */
+   public PrefixFunction assertPrefixFunctionLoading(MatcherProfile profile)
+   {
+      PrefixFunctionLoader loader = PrefixFunctionLoader.getLoaderForProfile(
+            profile);
+      loader.prepareForLoading();
+      PrefixFunction function = loader.loadElement("abac");
+      assertSame(loader.loadElement("abac"), function);
+      assertSame(loader.loadElement("abdab"), function);
+      loader.loaded();
+      assertSame(loader.getLoadedFunction(), function);
+      return function;
+   }
+   
+   /**
+    * Asserts the pattern loader operations.
+    * 
+    * @param profile                the profile associated with the prefix
+    *                               function loader that will be tested 
+    * @param patternEndPartValue    the expected pattern end part value
+    * @param patternEndElementValue the expected pattern end element value
+    */
+   public void assertLoader(MatcherProfile profile, int patternEndPartValue, 
+         int patternEndElementValue)
+   {
+      PrefixFunction function = assertPrefixFunctionLoading(profile);
+      assertNotNull(function);
+      KeyPartIndex index = new KeyPartIndex();
+      // test function for 0, 3
+      index.getElementIndex().increment(3);
+      function.applyTo(index);
+      assertEquals(0, index.getValue());
+      assertEquals(1, index.getElementIndex().getValue());
+      // test function for 2, 0
+      index.increment(2);
+      function.applyTo(index);
+      assertEquals(1, index.getValue());
+      assertEquals(0, index.getElementIndex().getValue());
+      // test function for 2, 2
+      index.increment();
+      index.getElementIndex().increment(2);
+      function.applyTo(index);
+      assertEquals(1, index.getValue());
+      assertEquals(2, index.getElementIndex().getValue());
+      // test function for 3, 0, the pattern end
+      index.increment(2);
+      function.applyTo(index);
+      assertEquals(patternEndPartValue, index.getValue());
+      assertEquals(patternEndElementValue, index.getElementIndex().getValue());
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/element/AllTests.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/element/AllTests.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/element/AllTests.java	2008-01-03 18:54:24 UTC (rev 68603)
@@ -0,0 +1,45 @@
+/*
+ * 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 junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * Test suite that contains all test cases of this package.
+ * 
+ * @author Flavia Rainone
+ */
+public class AllTests
+{
+
+   public static Test suite()
+   {
+      TestSuite suite = new TestSuite(
+            "Test for org.jboss.aop.joinpoint.graph.tree.search.element");
+      //$JUnit-BEGIN$
+      suite.addTestSuite(ComparableElementFactoryTest.class);
+      suite.addTestSuite(ComparableElementTest.class);
+      //$JUnit-END$
+      return suite;
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/element/ComparableElementFactoryTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/element/ComparableElementFactoryTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/element/ComparableElementFactoryTest.java	2008-01-03 18:54:24 UTC (rev 68603)
@@ -0,0 +1,117 @@
+/*
+ * 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.element.ComparableElement;
+import org.jboss.aop.joinpoint.graph.tree.search.element.ComparableElementFactory;
+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.MatcherProfile;
+
+import junit.framework.TestCase;
+
+/**
+ * Test of the {@link ComparableElementFactory} class.
+ * 
+ * @author Flavia Rainone
+ */
+public class ComparableElementFactoryTest extends TestCase
+{
+   ComparableElementFactory factory;
+   
+   public void setUp()
+   {
+      factory = ComparableElementFactory.getInstance();
+   }
+   
+   public void testSeparator()
+   {
+      assertEquals('.', factory.getSeparator());
+   }
+   
+   public void testCreation()
+   {
+      factory.performCreationForProfile(MatcherProfile.SIMPLE);
+      factory.startCreation();
+      ComparableElement comparable = (ComparableElement)
+         factory.create("someExpression", null);
+      assertNotNull(comparable);
+      // checks if the created comparable behaves as expected
+      assertSame(ComparisonResult.BOTH_ENDS, comparable.compare(
+            "someExpression", new Index(), new Index(), null));
+      assertSame(ComparisonResult.MISMATCH_FOUND, comparable.compare(
+            "differentExpression", new Index(), new Index(), null));
+      factory.stopCreation();
+   }
+   
+   public void testCreationForSimpleProfile()
+   {
+      assertLoadedPrefixFunction(MatcherProfile.SIMPLE, true);
+   }
+
+   public void testCreationForPrefixProfile()
+   {
+      assertLoadedPrefixFunction(MatcherProfile.PREFIX, true);
+   }
+   
+   public void testCreationForPatternProfile()
+   {
+      assertLoadedPrefixFunction(MatcherProfile.PATTERN, false);
+   }
+   
+   public void testCreationForSuffixProfile()
+   {
+      assertLoadedPrefixFunction(MatcherProfile.SUFFIX, false);
+   }
+   
+   /**
+    * Creates a sequence of comparable elements for the <code>profile</code>,
+    * and asserts the loaded prefix function as null or not null.
+    * 
+    * @param profile      the profile of the key part matcher that will contain
+    *                     the created comparable elements
+    * @param nullExpected indicates if the loaded prefix function is expected to
+    *                     be null or not.
+    */
+   public void assertLoadedPrefixFunction(MatcherProfile profile,
+         boolean nullExpected)
+   {
+      factory.performCreationForProfile(profile);
+      factory.startCreation();
+      for (int i = 0; i < 10; i++)
+      {
+         factory.create("someExpression", null);
+      }
+      factory.stopCreation();
+      if (nullExpected)
+      {
+         assertNull("Not null prefix function",
+               PrefixFunctionLoader.getCurrentLoader().getLoadedFunction());
+      }
+      else
+      {
+         assertNotNull("Null prefix function",
+               PrefixFunctionLoader.getCurrentLoader().getLoadedFunction());
+      }
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/element/ComparableElementTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/element/ComparableElementTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/element/ComparableElementTest.java	2008-01-03 18:54:24 UTC (rev 68603)
@@ -0,0 +1,229 @@
+/*
+ * 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.common.PrefixFunctionLoader;
+import org.jboss.aop.joinpoint.graph.tree.search.element.ComparableElement;
+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.MatcherProfile;
+
+import junit.framework.TestCase;
+
+/**
+ * Test of the {@link ComparableElement} class.
+ * 
+ * @author Flavia Rainone
+ */
+public class ComparableElementTest extends TestCase
+{
+   String expression;
+   ComparableElement element;
+   Index comparableIndex;
+   Index targetIndex;
+ 
+   public void setUp()
+   {
+      expression = "myExpression";
+      element = new ComparableElement(expression,
+            PrefixFunctionLoader.getLoaderForProfile(MatcherProfile.SIMPLE));
+      comparableIndex = new Index();
+      targetIndex = new Index();
+   }
+   
+   /**
+    * Tests the getNextCharacter method.
+    */
+   public void testNextCharacter()
+   {
+      LengthRange zeroRange = new LengthRange((byte) 0, (byte) 0);
+      for (int i = 0; i < 12; i++)
+      {
+         char expected = expression.charAt(i);
+         assertEquals(expected, element.getNextCharacter(comparableIndex,
+               null));
+         assertEquals(expected, element.getNextCharacter(comparableIndex, "",
+               zeroRange, null));
+         comparableIndex.increment();
+      }
+      assertEquals(KeyPart.KEY_ELEMENT_END,
+            element.getNextCharacter(comparableIndex, null));
+      assertEquals(KeyPart.KEY_ELEMENT_END,
+            element.getNextCharacter(comparableIndex, "", zeroRange, null));
+   }
+   
+   /**
+    * Tests comparison against an empty element.
+    */
+   public void testEmptyExpression()
+   {
+      ComparisonResult result = element.compare("", targetIndex,
+            comparableIndex, null);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, targetIndex.getValue());
+   }
+   
+   /**
+    * Tests comparison against the element itself.
+    */
+   public void testSameExpression()
+   {
+      ComparisonResult result = element.compare(expression, targetIndex,
+            comparableIndex, null);
+      assertSame(ComparisonResult.BOTH_ENDS, result);
+   }
+   
+   /**
+    * Tests comparison against a different element.
+    */
+   public void testDifferentExpression()
+   {
+      ComparisonResult result = element.compare("anotherExpression",
+            targetIndex, comparableIndex, null);
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      
+   }
+   
+   /**
+    * Tests comparison against an element with the same prefix as the 
+    * comparable element, but with different ending.
+    */
+   public void testSamePrefix()
+   {
+      ComparisonResult result = element.compare("myDifferentExpression",
+            targetIndex, comparableIndex, null);
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+   }
+   
+   /**
+    * Tests comparison indexes using an empty string in the first comparison.
+    */
+   public void testComparisonIndexesEmptyString()
+   {
+      ComparisonResult result = element.compare("",
+            targetIndex, comparableIndex, null);
+      result = element.compare("myExpression",
+            targetIndex, comparableIndex, null);
+      assertSame(ComparisonResult.BOTH_ENDS, result);
+   }
+   
+   /**
+    * Tests comparison indexes using a prefix of the comparable element as
+    * target during the first comparison.
+    */
+   public void testComparisonIndexesPrefix()
+   {
+      ComparisonResult result = element.compare("my", targetIndex,
+            comparableIndex, null);
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(2, comparableIndex.getValue());
+      assertEquals(2, targetIndex.getValue());
+      targetIndex.reset();
+      result = element.compare("E", targetIndex, comparableIndex, null);
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(3, comparableIndex.getValue());
+      assertEquals(1, targetIndex.getValue());
+      targetIndex.reset();
+      result = element.compare("xpression",
+            targetIndex, comparableIndex, null);
+      assertSame(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(12, comparableIndex.getValue());
+      assertEquals(9, targetIndex.getValue());
+   }
+   
+   /**
+    * Tests the comparison indexes in a comparison whose expected outcome is a
+    * mismatch.
+    */
+   public void testComparisonIndexesMismatch()
+   {
+      ComparisonResult result = element.compare("my",
+            targetIndex, comparableIndex, null);
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(2, comparableIndex.getValue());
+      assertEquals(2, targetIndex.getValue());
+      targetIndex.reset();
+      result = element.compare("myE",
+            targetIndex, comparableIndex, null);
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(2, comparableIndex.getValue());
+      assertEquals(0, targetIndex.getValue());
+   }
+
+   /**
+    * Tests the comparison indexes using the comparable element itself broken
+    * into pieces as the targets of the comparisons.
+    */
+   public void testComparisonIndexesBrokenExp()
+   {
+      ComparisonResult result = element.compare("my",
+            targetIndex, comparableIndex, null);
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(2, comparableIndex.getValue());
+      assertEquals(2, targetIndex.getValue());
+      targetIndex.reset();
+      result = element.compare("", targetIndex, comparableIndex, null);
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(2, comparableIndex.getValue());
+      assertEquals(0, targetIndex.getValue());
+      targetIndex.reset();
+      result = element.compare("Expression",
+            targetIndex, comparableIndex, null);
+      assertSame(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(12, comparableIndex.getValue());
+      assertEquals(10, targetIndex.getValue());
+   }
+   
+   /**
+    * Tests comparison when target index is not zero.
+    */
+   public void testTargetIndex()
+   {
+      targetIndex.increment(6);
+      ComparisonResult result = element.compare("other_myExpression",
+            targetIndex, comparableIndex, null);
+      assertEquals(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(12, comparableIndex.getValue());
+      assertEquals(18, targetIndex.getValue());
+   }
+
+   /**
+    * Tests comparison when target index is not zero, and the complete target
+    * expression is broken into two targets.
+    */
+   public void testTargetIndexBrokenExp()
+   {
+      targetIndex.increment(6);
+      ComparisonResult result = element.compare("other_myE",
+            targetIndex, comparableIndex, null);
+      assertEquals(ComparisonResult.TARGET_END, result);
+      assertEquals(3, comparableIndex.getValue());
+      assertEquals(9, targetIndex.getValue());
+      targetIndex.reset();
+      result = element.compare("xpression123", targetIndex, comparableIndex, null);
+      assertEquals(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(12, comparableIndex.getValue());
+      assertEquals(9, targetIndex.getValue());
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/AllTests.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/AllTests.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/AllTests.java	2008-01-03 18:54:24 UTC (rev 68603)
@@ -0,0 +1,55 @@
+/*
+ * 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 junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * Test suite that contains all test cases of this package.
+ * 
+ * @author Flavia Rainone
+ */
+public class AllTests
+{
+
+   public static Test suite()
+   {
+      TestSuite suite = new TestSuite(
+            "Test for org.jboss.aop.joinpoint.graph.tree.search.match");
+      //$JUnit-BEGIN$
+      suite.addTestSuite(ComparisonAlgorithmTest.class);
+      suite.addTestSuite(ComparisonEndStateTest.class);
+      suite.addTestSuite(ComparisonResultTest.class);
+      suite.addTestSuite(ComparisonStartStateTest.class);
+      suite.addTestSuite(ComparisonStartTest.class);
+      suite.addTestSuite(IndexTest.class);
+      suite.addTestSuite(LengthRangeTest.class);
+      suite.addTestSuite(LengthRestrictionTest.class);
+      suite.addTestSuite(MatcherFactoryTest.class);
+      suite.addTestSuite(MatcherTest.class);
+      suite.addTestSuite(MatchingStateTest.class);
+      //$JUnit-END$
+      return suite;
+   }
+
+}

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/ComparisonAlgorithmTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/ComparisonAlgorithmTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/ComparisonAlgorithmTest.java	2008-01-03 18:54:24 UTC (rev 68603)
@@ -0,0 +1,411 @@
+/*
+ * 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.KeyPart;
+import org.jboss.aop.joinpoint.graph.tree.search.Flags;
+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.ComparisonAlgorithm;
+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.LengthRestriction;
+import org.jboss.aop.joinpoint.graph.tree.search.match.MatcherProfile;
+import org.jboss.aop.joinpoint.graph.tree.search.match.MatchingState;
+
+import junit.framework.TestCase;
+
+/**
+ * Test of the {@link ComparisonAlgorithm} class.
+ * 
+ * @author Flavia Rainone
+ */
+public class ComparisonAlgorithmTest extends TestCase
+{
+   Index comparableIndex;
+   Index targetIndex;
+   Comparable comparable;
+   Comparable emptyComparable;
+   MatchingState state;
+   String target;
+   
+   public void setUp() throws Exception
+   {
+      // create indexes
+      comparableIndex = new Index();
+      targetIndex = new Index();
+      // create comparables
+      ComparableElementFactory factory = ComparableElementFactory.getInstance();
+      factory.performCreationForProfile(MatcherProfile.PATTERN);
+      factory.startCreation();
+      comparable = factory.create("abcabca", null);
+      factory.stopCreation();
+      factory.startCreation();
+      emptyComparable = factory.create("", null);
+      factory.stopCreation();
+      // create state
+      state = new MatchingState();
+      // assign target value
+      target = "abcabca";
+   }
+   
+   public void testCompare1_Simple()
+   {
+      ComparisonResult result = ComparisonAlgorithm.SIMPLE.execute(comparable,
+            comparableIndex, "abcabca", targetIndex, 7,
+            LengthRestriction.LESS_OR_EQUAL, state);
+      assertSame(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(7, comparableIndex.getValue());
+      assertEquals(7, targetIndex.getValue());
+   }
+   
+   public void testCompare2_Simple()
+   {
+      ComparisonResult result = ComparisonAlgorithm.SIMPLE.execute(comparable,
+            comparableIndex, "abc", targetIndex,
+            new LengthRange((byte) 3, (byte) 7, (byte) 7),
+            LengthRestriction.LESS_OR_EQUAL, state);
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(3, comparableIndex.getValue());
+      assertEquals(3, targetIndex.getValue());
+   }
+   
+   public void testCompare3_Simple()
+   {
+      ComparisonResult result = ComparisonAlgorithm.SIMPLE.execute(comparable,
+            comparableIndex, "abcabcabc", targetIndex,
+            new LengthRange((byte) 9, (byte) 9, (byte) 10),
+            LengthRestriction.LESS_OR_EQUAL, state);
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(7, comparableIndex.getValue());
+      assertEquals(7, targetIndex.getValue());
+   }
+   
+   public void testCompare4_Simple()
+   {
+      ComparisonResult result = ComparisonAlgorithm.SIMPLE.execute(comparable,
+            comparableIndex, "abcaabcabc", targetIndex, 10,
+            LengthRestriction.LESS_OR_EQUAL, state);
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(4, targetIndex.getValue());
+   }
+   
+   public void testCompare5_Simple()
+   {
+      targetIndex.increment(3);
+      comparableIndex.increment();
+      ComparisonResult result = ComparisonAlgorithm.SIMPLE.execute(comparable,
+            comparableIndex, "abcbcabc", targetIndex, 8,
+            LengthRestriction.LESS_OR_EQUAL, state);
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(6, comparableIndex.getValue());
+      assertEquals(8, targetIndex.getValue());
+   }
+   
+   public void testCompare6_Simple()
+   {
+      ComparisonResult result = ComparisonAlgorithm.SIMPLE.execute(
+            emptyComparable, comparableIndex, "anytarget", targetIndex, 9,
+            LengthRestriction.LESS_OR_EQUAL, state);
+      assertEquals(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, targetIndex.getValue());
+   }
+
+   public void testCompare7_Simple()
+   {
+      ComparisonResult result = ComparisonAlgorithm.SIMPLE.execute(
+            emptyComparable, comparableIndex, "anytarget", targetIndex,
+            new LengthRange((byte) 9, (byte) 10, (byte) 14),
+            LengthRestriction.LESS_OR_EQUAL, state);
+      assertEquals(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, targetIndex.getValue());
+   }
+
+   public void testCompare8_Simple()
+   {
+      ComparisonResult result = ComparisonAlgorithm.SIMPLE.execute(
+            emptyComparable, comparableIndex, "", targetIndex, 0,
+            LengthRestriction.LESS_OR_EQUAL, state);
+      assertEquals(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, targetIndex.getValue());
+   }
+   
+   public void testCompare9_Simple()
+   {
+      ComparisonResult result = ComparisonAlgorithm.SIMPLE.execute(
+            emptyComparable, comparableIndex, "", targetIndex,
+            new LengthRange((byte) 0, (byte) 3, (byte) 4),
+            LengthRestriction.LESS_OR_EQUAL, state);
+      assertEquals(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, targetIndex.getValue());
+   }
+   
+   public void testCompare1_KMP()
+   {
+      ComparisonResult result = ComparisonAlgorithm.KMP.execute(comparable,
+            comparableIndex, "abcabca", targetIndex, 7,
+            LengthRestriction.LESS_OR_EQUAL, state);
+      assertEquals(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(7, comparableIndex.getValue());
+      assertEquals(7, targetIndex.getValue());
+   }
+   
+   public void testCompare2_KMP()
+   {
+      ComparisonResult result = ComparisonAlgorithm.KMP.execute(comparable,
+            comparableIndex, "abcabca", targetIndex,
+            new LengthRange((byte) 7, (byte) 10, (byte) 10),
+            LengthRestriction.LESS_OR_EQUAL, state);
+      assertEquals(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(7, comparableIndex.getValue());
+      assertEquals(7, targetIndex.getValue());
+   }
+   
+   public void testCompare3_KMP()
+   {
+      ComparisonResult result = ComparisonAlgorithm.KMP.execute(comparable,
+            comparableIndex, "bbabcabca", targetIndex,
+            new LengthRange((byte) 9, (byte) 10, (byte) 10),
+            LengthRestriction.LESS_OR_EQUAL, state);
+      assertEquals(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(7, comparableIndex.getValue());
+      assertEquals(9, targetIndex.getValue());
+   }
+   
+   public void testCompare4_KMP()
+   {
+      ComparisonResult result = ComparisonAlgorithm.KMP.execute(comparable,
+            comparableIndex, "bbabcab", targetIndex,
+            new LengthRange((byte) 7, (byte) 8, (byte) 8),
+            LengthRestriction.LESS_OR_EQUAL, state);
+      assertEquals(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(2, targetIndex.getValue());
+   }
+   
+   public void testCompare5_KMP()
+   {
+      ComparisonResult result = ComparisonAlgorithm.KMP.execute(comparable,
+            comparableIndex, "bbabcab", targetIndex, 7,
+            LengthRestriction.LESS_OR_EQUAL, state);
+      assertEquals(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(1, targetIndex.getValue());
+   }
+   
+   public void testCompare6_KMP()
+   {
+      ComparisonResult result = ComparisonAlgorithm.KMP.execute(comparable,
+            comparableIndex, "bbabcabb", targetIndex,
+            new LengthRange((byte) 8, (byte) 20, (byte) 30),
+            LengthRestriction.LESS_OR_EQUAL, state);
+      assertEquals(ComparisonResult.TARGET_END, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(8, targetIndex.getValue());
+   }
+   
+   public void testCompare7_KMP()
+   {
+      ComparisonResult result = ComparisonAlgorithm.KMP.execute(comparable,
+            comparableIndex, "bbabcabc", targetIndex,
+            new LengthRange((byte) 8, (byte) 20, (byte) 30),
+            LengthRestriction.LESS_OR_EQUAL, state);
+      assertEquals(ComparisonResult.TARGET_END, result);
+      assertEquals(6, comparableIndex.getValue());
+      assertEquals(8, targetIndex.getValue());
+   }
+   
+   public void testCompare8_KMP()
+   {
+      ComparisonResult result = ComparisonAlgorithm.KMP.execute(comparable,
+            comparableIndex, "bbabcabcabcabcabc", targetIndex,
+            new LengthRange((byte) 17, (byte) 17, (byte) 21),
+            LengthRestriction.LESS_OR_EQUAL, state);
+      assertEquals(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(7, comparableIndex.getValue());
+      assertEquals(9, targetIndex.getValue());
+   }
+   
+   public void testCompare9_KMP()
+   {
+      ComparisonResult result = ComparisonAlgorithm.KMP.execute(comparable,
+            comparableIndex, "bbabcabcabcabcabc", targetIndex, 17,
+            LengthRestriction.LESS_OR_EQUAL, state);
+      assertEquals(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(7, comparableIndex.getValue());
+      assertEquals(9, targetIndex.getValue());
+   }
+   
+   public void testCompare11_KMP()
+   {
+      ComparisonResult result = ComparisonAlgorithm.KMP.execute(emptyComparable,
+            comparableIndex, "anytarget", targetIndex, 9,
+            LengthRestriction.LESS_OR_EQUAL, state);
+      assertEquals(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, targetIndex.getValue());
+   }
+   
+   public void testCompare12_KMP()
+   {
+      ComparisonResult result = ComparisonAlgorithm.KMP.execute(emptyComparable,
+            comparableIndex, "anytarget", targetIndex,
+            new LengthRange((byte) 9, (byte) 10, (byte) 20),
+            LengthRestriction.LESS_OR_EQUAL, state);
+      assertEquals(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, targetIndex.getValue());
+   }
+   
+   public void testCompare13_KMP()
+   {
+      ComparisonResult result = ComparisonAlgorithm.KMP.execute(emptyComparable,
+            comparableIndex, "", targetIndex, 0,
+            LengthRestriction.LESS_OR_EQUAL, state);
+      assertEquals(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, targetIndex.getValue());
+   }
+   
+   public void testCompare14_KMP()
+   {
+      ComparisonResult result = ComparisonAlgorithm.KMP.execute(emptyComparable,
+            comparableIndex, "", targetIndex,
+            new LengthRange((byte) 0,(byte) 0, (byte) 7),
+            LengthRestriction.LESS_OR_EQUAL, state);
+      assertEquals(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, targetIndex.getValue());
+   }
+   
+   public void testGetNextCharStateless()
+   {
+      assertEquals('a', ComparisonAlgorithm.SIMPLE.getNextCharacter(comparable,
+            comparableIndex, state));
+      assertEquals(Flags.ALL, ComparisonAlgorithm.KMP.getNextCharacter(
+            comparable, comparableIndex, state));
+      comparableIndex.increment();
+      assertEquals('b', ComparisonAlgorithm.SIMPLE.getNextCharacter(comparable,
+            comparableIndex, state));
+      assertEquals(Flags.ALL, ComparisonAlgorithm.KMP.getNextCharacter(
+            comparable, comparableIndex, state));
+      comparableIndex.increment();
+      assertEquals('c', ComparisonAlgorithm.SIMPLE.getNextCharacter(comparable,
+            comparableIndex, state));
+      assertEquals(Flags.ALL, ComparisonAlgorithm.KMP.getNextCharacter(
+            comparable, comparableIndex, state));
+      comparableIndex.increment(3);
+      assertEquals('c', ComparisonAlgorithm.SIMPLE.getNextCharacter(comparable,
+            comparableIndex, state));
+      assertEquals(Flags.ALL, ComparisonAlgorithm.KMP.getNextCharacter(
+            comparable, comparableIndex, state));
+      comparableIndex.increment();
+      assertEquals('a', ComparisonAlgorithm.SIMPLE.getNextCharacter(comparable,
+            comparableIndex, state));
+      assertEquals(Flags.ALL, ComparisonAlgorithm.KMP.getNextCharacter(
+            comparable, comparableIndex, state));
+      comparableIndex.increment();
+      assertEquals(KeyPart.KEY_ELEMENT_END, ComparisonAlgorithm.SIMPLE.
+            getNextCharacter(comparable, comparableIndex, state));
+      assertEquals(Flags.ALL, ComparisonAlgorithm.KMP.getNextCharacter(
+            comparable, comparableIndex, state));
+   }
+   
+   public void testGetNextCharLooseState()
+   {
+      LengthRange lengthRange = new LengthRange((byte) target.length(),
+            (byte) target.length(), (byte) (target.length() * 3));
+      assertEquals('a', ComparisonAlgorithm.SIMPLE.getNextCharacter(comparable,
+            comparableIndex, target, lengthRange, state));
+      assertEquals(Flags.ALL, ComparisonAlgorithm.KMP.getNextCharacter(
+            comparable, comparableIndex, target, lengthRange, state));
+      comparableIndex.increment();
+      assertEquals('b', ComparisonAlgorithm.SIMPLE.getNextCharacter(comparable,
+            comparableIndex, target, lengthRange, state));
+      assertEquals(Flags.ALL, ComparisonAlgorithm.KMP.getNextCharacter(
+            comparable, comparableIndex, target, lengthRange, state));
+      comparableIndex.increment();
+      assertEquals('c', ComparisonAlgorithm.SIMPLE.getNextCharacter(comparable,
+            comparableIndex, target, lengthRange, state));
+      assertEquals(Flags.ALL, ComparisonAlgorithm.KMP.getNextCharacter(
+            comparable, comparableIndex, target, lengthRange, state));
+      comparableIndex.increment(3);
+      assertEquals('c', ComparisonAlgorithm.SIMPLE.getNextCharacter(comparable,
+            comparableIndex, target, lengthRange, state));
+      assertEquals(Flags.ALL, ComparisonAlgorithm.KMP.getNextCharacter(
+            comparable, comparableIndex, target, lengthRange, state));
+      comparableIndex.increment();
+      assertEquals('a', ComparisonAlgorithm.SIMPLE.getNextCharacter(comparable,
+            comparableIndex, target, lengthRange, state));
+      assertEquals(Flags.ALL, ComparisonAlgorithm.KMP.getNextCharacter(
+            comparable, comparableIndex, target, lengthRange, state));
+      comparableIndex.increment();
+      assertEquals(KeyPart.KEY_ELEMENT_END, ComparisonAlgorithm.SIMPLE.
+            getNextCharacter(comparable, comparableIndex, target, lengthRange,
+                  state));
+      assertEquals(Flags.ALL, ComparisonAlgorithm.KMP.getNextCharacter(
+            comparable, comparableIndex, target, lengthRange, state));
+   }
+   
+   public void testGetNextCharTightState()
+   {
+      LengthRange lengthRange = new LengthRange((byte) target.length(),
+            (byte) target.length(), (byte) (target.length() * 2));
+      assertEquals('a', ComparisonAlgorithm.SIMPLE.getNextCharacter(comparable,
+            comparableIndex, target, lengthRange, state));
+      assertEquals('a', ComparisonAlgorithm.KMP.getNextCharacter(
+            comparable, comparableIndex, target, lengthRange, state));
+      comparableIndex.increment();
+      assertEquals('b', ComparisonAlgorithm.SIMPLE.getNextCharacter(comparable,
+            comparableIndex, target, lengthRange, state));
+      assertEquals('b', ComparisonAlgorithm.KMP.getNextCharacter(
+            comparable, comparableIndex, target, lengthRange, state));
+      comparableIndex.increment();
+      assertEquals('c', ComparisonAlgorithm.SIMPLE.getNextCharacter(comparable,
+            comparableIndex, target, lengthRange, state));
+      assertEquals('c', ComparisonAlgorithm.KMP.getNextCharacter(
+            comparable, comparableIndex, target, lengthRange, state));
+      comparableIndex.increment(3);
+      assertEquals('c', ComparisonAlgorithm.SIMPLE.getNextCharacter(comparable,
+            comparableIndex, target, lengthRange, state));
+      assertEquals('c', ComparisonAlgorithm.KMP.getNextCharacter(
+            comparable, comparableIndex, target, lengthRange, state));
+      comparableIndex.increment();
+      assertEquals('a', ComparisonAlgorithm.SIMPLE.getNextCharacter(comparable,
+            comparableIndex, target, lengthRange, state));
+      assertEquals('a', ComparisonAlgorithm.KMP.getNextCharacter(
+            comparable, comparableIndex, target, lengthRange, state));
+      comparableIndex.increment();
+      assertEquals(KeyPart.KEY_ELEMENT_END, ComparisonAlgorithm.SIMPLE.
+            getNextCharacter(comparable, comparableIndex, target, lengthRange,
+                  state));
+      assertEquals(KeyPart.KEY_ELEMENT_END, ComparisonAlgorithm.KMP.
+            getNextCharacter(comparable, comparableIndex, target, lengthRange,
+                  state));
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/ComparisonEndStateTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/ComparisonEndStateTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/ComparisonEndStateTest.java	2008-01-03 18:54:24 UTC (rev 68603)
@@ -0,0 +1,195 @@
+/*
+ * 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.lang.reflect.Field;
+
+import org.jboss.aop.joinpoint.graph.tree.search.Flags;
+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.ComparisonEndState;
+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.MatcherProfile;
+import org.jboss.aop.joinpoint.graph.tree.search.match.MatchingState;
+
+import junit.framework.TestCase;
+
+/**
+ * Test of the {@link ComparisonEndState} class.
+ * 
+ * @author Flavia Rainone
+ */
+public class ComparisonEndStateTest extends TestCase
+{
+   Field compEndStateField;
+   MatchingState matchingState;
+   Index targetIndex;
+   LengthRange targetLengthRange;
+   Comparable comparable;
+   Index comparableIndex;
+   
+   public void setUp() throws Exception
+   {
+      compEndStateField = MatchingState.class.getDeclaredField(
+            "comparisonEndState");
+      matchingState = new MatchingState();
+      targetIndex = new Index();
+      targetIndex.increment(1);
+      targetLengthRange = new LengthRange((byte) 3, (byte) 20, (byte) 30);
+      // create comparable
+      ComparableElementFactory factory = ComparableElementFactory.getInstance();
+      factory.performCreationForProfile(MatcherProfile.PATTERN);
+      factory.startCreation();
+      comparable = factory.create("abcabca", null);
+      factory.stopCreation();
+      comparableIndex = new Index();
+      comparableIndex.increment();
+   }
+   
+   public void testLooseUpdateToLoose() throws Exception
+   {
+      ComparisonEndState.LOOSE.update(matchingState, comparable,
+            comparableIndex, targetLengthRange.getPostPrefixMaxLength(),
+            targetIndex);
+      assertState(ComparisonEndState.LOOSE);
+   }
+
+   public void testLooseUpdateToTight1() throws Exception
+   {
+      targetLengthRange.reset((byte) 3, (byte) 4, (byte) 7);
+      ComparisonEndState.LOOSE.update(matchingState, comparable,
+            comparableIndex, targetLengthRange.getPostPrefixMaxLength(),
+            targetIndex);
+      assertState(ComparisonEndState.TIGHT);
+   }
+
+   public void testLooseUpdateToTight2() throws Exception
+   {
+      targetLengthRange.reset((byte) 3, (byte) 7, (byte) 7);
+      ComparisonEndState.LOOSE.update(matchingState, comparable,
+            comparableIndex, targetLengthRange.getPostPrefixMaxLength(),
+            targetIndex);
+      assertState(ComparisonEndState.TIGHT);
+   }
+
+   public void testLooseUpdateToTight3() throws Exception
+   {
+      targetLengthRange.reset((byte) 3, (byte) 4, (byte) 5);
+      ComparisonEndState.LOOSE.update(matchingState, comparable,
+            comparableIndex, targetLengthRange.getPostPrefixMaxLength(),
+            targetIndex);
+      assertState(ComparisonEndState.TIGHT);
+   }
+
+   public void testLooseGetNextCharacter() throws Exception
+   {
+      assertGetNextCharacter(ComparisonEndState.LOOSE, Flags.ALL, 'b');
+   }
+
+   public void testTightGetNextCharacter() throws Exception
+   {
+      testLooseGetNextCharacter(); // make current state change to tight
+      assertGetNextCharacter(ComparisonEndState.TIGHT, 'b', 'b');
+   }
+   
+   public void testLooseTightenIndexesCurrentTarget()
+   {
+      ComparisonEndState.LOOSE.tightenComparison(matchingState, comparable,
+            comparableIndex, 8, targetIndex);
+      assertTrue(comparableIndex.isInitialState());
+      assertEquals(1, targetIndex.getValue());
+   }
+   
+   public void testLooseTightenIndexesNextSuffixFirstComponent()
+   {
+      ComparisonEndState.LOOSE.tightenComparison(matchingState, comparable,
+            comparableIndex, 10, targetIndex);
+      assertTrue(comparableIndex.isInitialState());
+      assertEquals(3, targetIndex.getValue());
+   }
+   
+   public void testLooseTightenIndexesNextSuffixes()
+   {
+      ComparisonEndState.LOOSE.tightenComparison(matchingState, comparable,
+            comparableIndex, targetLengthRange.getPostPrefixMaxLength(),
+            targetIndex);
+      assertTrue(comparableIndex.isInitialState());
+      assertEquals(23, targetIndex.getValue());
+   }
+   
+   public void testTightTightenIndexesCurrentTarget()
+   {
+      ComparisonEndState.TIGHT.tightenComparison(matchingState, comparable,
+            comparableIndex, 8, targetIndex);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(1, targetIndex.getValue());
+   }
+   
+   public void testTightTightenIndexesNextSuffixFirstComponent()
+   {
+      ComparisonEndState.TIGHT.tightenComparison(matchingState, comparable,
+            comparableIndex, 10, targetIndex);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(1, targetIndex.getValue());
+   }
+   
+   public void testTightTightenIndexesNextSuffixes()
+   {
+      ComparisonEndState.TIGHT.tightenComparison(matchingState, comparable,
+            comparableIndex, targetLengthRange.getPostPrefixMaxLength(),
+            targetIndex);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(1, targetIndex.getValue());
+   }
+
+   private void assertState(ComparisonEndState expectedState) throws Exception
+   {
+      ComparisonEndState actualState = (ComparisonEndState)
+         compEndStateField.get(matchingState);
+      assertEquals(expectedState, actualState);
+   }
+
+   public void assertGetNextCharacter(ComparisonEndState state,
+         char looseChar, char tightChar) throws Exception
+   {
+      assertGetNextCharacter_(state, looseChar, looseChar);
+      targetLengthRange.reset((byte) 3, (byte) 3, (byte) 10);
+      assertGetNextCharacter_(state, looseChar, looseChar);
+      targetLengthRange.reset((byte) 3, (byte) 3, (byte) 9);
+      assertGetNextCharacter_(state, tightChar, looseChar);
+      assertState(ComparisonEndState.TIGHT);
+      targetLengthRange.reset((byte) 3, (byte) 3, (byte) 8);
+      assertGetNextCharacter_(state, tightChar, looseChar);
+   }
+
+   private void assertGetNextCharacter_(ComparisonEndState state,
+         char expected1, char expected2)
+   {
+      char nextChar = state.getNextCharacter(matchingState, comparable,
+            comparableIndex, "aba", targetLengthRange);
+      assertEquals(expected1, nextChar);
+      nextChar = state.getNextCharacter(matchingState, comparable,
+            comparableIndex);
+      assertEquals(expected2, nextChar);
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/ComparisonResultTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/ComparisonResultTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/ComparisonResultTest.java	2008-01-03 18:54:24 UTC (rev 68603)
@@ -0,0 +1,58 @@
+/*
+ * 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.match.ComparisonResult;
+
+import junit.framework.TestCase;
+
+/**
+ * Test of the {@link ComparisonResult} class.
+ * 
+ * @author Flavia Rainone
+ */
+public class ComparisonResultTest extends TestCase
+{
+   public void testGetMismatchInstance()
+   {
+      assertEquals(ComparisonResult.MISMATCH_FOUND,
+            ComparisonResult.getInstance(false, false));
+   }
+   
+   public void testGetTargetEndInstance()
+   {
+      assertEquals(ComparisonResult.TARGET_END,
+            ComparisonResult.getInstance(false, true));
+   }
+   
+   public void testGetComparableEndInstance()
+   {
+      assertEquals(ComparisonResult.COMPARABLE_END,
+            ComparisonResult.getInstance(true, false));
+   }
+   
+   public void testGetBothEndsInstance()
+   {
+      assertEquals(ComparisonResult.BOTH_ENDS,
+            ComparisonResult.getInstance(true, true));
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/ComparisonStartStateTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/ComparisonStartStateTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/ComparisonStartStateTest.java	2008-01-03 18:54:24 UTC (rev 68603)
@@ -0,0 +1,221 @@
+/*
+ * 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.lang.reflect.Field;
+
+import org.jboss.aop.joinpoint.graph.tree.search.Flags;
+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.ComparisonStartState;
+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.MatcherProfile;
+import org.jboss.aop.joinpoint.graph.tree.search.match.MatchingState;
+
+import junit.framework.TestCase;
+
+/**
+ * Test of the {@link ComparisonStartState} class.
+ * 
+ * @author Flavia Rainone
+ */
+public class ComparisonStartStateTest extends TestCase
+{
+   Field compStartStateField;
+   MatchingState matchingState;
+   Index currentTargetIndex;
+   Index nextSuffixesFirstCompIndex;
+   Index nextSuffixesIndex;
+   LengthRange targetLengthRange;
+   Comparable comparable;
+   Index comparableIndex;
+   
+   public void setUp() throws Exception
+   {
+      compStartStateField = MatchingState.class.getDeclaredField(
+            "comparisonStartState");
+      matchingState = new MatchingState();
+      currentTargetIndex = new Index();
+      currentTargetIndex.increment(1);
+      nextSuffixesFirstCompIndex = new Index();
+      nextSuffixesFirstCompIndex.increment(3);
+      nextSuffixesIndex = new Index();
+      nextSuffixesIndex.increment(10);
+      targetLengthRange = new LengthRange((byte) 3, (byte) 20, (byte) 30);
+      // create comparable
+      ComparableElementFactory factory = ComparableElementFactory.getInstance();
+      factory.performCreationForProfile(MatcherProfile.PATTERN);
+      factory.startCreation();
+      comparable = factory.create("abcabca", null);
+      factory.stopCreation();
+      comparableIndex = new Index();
+      comparableIndex.increment();
+   }
+   
+   public void testCurrentTargetUpdateToCurrentTarget() throws Exception
+   {
+      ComparisonStartState.CURRENT_TARGET.update(matchingState,
+            currentTargetIndex, targetLengthRange);
+      assertState(ComparisonStartState.CURRENT_TARGET);
+   }
+   
+   public void testCurrentTargetUpdateToNextSuffixesFirstComp() throws Exception
+   {
+      ComparisonStartState.CURRENT_TARGET.update(matchingState,
+            nextSuffixesFirstCompIndex, targetLengthRange);
+      assertState(ComparisonStartState.NEXT_SUFFIX_FIRST_COMPONENT);
+   }
+   
+   public void testCurrentTargetUpdateToNextSuffixes() throws Exception
+   {
+      ComparisonStartState.CURRENT_TARGET.update(matchingState,
+            nextSuffixesIndex, targetLengthRange);
+      assertState(ComparisonStartState.NEXT_SUFFIXES);
+   }
+   
+   public void testNextSuffixFirstCompUpdateToCurrentTarget() throws Exception
+   {
+      this.testCurrentTargetUpdateToNextSuffixesFirstComp();
+      ComparisonStartState.NEXT_SUFFIX_FIRST_COMPONENT.update(matchingState,
+            currentTargetIndex, targetLengthRange);
+      assertState(ComparisonStartState.CURRENT_TARGET);
+   }
+
+   public void testNextSuffixFirstCompUpdateToNextSuffixFirstComp()
+      throws Exception
+   {
+      this.testCurrentTargetUpdateToNextSuffixesFirstComp();
+      ComparisonStartState.NEXT_SUFFIX_FIRST_COMPONENT.update(matchingState,
+            nextSuffixesFirstCompIndex, targetLengthRange);
+      assertState(ComparisonStartState.NEXT_SUFFIX_FIRST_COMPONENT);
+   }
+
+   public void testNextSuffixFirstCompUpdateToNextSuffixes()
+      throws Exception
+   {
+      this.testCurrentTargetUpdateToNextSuffixesFirstComp();
+      ComparisonStartState.NEXT_SUFFIX_FIRST_COMPONENT.update(matchingState,
+            nextSuffixesIndex, targetLengthRange);
+      assertState(ComparisonStartState.NEXT_SUFFIXES);
+   }
+   
+   public void testNextSuffixesUpdateToCurrentTarget() throws Exception
+   {
+      this.testCurrentTargetUpdateToNextSuffixes();
+      ComparisonStartState.NEXT_SUFFIXES.update(matchingState,
+            currentTargetIndex, targetLengthRange);
+      assertState(ComparisonStartState.CURRENT_TARGET);
+   }
+   
+   public void testNextSuffixesUpdateToNextSuffixesFirstComp() throws Exception
+   {
+      this.testCurrentTargetUpdateToNextSuffixes();
+      ComparisonStartState.NEXT_SUFFIXES.update(matchingState,
+            nextSuffixesFirstCompIndex, targetLengthRange);
+      assertState(ComparisonStartState.NEXT_SUFFIX_FIRST_COMPONENT);
+   }
+   
+   public void testNextSuffixesUpdateToNextSuffixes() throws Exception
+   {
+      this.testCurrentTargetUpdateToNextSuffixes();
+      ComparisonStartState.NEXT_SUFFIXES.update(matchingState,
+            nextSuffixesIndex, targetLengthRange);
+      assertState(ComparisonStartState.NEXT_SUFFIXES);
+   }
+   
+   public void testCurrentTargetGetNextCharacter()
+   {
+      assertGetNextCharacter(ComparisonStartState.CURRENT_TARGET, Flags.ALL,
+            'b');
+   }
+   
+   public void testNextSuffixFistCompGetNextCharacter()
+   {
+      assertGetNextCharacter(ComparisonStartState.NEXT_SUFFIX_FIRST_COMPONENT,
+            Flags.ALL, 'b');
+   }
+   
+   public void testNextSuffixesGetNextCharacter()
+   {
+      assertGetNextCharacter(ComparisonStartState.NEXT_SUFFIXES, Flags.ALL,
+            Flags.ALL);
+   }
+
+   public void testIsComparisonPostPoned()
+   {
+      assertFalse(ComparisonStartState.CURRENT_TARGET.isComparisonPostponed());
+      assertTrue(ComparisonStartState.NEXT_SUFFIX_FIRST_COMPONENT.
+            isComparisonPostponed());
+      assertTrue(ComparisonStartState.NEXT_SUFFIXES.isComparisonPostponed());
+   }
+   
+   /**
+    * Asserts that the current comparison start state is <code>expectedState
+    * </code>.
+    * 
+    * @param expectedState the comparison start state that is expected to be
+    *                      the current one.
+    */
+   private void assertState(ComparisonStartState expectedState) throws Exception
+   {
+      ComparisonStartState actualState = (ComparisonStartState)
+         compStartStateField.get(matchingState);
+      assertEquals(expectedState, actualState);
+   }
+   
+   /**
+    * Asserts <code>getNextCharacter</code> method functionality.
+    * 
+    * @param state     the comparison start state to be tested
+    * @param looseChar the character that is expected when comparison is loose
+    * @param tightChar the character that is expected when comparison is tight
+    */
+   public void assertGetNextCharacter(ComparisonStartState state,
+         char looseChar, char tightChar)
+   {
+      assertGetNextCharacter(state, looseChar);
+      targetLengthRange.reset((byte) 3, (byte) 3, (byte) 10);
+      assertGetNextCharacter(state, looseChar);
+      targetLengthRange.reset((byte) 3, (byte) 3, (byte) 9);
+      assertGetNextCharacter(state, tightChar);
+      targetLengthRange.reset((byte) 3, (byte) 3, (byte) 8);
+      assertGetNextCharacter(state, tightChar);
+   }
+
+   /**
+    * Asserts <code>getNextCharacter</code> method functionality.
+    * 
+    * @param state    the comparison start state to be tested
+    * @param expected the character that is expected as result
+    */
+   private void assertGetNextCharacter(ComparisonStartState state,
+         char expected)
+   {
+      char nextChar = state.getNextCharacter(matchingState, comparable,
+            comparableIndex, "aba", targetLengthRange);
+      assertEquals(expected, nextChar);
+      nextChar = state.getNextCharacter(matchingState, comparable,
+            comparableIndex);
+      assertEquals(expected, nextChar);
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/ComparisonStartTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/ComparisonStartTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/ComparisonStartTest.java	2008-01-03 18:54:24 UTC (rev 68603)
@@ -0,0 +1,256 @@
+/*
+ * 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.element.ComparableElementFactory;
+import org.jboss.aop.joinpoint.graph.tree.search.match.Comparable;
+import org.jboss.aop.joinpoint.graph.tree.search.match.ComparisonStart;
+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.MatcherProfile;
+import org.jboss.aop.joinpoint.graph.tree.search.match.MatchingState;
+
+import junit.framework.TestCase;
+
+/**
+ * Test of the {@link ComparisonStart} class.
+ * 
+ * @author Flavia Rainone
+ */
+public class ComparisonStartTest extends TestCase
+{
+   Index comparableIndex;
+   Index targetIndex;
+   Comparable comparable;
+   MatchingState state;
+   
+   public void setUp() throws Exception
+   {
+      // create indexes
+      comparableIndex = new Index();
+      targetIndex = new Index();
+      // create comparable
+      ComparableElementFactory factory = ComparableElementFactory.getInstance();
+      factory.performCreationForProfile(MatcherProfile.PATTERN);
+      factory.startCreation();
+      comparable = factory.create("abcabca", null);
+      factory.stopCreation();
+      // create state
+      state = new MatchingState();
+   }
+   
+   public void testLoose()
+   {
+      ComparisonStart.LOOSE.tuneIndex(comparable, comparableIndex, 7,
+            targetIndex, state);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, targetIndex.getValue());
+   }
+   
+   public void testLoose2()
+   {
+      ComparisonStart.LOOSE.tuneIndex(comparable, comparableIndex, 13,
+            targetIndex, state);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, targetIndex.getValue());
+   }
+   
+   public void testLoose3()
+   {
+      comparableIndex.increment();
+      targetIndex.increment(8);
+      ComparisonStart.LOOSE.tuneIndex(comparable, comparableIndex, 13,
+            targetIndex, state);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(8, targetIndex.getValue());
+   }
+   
+   public void testLoose4()
+   {
+      ComparisonStart.LOOSE.tuneIndex(comparable, comparableIndex,
+            new LengthRange((byte) 3, (byte) 7, (byte) 7),
+            targetIndex, state);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, targetIndex.getValue());
+   }
+   
+   public void testLoose5()
+   {
+      ComparisonStart.LOOSE.tuneIndex(comparable, comparableIndex,
+            new LengthRange((byte) 4, (byte) 5, (byte) 13),
+            targetIndex, state);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, targetIndex.getValue());
+   }
+   
+   public void testLoose6()
+   {
+      comparableIndex.increment();
+      targetIndex.increment(8);
+      ComparisonStart.LOOSE.tuneIndex(comparable, comparableIndex,
+            new LengthRange((byte) 9, (byte) 10, (byte) 13),
+            targetIndex, state);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(8, targetIndex.getValue());
+   }
+   
+   public void testTight1()
+   {
+      ComparisonStart.TIGHT.tuneIndex(comparable, comparableIndex, 7,
+            targetIndex, state);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, targetIndex.getValue());
+   }
+   
+   public void testTight2()
+   {
+      ComparisonStart.TIGHT.tuneIndex(comparable, comparableIndex, 13,
+            targetIndex, state);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(6, targetIndex.getValue());
+   }
+   
+   public void testTight3()
+   {
+      comparableIndex.increment(3);
+      targetIndex.increment(9);
+      ComparisonStart.TIGHT.tuneIndex(comparable, comparableIndex, 13,
+            targetIndex, state);
+      assertEquals(3, comparableIndex.getValue());
+      assertEquals(9, targetIndex.getValue());
+   }
+   
+   public void testTight4()
+   {
+      // more than tight scenario
+      comparableIndex.increment(3);
+      targetIndex.increment(12);
+      ComparisonStart.TIGHT.tuneIndex(comparable, comparableIndex, 13,
+            targetIndex, state);
+      assertEquals(3, comparableIndex.getValue());
+      assertEquals(12, targetIndex.getValue());
+   }
+   
+   public void testTight5()
+   {
+      comparableIndex.increment(3);
+      targetIndex.increment(6);
+      ComparisonStart.TIGHT.tuneIndex(comparable, comparableIndex, 13,
+            targetIndex, state);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(6, targetIndex.getValue());
+   }
+   
+   public void testTight6()
+   {
+      comparableIndex.increment(6);
+      targetIndex.increment(7);
+      ComparisonStart.TIGHT.tuneIndex(comparable, comparableIndex, 13,
+            targetIndex, state);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(7, targetIndex.getValue());
+   }
+   
+   public void testTight7()
+   {
+      comparableIndex.increment(6);
+      targetIndex.increment(9);
+      ComparisonStart.TIGHT.tuneIndex(comparable, comparableIndex, 13,
+            targetIndex, state);
+      assertEquals(3, comparableIndex.getValue());
+      assertEquals(9, targetIndex.getValue());
+   }
+   
+   public void testTight8()
+   {
+      ComparisonStart.TIGHT.tuneIndex(comparable, comparableIndex,
+            new LengthRange((byte) 3, (byte) 7, (byte) 10),
+            targetIndex, state);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, targetIndex.getValue());
+   }
+   
+   public void testTight9()
+   {
+      ComparisonStart.TIGHT.tuneIndex(comparable, comparableIndex,
+            new LengthRange((byte) 3, (byte) 13, (byte) 13),
+            targetIndex, state);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(6, targetIndex.getValue());
+   }
+   
+   public void testTight10()
+   {
+      comparableIndex.increment(3);
+      targetIndex.increment(9);
+      ComparisonStart.TIGHT.tuneIndex(comparable, comparableIndex,
+            new LengthRange((byte) 2, (byte) 13, (byte) 20),
+            targetIndex, state);
+      assertEquals(3, comparableIndex.getValue());
+      assertEquals(9, targetIndex.getValue());
+   }
+   
+   public void testTight11()
+   {
+      // more than tight scenario
+      comparableIndex.increment(3);
+      targetIndex.increment(12);
+      ComparisonStart.TIGHT.tuneIndex(comparable, comparableIndex,
+            new LengthRange((byte) 2, (byte) 13, (byte) 14),
+            targetIndex, state);
+      assertEquals(3, comparableIndex.getValue());
+      assertEquals(12, targetIndex.getValue());
+   }
+   
+   public void testTight12()
+   {
+      comparableIndex.increment(3);
+      targetIndex.increment(6);
+      ComparisonStart.TIGHT.tuneIndex(comparable, comparableIndex,
+            new LengthRange((byte) 10, (byte) 13, (byte) 13),
+            targetIndex, state);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(6, targetIndex.getValue());
+   }
+   
+   public void testTight13()
+   {
+      comparableIndex.increment(6);
+      targetIndex.increment(7);
+      ComparisonStart.TIGHT.tuneIndex(comparable, comparableIndex,
+            new LengthRange((byte) 8, (byte) 13, (byte) 30),
+            targetIndex, state);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(7, targetIndex.getValue());
+   }
+   
+   public void testTight14()
+   {
+      comparableIndex.increment(6);
+      targetIndex.increment(9);
+      ComparisonStart.TIGHT.tuneIndex(comparable, comparableIndex,
+            new LengthRange((byte) 10, (byte) 13, (byte) 15),
+            targetIndex, state);
+      assertEquals(3, comparableIndex.getValue());
+      assertEquals(9, targetIndex.getValue());
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/IndexTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/IndexTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/IndexTest.java	2008-01-03 18:54:24 UTC (rev 68603)
@@ -0,0 +1,171 @@
+/*
+ * 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.match.Index;
+import org.jboss.aop.joinpoint.graph.tree.search.match.LengthRange;
+
+import junit.framework.TestCase;
+
+/**
+ * Test of the {@link Index} class.
+ * 
+ * @author Flavia Rainone
+ */
+public class IndexTest extends TestCase
+{
+   public void testIndexOperations()
+   {
+      assertIndexOperations(3, 2);
+      assertIndexOperations(0, 0);
+      assertIndexOperations(20, 13);
+      assertIndexOperations(5, 5);
+   }
+   
+   private void assertIndexOperations(int incremental, int prefixFunctionValue)
+   {
+      Index index = new Index();
+      Index copierIndex = new Index();
+      // initial state
+      copierIndex.copy(index);
+      assertEquals(0, index.getValue());
+      assertTrue(index.isInitialState());
+      assertEquals(0, copierIndex.getValue());
+      assertTrue(copierIndex.isInitialState());
+      // no argument increment
+      index.increment();
+      copierIndex.copy(index);
+      assertEquals(1, index.getValue());
+      assertEquals(1, copierIndex.getValue());
+      // argument increment
+      index.increment(incremental);
+      copierIndex.copy(index);
+      assertEquals(1 + incremental, index.getValue());
+      assertEquals(1 + incremental, copierIndex.getValue());
+      // prefix function
+      index.applyPrefixFunction(prefixFunctionValue);
+      copierIndex.copy(index);
+      assertEquals(prefixFunctionValue, index.getValue());
+      assertEquals(prefixFunctionValue, copierIndex.getValue());
+      // reset
+      index.reset();
+      copierIndex.copy(index);
+      assertEquals(0, index.getValue());
+      assertTrue(index.isInitialState());
+      assertEquals(0, copierIndex.getValue());
+      assertTrue(copierIndex.isInitialState());
+   }
+   
+   public void testCallBackMethod()
+   {
+      MyIndex index = new MyIndex();
+      assertFalse(index.isValueChanged());
+      index.increment();
+      assertTrue(index.isValueChanged());
+      index.applyPrefixFunction(0);
+      assertFalse(index.isValueChanged());
+      index.noCallBackIncrement(5);
+      assertFalse(index.isValueChanged());
+      index.increment(10);
+      assertTrue(index.isValueChanged());
+      index.reset();
+      assertTrue(index.isValueChanged());
+      index.noCallBackIncrement(7);
+      assertFalse(index.isInitialState());
+   }
+   
+   public void testUpdate()
+   {
+      LengthRange targetLengthRange = new MyLengthRange((byte) 3, (byte) 5);
+      MyIndex index = new MyIndex();
+      MyIndex copierIndex = new MyIndex();
+      
+      index.increment(15);
+      index.update(targetLengthRange);
+      copierIndex.copy(index);
+      assertEquals(0, index.getValue());
+      assertEquals(0, copierIndex.getValue());
+      
+      index.comparisonPostponed();
+      copierIndex.copy(index);
+      index.update(targetLengthRange);
+      copierIndex.update(targetLengthRange);
+      assertEquals(30, index.getValue());
+      assertEquals(30, copierIndex.getValue());
+      
+      index.increment(-29);
+      copierIndex.copy(index);
+      index.update(targetLengthRange);
+      copierIndex.update(targetLengthRange);
+      assertEquals(31, index.getValue());
+      assertEquals(31, copierIndex.getValue());
+      
+      index.comparisonReady();
+      copierIndex.copy(index);
+      index.update(targetLengthRange);
+      copierIndex.update(targetLengthRange);
+      assertEquals(0, index.getValue());
+      assertEquals(0, copierIndex.getValue());
+   }
+   
+   /**
+    * Auxiliary class, allows to verify if the <code>valueChanged</code> method
+    * is invoked correctly.
+    * 
+    * @author Flavia Rainone
+    */
+   private class MyIndex extends Index
+   {
+      private boolean valueChanged = false;
+      
+      protected void valueChanged()
+      {
+         valueChanged = true;
+      }
+      
+      boolean isValueChanged()
+      {
+         boolean isChanged = valueChanged;
+         valueChanged = false;
+         return isChanged;
+      }
+   }
+   
+   /**
+    * Subclass of <code>LengthRange</code>, tests the <code>Index.update</code>
+    * method.
+    * 
+    * @author Flavia Rainone
+    */
+   private class MyLengthRange extends LengthRange
+   {
+      public MyLengthRange(byte length, byte postPrefixLength)
+      {
+         super(length, postPrefixLength);
+      }
+
+      public byte getPostPrefix_SuffixDiff()
+      {
+         return (byte) -30;
+      }
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/LengthRangeTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/LengthRangeTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/LengthRangeTest.java	2008-01-03 18:54:24 UTC (rev 68603)
@@ -0,0 +1,114 @@
+/*
+ * 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.match.LengthRange;
+
+import junit.framework.TestCase;
+
+/**
+ * Test of the {@link LengthRange} class.
+ * 
+ * @author Flavia Rainone
+ */
+public class LengthRangeTest extends TestCase
+{
+   public void testOneSuffixConstruction()
+   {
+      LengthRange lengthRange = new LengthRange((byte) 1, (byte) 3);
+      assertLengthRange(lengthRange, 1, 3, 3, 2, 2);
+   }
+
+   public void testSuffixRangeConstruction()
+   {
+      LengthRange lengthRange = new LengthRange((byte) 1, (byte) 5, (byte) 11);
+      assertLengthRange(lengthRange, 1, 5, 11, 4, 10);
+   }
+   
+   public void testReset()
+   {
+      LengthRange lengthRange = new LengthRange((byte) 1, (byte) 5, (byte) 11);
+      lengthRange.reset((byte) 7, (byte) 10, (byte) 17);
+      assertLengthRange(lengthRange, 7, 10, 17, 3, 10);
+   }
+   
+   public void testUpdateNewSuffix()
+   {
+      LengthRange lengthRange = new LengthRange((byte) 1, (byte) 5, (byte) 11);
+      lengthRange.update((byte) 20);
+      assertLengthRange(lengthRange, 1, 5, 20, 4, 19);
+      lengthRange.update((byte) 4);
+      assertLengthRange(lengthRange, 1, 4, 20, 3, 19);
+      lengthRange.update((byte) 10);
+      assertLengthRange(lengthRange, 1, 4, 20, 3, 19);
+   }
+   
+   public void testUpdateNewSuffixGroup()
+   {
+      LengthRange lengthRange = new LengthRange((byte) 1, (byte) 5, (byte) 11);
+      lengthRange.update((byte) 6, (byte) 8);
+      assertLengthRange(lengthRange, 1, 5, 11, 4, 10);
+      lengthRange.update((byte) 4, (byte) 10);
+      assertLengthRange(lengthRange, 1, 4, 11, 3, 10);
+      lengthRange.update((byte) 6, (byte) 12);
+      assertLengthRange(lengthRange, 1, 4, 12, 3, 11);
+      lengthRange.update((byte) 15, (byte) 20);
+      assertLengthRange(lengthRange, 1, 4, 20, 3, 19);
+      lengthRange.update((byte) 2, (byte) 3);
+      assertLengthRange(lengthRange, 1, 2, 20, 1, 19);
+      lengthRange.update((byte) 1, (byte) 30);
+      assertLengthRange(lengthRange, 1, 1, 30, 0, 29);
+   }
+   
+   public void testPostPrefix_SuffixDiff()
+   {
+      LengthRange lengthRange = new LengthRange((byte) 5, (byte) 8, (byte) 19)
+      {
+        public byte getPostPrefix_SuffixDiff() 
+        {
+           return (byte) 30;
+        }
+      };
+      
+      assertLengthRange(lengthRange, 5, 8, 19, -22, -11);
+   }
+   
+   /**
+    * Checks if <code>lengthRange</code> provides the expected lengths.
+    * @param lengthRange     the length range whose data will be tested
+    * @param length          the expected length
+    * @param ppMinLength     the expected post-prefix minimum length
+    * @param ppMaxLength     the expected post-prefix maximum length
+    * @param suffixMinLength the expected suffix minimum length
+    * @param suffixMaxLength the expected suffix maximum length
+    */
+   public void assertLengthRange(LengthRange lengthRange, int length,
+         int ppMinLength, int ppMaxLength, int suffixMinLength,
+         int suffixMaxLength)
+   {
+      assertEquals(length, lengthRange.getLength());
+      assertEquals(ppMinLength, lengthRange.getPostPrefixMinLength());
+      assertEquals(ppMaxLength, lengthRange.getPostPrefixMaxLength());
+      assertEquals(suffixMinLength, lengthRange.getSuffixMinLength());
+      assertEquals(suffixMaxLength, lengthRange.getSuffixMaxLength());
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/LengthRestrictionTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/LengthRestrictionTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/LengthRestrictionTest.java	2008-01-03 18:54:24 UTC (rev 68603)
@@ -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;
+
+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.Index;
+import org.jboss.aop.joinpoint.graph.tree.search.match.LengthRestriction;
+import org.jboss.aop.joinpoint.graph.tree.search.match.MatcherProfile;
+
+import junit.framework.TestCase;
+
+/**
+ * Test of the {@link LengthRestriction} class.
+ * 
+ * @author Flavia Rainone
+ */
+public class LengthRestrictionTest extends TestCase
+{
+   Index comparableIndex;
+   Index targetIndex;
+   Comparable comparable;
+   Comparable emptyComparable;
+   
+   public void setUp()
+   {
+      comparableIndex = new Index();
+      targetIndex = new Index();
+      ComparableElementFactory factory = ComparableElementFactory.getInstance();
+      factory.performCreationForProfile(MatcherProfile.SIMPLE);
+      factory.startCreation();
+      comparable = factory.create("element", null);
+      emptyComparable = factory.create("", null);
+      factory.stopCreation();
+   }
+   
+   public void testZeroIndexes_EqualLength()
+   {
+      LengthRestriction restriction = LengthRestriction.LESS_OR_EQUAL;
+      assertTrue(restriction.appliesTo(comparable, comparableIndex, 7,
+            targetIndex));
+      restriction = LengthRestriction.EQUAL;
+      assertTrue(restriction.appliesTo(comparable, comparableIndex, 7,
+            targetIndex));
+   }
+   
+   public void testDifferentIndexes_EqualLength()
+   {
+      LengthRestriction restriction = LengthRestriction.LESS_OR_EQUAL;
+      comparableIndex.increment();
+      targetIndex.increment(10);
+      assertTrue(restriction.appliesTo(comparable, comparableIndex, 16,
+            targetIndex));
+      restriction = LengthRestriction.EQUAL;
+      assertTrue(restriction.appliesTo(comparable, comparableIndex, 16,
+            targetIndex));
+   }
+   
+   public void testSameIndexes_EqualLength()
+   {
+      LengthRestriction restriction = LengthRestriction.LESS_OR_EQUAL;
+      comparableIndex.increment(5);
+      targetIndex.increment(5);
+      assertTrue(restriction.appliesTo(comparable, comparableIndex, 7,
+            targetIndex));
+      restriction = LengthRestriction.EQUAL;
+      assertTrue(restriction.appliesTo(comparable, comparableIndex, 7,
+            targetIndex));
+   }
+   
+   public void testZeroIndexes_LengthLessThan()
+   {
+      LengthRestriction restriction = LengthRestriction.LESS_OR_EQUAL;
+      assertTrue(restriction.appliesTo(comparable, comparableIndex, 10,
+            targetIndex));
+      restriction = LengthRestriction.EQUAL;
+      assertFalse(restriction.appliesTo(comparable, comparableIndex, 10,
+            targetIndex));
+   }
+
+   public void testDifferentIndexes_LengthLessThan()
+   {
+      LengthRestriction restriction = LengthRestriction.LESS_OR_EQUAL;
+      comparableIndex.increment(2);
+      assertTrue(restriction.appliesTo(comparable, comparableIndex, 10,
+            targetIndex));
+      restriction = LengthRestriction.EQUAL;
+      assertFalse(restriction.appliesTo(comparable, comparableIndex, 10,
+            targetIndex));
+   }
+   
+   public void testSameIndexes_LengthLessThan()
+   {
+      LengthRestriction restriction = LengthRestriction.LESS_OR_EQUAL;
+      comparableIndex.increment();
+      targetIndex.increment();
+      assertTrue(restriction.appliesTo(comparable, comparableIndex, 10,
+            targetIndex));
+      restriction = LengthRestriction.EQUAL;
+      assertFalse(restriction.appliesTo(comparable, comparableIndex, 10,
+            targetIndex));
+   }
+   
+   public void testZeroIndexes_LengthMoreThan()
+   {
+      LengthRestriction restriction = LengthRestriction.LESS_OR_EQUAL;
+      assertFalse(restriction.appliesTo(comparable, comparableIndex, 3,
+            targetIndex));
+      restriction = LengthRestriction.EQUAL;
+      assertFalse(restriction.appliesTo(comparable, comparableIndex, 3,
+            targetIndex));
+   }
+   
+   public void testDifferentIndexes_LengthMoreThan()
+   {
+      LengthRestriction restriction = LengthRestriction.LESS_OR_EQUAL;
+      targetIndex.increment();
+      assertFalse(restriction.appliesTo(comparable, comparableIndex, 7,
+            targetIndex));
+      restriction = LengthRestriction.EQUAL;
+      assertFalse(restriction.appliesTo(comparable, comparableIndex, 7,
+            targetIndex));
+   }
+
+   public void testSameIndexes_LengthMoreThan()
+   {
+      LengthRestriction restriction = LengthRestriction.LESS_OR_EQUAL;
+      comparableIndex.increment(4);
+      targetIndex.increment(4);
+      assertFalse(restriction.appliesTo(comparable, comparableIndex, 1,
+            targetIndex));
+      restriction = LengthRestriction.EQUAL;
+      assertFalse(restriction.appliesTo(comparable, comparableIndex, 1,
+            targetIndex));
+   }
+   
+   public void testEmptyComparableAndTarget()
+   {
+      LengthRestriction restriction = LengthRestriction.LESS_OR_EQUAL;
+      assertTrue(restriction.appliesTo(emptyComparable, comparableIndex, 0,
+            targetIndex));
+      restriction = LengthRestriction.EQUAL;
+      assertTrue(restriction.appliesTo(emptyComparable, comparableIndex, 0,
+            targetIndex));
+   }
+   
+   public void testEmptyComparable()
+   {
+      LengthRestriction restriction = LengthRestriction.LESS_OR_EQUAL;
+      assertTrue(restriction.appliesTo(emptyComparable, comparableIndex, 3,
+            targetIndex));
+      restriction = LengthRestriction.EQUAL;
+      assertFalse(restriction.appliesTo(emptyComparable, comparableIndex, 3,
+            targetIndex));
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/MatcherFactoryTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/MatcherFactoryTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/MatcherFactoryTest.java	2008-01-03 18:54:24 UTC (rev 68603)
@@ -0,0 +1,210 @@
+/*
+ * 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;
+
+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.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.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.PrefixFunction;
+import org.jboss.aop.joinpoint.graph.tree.search.match.State;
+
+import junit.framework.TestCase;
+
+/**
+ * Test of the {@link MatcherFactory} class.
+ * 
+ * @author Flavia Rainone
+ */
+public class MatcherFactoryTest extends TestCase
+{
+   private ComparableFactoryImpl factory;
+   private MatcherSequenceProfile seqProfile;
+   
+   public void setUp()
+   {
+      this.factory = new ComparableFactoryImpl();
+      this.seqProfile = new MatcherSequenceProfile(
+            MatcherProfile.PREFIX, MatcherProfile.PATTERN,
+            MatcherProfile.SUFFIX, MatcherProfile.SIMPLE);
+   }
+   
+   public void testSimpleMatchableExpression()
+   {
+      MatcherFactory.createSequence("anything/splitten/by/slash", factory,
+            seqProfile);
+      ComparableImpl[] comparables = new ComparableImpl[4];
+      assertEquals(4, factory.created.size());
+      comparables = (ComparableImpl[]) factory.created.toArray(comparables);
+      assertEquals(MatcherProfile.PREFIX, comparables[0].profile);
+      assertEquals("anything", comparables[0].expression);
+      assertEquals(MatcherProfile.PATTERN, comparables[1].profile);
+      assertEquals("splitten", comparables[1].expression);
+      assertEquals(MatcherProfile.PATTERN, comparables[2].profile);
+      assertEquals("by", comparables[2].expression);
+      assertEquals(MatcherProfile.SUFFIX, comparables[3].profile);
+      assertEquals("slash", comparables[3].expression);
+   }
+   
+   public void testEmptyPrefixMatchableExpression()
+   {
+      MatcherFactory.createSequence("/splitten/by/slash", factory, seqProfile);
+      ComparableImpl[] comparables = new ComparableImpl[4];
+      assertEquals(4, factory.created.size());
+      comparables = (ComparableImpl[]) factory.created.toArray(comparables);
+      assertEquals(MatcherProfile.PREFIX, comparables[0].profile);
+      assertEquals("", comparables[0].expression);
+      assertEquals(MatcherProfile.PATTERN, comparables[1].profile);
+      assertEquals("splitten", comparables[1].expression);
+      assertEquals(MatcherProfile.PATTERN, comparables[2].profile);
+      assertEquals("by", comparables[2].expression);
+      assertEquals(MatcherProfile.SUFFIX, comparables[3].profile);
+      assertEquals("slash", comparables[3].expression);
+   }
+
+   public void testEmptySuffixMatchableExpression()
+   {
+      MatcherFactory.createSequence("anything/splitten/by/", factory,
+            seqProfile);
+      ComparableImpl[] comparables = new ComparableImpl[4];
+      assertEquals(4, factory.created.size());
+      comparables = (ComparableImpl[]) factory.created.toArray(comparables);
+      assertEquals(MatcherProfile.PREFIX, comparables[0].profile);
+      assertEquals("anything", comparables[0].expression);
+      assertEquals(MatcherProfile.PATTERN, comparables[1].profile);
+      assertEquals("splitten", comparables[1].expression);
+      assertEquals(MatcherProfile.PATTERN, comparables[2].profile);
+      assertEquals("by", comparables[2].expression);
+      assertEquals(MatcherProfile.SUFFIX, comparables[3].profile);
+      assertEquals("", comparables[3].expression);
+   }
+   
+   public void testEmptyAffixesMatchableExpression()
+   {
+      MatcherFactory.createSequence("/splitten/", factory, seqProfile);
+      ComparableImpl[] comparables = new ComparableImpl[3];
+      assertEquals(3, factory.created.size());
+      comparables = (ComparableImpl[]) factory.created.toArray(comparables);
+      assertEquals(MatcherProfile.PREFIX, comparables[0].profile);
+      assertEquals("", comparables[0].expression);
+      assertEquals(MatcherProfile.PATTERN, comparables[1].profile);
+      assertEquals("splitten", comparables[1].expression);
+      assertEquals(MatcherProfile.SUFFIX, comparables[2].profile);
+      assertEquals("", comparables[2].expression);
+   }
+   
+   public void testOnlyAffixesMatchableExpression()
+   {
+      MatcherFactory.createSequence("splitten/by", factory, seqProfile);
+      ComparableImpl[] comparables = new ComparableImpl[2];
+      assertEquals(2, factory.created.size());
+      comparables = (ComparableImpl[]) factory.created.toArray(comparables);
+      assertEquals(MatcherProfile.PREFIX, comparables[0].profile);
+      assertEquals("splitten", comparables[0].expression);
+      assertEquals(MatcherProfile.SUFFIX, comparables[1].profile);
+      assertEquals("by", comparables[1].expression);
+   }
+   
+   public void testSlashMatchableExpression()
+   {
+      MatcherFactory.createSequence("/", factory, seqProfile);
+      ComparableImpl[] comparables = new ComparableImpl[2];
+      assertEquals(2, factory.created.size());
+      comparables = (ComparableImpl[]) factory.created.toArray(comparables);
+      assertEquals(MatcherProfile.PREFIX, comparables[0].profile);
+      assertEquals("", comparables[0].expression);
+      assertEquals(MatcherProfile.SUFFIX, comparables[1].profile);
+      assertEquals("", comparables[1].expression);
+   }
+   
+   public void testUniqueMatchableExpression()
+   {
+      MatcherFactory.createSequence("uniqueComparableExpression", factory,
+            seqProfile);
+      assertEquals(1, factory.created.size());
+      ComparableImpl[] comparables = new ComparableImpl[0];
+      comparables = (ComparableImpl[]) factory.created.toArray(comparables);
+      assertEquals(MatcherProfile.SIMPLE, comparables[0].profile);
+      assertEquals("uniqueComparableExpression", comparables[0].expression);
+   }
+   
+   /**
+    * Implementation of <code>ComparableFactory</code>. For tests purpose.
+    * 
+    * @author Flavia Rainone
+    */
+   private class ComparableFactoryImpl implements ComparableFactory
+   {
+      Collection created = new ArrayList();
+      
+      public char getSeparator()
+      {
+         return '/';
+      }
+
+      public void startCreation() { }
+      public void stopCreation()  { }
+      public Comparable create(String exp, MatcherProfile profile)
+      {
+         Comparable comparable = new ComparableImpl(exp, profile);
+         created.add(comparable);
+         return comparable;
+      }
+   }
+   
+   /**
+    * Implementation of comparable, is the comparable created by <code>
+    * ComparableFactoryImpl</code>.
+    * 
+    * @author Flavia Rainone
+    */
+   private class ComparableImpl implements Comparable
+   {
+      String expression;
+      MatcherProfile profile;
+      
+      public ComparableImpl(String expression, MatcherProfile profile)
+      {
+         this.expression = expression;
+         this.profile = profile;
+      }
+
+      public int getLength() {return 0; }
+      public int getPostPrefixLength() { return 0; }
+      public void saveState(Object comparisonState) {}
+      public void rollbackState(Object comparisonState) {}
+      public char getNextCharacter(Index comparableIndex,
+            Object comparisonState) { return 0; }
+      public char getNextCharacter(Index comparableIndex, Object target,
+            LengthRange targetLengthRange, Object comparisonState) { return 0; }
+      public PrefixFunction getPrefixFunction() { return null; }
+      public ComparisonResult compare(Object target, Index targetIndex,
+            Index comparableIndex, State comparisonState) { return null; }
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/MatcherTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/MatcherTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/MatcherTest.java	2008-01-03 18:54:24 UTC (rev 68603)
@@ -0,0 +1,535 @@
+/*
+ * 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.KeyPart;
+import org.jboss.aop.joinpoint.graph.tree.search.Flags;
+import org.jboss.aop.joinpoint.graph.tree.search.element.ComparableElementFactory;
+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 junit.framework.TestCase;
+
+/**
+ * Test of the {@link Matcher} class.
+ * 
+ * @author Flavia Rainone
+ */
+public class MatcherTest extends TestCase
+{
+   Matcher[] matcherSequence;
+   Matcher[] patternMatcherSequence;
+   Matcher[] suffixMatcherSequence;
+   Index comparableIndex;
+   Index targetIndex;
+   MatchingState looseState;
+   MatchingState tightState;
+   
+   public void setUp()
+   {
+      MatcherSequenceProfile seqProfile = new MatcherSequenceProfile(
+            MatcherProfile.PREFIX, MatcherProfile.SIMPLE,
+            MatcherProfile.SUFFIX, MatcherProfile.PATTERN);
+      ComparableElementFactory factory = ComparableElementFactory.getInstance();
+      factory.performCreationForProfile(MatcherProfile.PATTERN);
+      matcherSequence = MatcherFactory.createSequence(
+            "any.matchable.expression.toCompare", factory, seqProfile);
+      patternMatcherSequence = MatcherFactory.createSequence("uniqueElement",
+            ComparableElementFactory.getInstance(), seqProfile);
+      suffixMatcherSequence = MatcherFactory.createSequence("toCompare",
+            factory, new MatcherSequenceProfile(MatcherProfile.SUFFIX,
+            MatcherProfile.SUFFIX, MatcherProfile.SUFFIX, MatcherProfile.SUFFIX));
+      comparableIndex = new Index();
+      targetIndex = new Index();
+      looseState = new MatchingState();
+      tightState = new MatchingState();
+      tightState.getNextCharacter(factory.create("exp", null), comparableIndex,
+            "exp", new LengthRange((byte) 3, (byte) 6, (byte) 6));
+   }
+
+   public void testPrefixMatcherGetChar()
+   {
+      assertEquals('a', matcherSequence[0].getNextCharacter(comparableIndex,
+            looseState));
+      assertEquals('a', matcherSequence[0].getNextCharacter(comparableIndex,
+            tightState));
+      comparableIndex.increment();
+      assertEquals('n', matcherSequence[0].getNextCharacter(comparableIndex,
+            looseState));
+      assertEquals('n', matcherSequence[0].getNextCharacter(comparableIndex,
+            tightState));
+      comparableIndex.increment();
+      assertEquals('y', matcherSequence[0].getNextCharacter(comparableIndex,
+            looseState));
+      assertEquals('y', matcherSequence[0].getNextCharacter(comparableIndex,
+            tightState));
+      comparableIndex.increment();
+      assertEquals(KeyPart.KEY_ELEMENT_END, matcherSequence[0].
+            getNextCharacter(comparableIndex, looseState));
+      assertEquals(KeyPart.KEY_ELEMENT_END, matcherSequence[0].
+            getNextCharacter(comparableIndex, tightState));
+   }
+   
+   public void testSimpleMatcherGetChar()
+   {
+      assertEquals('m', matcherSequence[1].getNextCharacter(comparableIndex,
+            looseState));
+      assertEquals('m', matcherSequence[1].getNextCharacter(comparableIndex,
+            tightState));
+      comparableIndex.increment(3);
+      assertEquals('c', matcherSequence[1].getNextCharacter(comparableIndex,
+            looseState));
+      assertEquals('c', matcherSequence[1].getNextCharacter(comparableIndex,
+            tightState));
+      comparableIndex.increment(3);
+      assertEquals('b', matcherSequence[1].getNextCharacter(comparableIndex,
+            looseState));
+      assertEquals('b', matcherSequence[1].getNextCharacter(comparableIndex,
+            tightState));
+   }
+   
+   public void testPatternMatcherGetChar()
+   {
+      assertEquals(Flags.ALL, patternMatcherSequence[0].getNextCharacter(
+            comparableIndex, looseState));
+      assertEquals('u', patternMatcherSequence[0].getNextCharacter(
+            comparableIndex, tightState));
+      comparableIndex.increment();
+      assertEquals(Flags.ALL, patternMatcherSequence[0].getNextCharacter(
+            comparableIndex, looseState));
+      assertEquals('n', patternMatcherSequence[0].getNextCharacter(
+            comparableIndex, tightState));
+      comparableIndex.increment(5);
+      assertEquals(Flags.ALL, patternMatcherSequence[0].getNextCharacter(
+            comparableIndex, looseState));
+      assertEquals('E', patternMatcherSequence[0].getNextCharacter(
+            comparableIndex, tightState));
+   }
+   
+   public void testSuffixMatcherGetChar()
+   {
+      assertEquals(Flags.ALL, suffixMatcherSequence[0].getNextCharacter(
+            comparableIndex, looseState));
+      assertEquals('t', suffixMatcherSequence[0].getNextCharacter(
+            comparableIndex, tightState));
+      comparableIndex.increment(4);
+      assertEquals(Flags.ALL, suffixMatcherSequence[0].getNextCharacter(
+            comparableIndex, looseState));
+      assertEquals('m', suffixMatcherSequence[0].getNextCharacter(
+            comparableIndex, tightState));
+      comparableIndex.increment(2);
+      assertEquals(Flags.ALL, suffixMatcherSequence[0].getNextCharacter(
+            comparableIndex, looseState));
+      assertEquals('a', suffixMatcherSequence[0].getNextCharacter(
+            comparableIndex, tightState));
+   }
+   
+   public void testPrefixMatcher1()
+   {
+      MatchingResult result = matcherSequence[0].matches("any", 3, targetIndex,
+            comparableIndex, looseState);
+      assertEquals(MatchingResult.POSITIVE_MATCH, result);
+      assertEquals(3, comparableIndex.getValue());
+      assertEquals(3, targetIndex.getValue());
+   }
+   
+   public void testPrefixMatcher2()
+   {
+      MatchingResult result = matcherSequence[0].matches("any",
+            new LengthRange((byte) 3, (byte) 5, (byte) 5), targetIndex,
+            comparableIndex, looseState);
+      assertEquals(MatchingResult.POSITIVE_MATCH, result);
+      assertEquals(3, comparableIndex.getValue());
+      assertEquals(3, targetIndex.getValue());
+   }
+
+   public void testPrefixMatcher3()
+   {
+      MatchingResult result = matcherSequence[0].matches("", 0, targetIndex,
+            comparableIndex, looseState);
+      assertEquals(MatchingResult.NEGATIVE_MATCH, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, targetIndex.getValue());
+   }
+   
+   public void testPrefixMatcher4()
+   {
+      MatchingResult result = matcherSequence[0].matches("",
+            new LengthRange((byte) 0, (byte) 1, (byte) 5), targetIndex,
+            comparableIndex, looseState);
+      assertEquals(MatchingResult.PARTIAL_MATCH, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, targetIndex.getValue());
+   }
+   
+   public void testPrefixMatcher5()
+   {
+      MatchingResult result = matcherSequence[0].matches("",
+            new LengthRange((byte) 0, (byte) 1, (byte) 2), targetIndex,
+            comparableIndex, looseState);
+      assertEquals(MatchingResult.NEGATIVE_MATCH, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, targetIndex.getValue());
+   }
+   
+   public void testPrefixMatcher6()
+   {
+      MatchingResult result = matcherSequence[0].matches("an",2, targetIndex,
+            comparableIndex, looseState);
+      assertEquals(MatchingResult.NEGATIVE_MATCH, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, targetIndex.getValue());
+   }
+   
+   public void testPrefixMatcher7()
+   {
+      MatchingResult result = matcherSequence[0].matches("an",
+            new LengthRange((byte) 2, (byte) 4, (byte) 8), targetIndex,
+            comparableIndex, looseState);
+      assertEquals(MatchingResult.PARTIAL_MATCH, result);
+      assertEquals(2, comparableIndex.getValue());
+      assertEquals(2, targetIndex.getValue());
+   }
+   
+   public void testPrefixMatcher8()
+   {
+      targetIndex.increment();
+      MatchingResult result = matcherSequence[0].matches("can",
+            new LengthRange((byte) 2, (byte) 4, (byte) 8), targetIndex,
+            comparableIndex, looseState);
+      assertEquals(MatchingResult.PARTIAL_MATCH, result);
+      assertEquals(2, comparableIndex.getValue());
+      assertEquals(3, targetIndex.getValue());
+   }
+   
+   public void testSimpleMatcher1()
+   {
+      MatchingResult result = matcherSequence[2].matches("expression", 10,
+            targetIndex, comparableIndex, looseState);
+      assertEquals(MatchingResult.POSITIVE_MATCH, result);
+      assertEquals(10, comparableIndex.getValue());
+      assertEquals(10, targetIndex.getValue());
+   }
+   
+   public void testSimpleMatcher2()
+   {
+      MatchingResult result = matcherSequence[2].matches("expression",
+            new LengthRange((byte) 10, (byte) 11, (byte) 20),
+            targetIndex, comparableIndex, looseState);
+      assertEquals(MatchingResult.NEGATIVE_MATCH, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, targetIndex.getValue());
+   }
+   
+   public void testSimpleMatcher3()
+   {
+      targetIndex.increment(3);
+      MatchingResult result = matcherSequence[2].matches("anyexpresZion", 13,
+            targetIndex, comparableIndex, looseState);
+      assertEquals(MatchingResult.NEGATIVE_MATCH, result);
+      assertEquals(6, comparableIndex.getValue());
+      assertEquals(9, targetIndex.getValue());
+   }
+
+   public void testSimpleMatcher4()
+   {
+      targetIndex.increment(3);
+      MatchingResult result = matcherSequence[2].matches("anyexpresZio",
+            new LengthRange((byte) 12, (byte) 13, (byte) 20),
+            targetIndex, comparableIndex, looseState);
+      assertEquals(MatchingResult.NEGATIVE_MATCH, result);
+      assertEquals(6, comparableIndex.getValue());
+      assertEquals(9, targetIndex.getValue());
+   }
+   
+   public void testSimpleMatcher5()
+   {
+      MatchingResult result = matcherSequence[2].matches("anyexpresZion", 13,
+            targetIndex, comparableIndex, looseState);
+      assertEquals(MatchingResult.NEGATIVE_MATCH, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, targetIndex.getValue());
+   }
+
+   public void testSimpleMatcher6()
+   {
+      MatchingResult result = matcherSequence[2].matches("anyexpresZion",
+            new LengthRange((byte) 13, (byte) 13, (byte) 20),
+            targetIndex, comparableIndex, looseState);
+      assertEquals(MatchingResult.NEGATIVE_MATCH, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, targetIndex.getValue());
+   }
+   
+   public void testSimpleMatcher7()
+   {
+      MatchingResult result = matcherSequence[2].matches("anything", 8,
+            targetIndex, comparableIndex, looseState);
+      assertEquals(MatchingResult.NEGATIVE_MATCH, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, targetIndex.getValue());
+   }
+
+   public void testSimpleMatcher8()
+   {
+      MatchingResult result = matcherSequence[2].matches("anything",
+            new LengthRange((byte) 8, (byte) 8, (byte) 8),
+            targetIndex, comparableIndex, looseState);
+      assertEquals(MatchingResult.NEGATIVE_MATCH, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, targetIndex.getValue());
+   }
+   
+   public void testSimpleMatcher9()
+   {
+      targetIndex.increment(11);
+      comparableIndex.increment(6);
+      MatchingResult result = matcherSequence[2].matches("anything123sn", 13,
+            targetIndex, comparableIndex, looseState);
+      assertEquals(MatchingResult.NEGATIVE_MATCH, result);
+      assertEquals(6, comparableIndex.getValue());
+      assertEquals(11, targetIndex.getValue());
+   }
+
+   public void testSimpleMatcher10()
+   {
+      targetIndex.increment(11);
+      comparableIndex.increment(6);
+      MatchingResult result = matcherSequence[2].matches("anything12sn",
+            new LengthRange((byte) 12, (byte) 13, (byte) 15),
+            targetIndex, comparableIndex, looseState);
+      assertEquals(MatchingResult.NEGATIVE_MATCH, result);
+      assertEquals(6, comparableIndex.getValue());
+      assertEquals(11, targetIndex.getValue());
+   }
+   
+   public void testSimpleMatcher11()
+   {
+      targetIndex.increment(11);
+      comparableIndex.increment(6);
+      MatchingResult result = matcherSequence[2].matches("anything123s",
+            new LengthRange((byte) 12, (byte) 13, (byte) 15),
+            targetIndex, comparableIndex, looseState);
+      assertEquals(MatchingResult.PARTIAL_MATCH, result);
+      assertEquals(7, comparableIndex.getValue());
+      assertEquals(12, targetIndex.getValue());
+   }
+   
+   public void testSuffixMatcher1()
+   {
+      MatchingResult result = suffixMatcherSequence[0].matches("toCompare",
+            9, targetIndex, comparableIndex, looseState);
+      assertEquals(MatchingResult.POSITIVE_MATCH, result);
+      assertEquals(9, comparableIndex.getValue());
+      assertEquals(9, targetIndex.getValue());
+   }
+
+   public void testSuffixMatcher2()
+   {
+      MatchingResult result = suffixMatcherSequence[0].matches("toCompare",
+            new LengthRange((byte) 9, (byte) 9, (byte) 10),
+            targetIndex, comparableIndex, looseState);
+      assertEquals(MatchingResult.POSITIVE_MATCH, result);
+      assertEquals(9, comparableIndex.getValue());
+      assertEquals(9, targetIndex.getValue());
+   }
+   
+   public void testSuffixMatcher3()
+   {
+      MatchingResult result = suffixMatcherSequence[0].matches("toCompareAny",
+            11, targetIndex, comparableIndex, looseState);
+      assertEquals(MatchingResult.NEGATIVE_MATCH, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(3, targetIndex.getValue());
+   }
+   
+   public void testSuffixMatcher4()
+   {
+      MatchingResult result = suffixMatcherSequence[0].matches("toCompare",
+            new LengthRange((byte) 9, (byte) 11, (byte) 17), targetIndex,
+            comparableIndex, looseState);
+      assertEquals(MatchingResult.NEGATIVE_MATCH, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(9, targetIndex.getValue());
+   }
+
+   public void testSuffixMatcher5()
+   {
+      MatchingResult result = suffixMatcherSequence[0].matches("toCompare",
+            new LengthRange((byte) 9, (byte) 11, (byte) 18), targetIndex,
+            comparableIndex, looseState);
+      assertEquals(MatchingResult.PARTIAL_MATCH, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(9, targetIndex.getValue());
+   }
+   
+   public void testSuffixMatcher6()
+   {
+      comparableIndex.increment(3);
+      targetIndex.increment(2);
+      MatchingResult result = suffixMatcherSequence[0].matches(
+            "toComtoComtoCompare", 19, targetIndex, comparableIndex, looseState);
+      assertEquals(MatchingResult.POSITIVE_MATCH, result);
+      assertEquals(9, comparableIndex.getValue());
+      assertEquals(19, targetIndex.getValue());
+   }
+
+   public void testSuffixMatcher7()
+   {
+      comparableIndex.increment(3);
+      targetIndex.increment(2);
+      MatchingResult result = suffixMatcherSequence[0].matches(
+            "toComtoComtoCompare",
+            new LengthRange((byte) 19, (byte) 19, (byte) 21), targetIndex,
+            comparableIndex, looseState);
+      assertEquals(MatchingResult.POSITIVE_MATCH, result);
+      assertEquals(9, comparableIndex.getValue());
+      assertEquals(19, targetIndex.getValue());
+   }
+   
+   public void testSuffixMatcher8()
+   {
+      comparableIndex.increment(3);
+      targetIndex.increment(2);
+      MatchingResult result = suffixMatcherSequence[0].matches(
+            "toComtoComtoCompare1", 19, targetIndex, comparableIndex, looseState);
+      assertEquals(MatchingResult.NEGATIVE_MATCH, result);
+      assertEquals(9, comparableIndex.getValue());
+      assertEquals(19, targetIndex.getValue());
+   }
+
+   public void testSuffixMatcher9()
+   {
+      comparableIndex.increment(3);
+      targetIndex.increment(2);
+      MatchingResult result = suffixMatcherSequence[0].matches(
+            "toComtoComtoCompare1",
+            new LengthRange((byte) 19, (byte) 19, (byte) 21), targetIndex,
+            comparableIndex, looseState);
+      assertEquals(MatchingResult.NEGATIVE_MATCH, result);
+      assertEquals(9, comparableIndex.getValue());
+      assertEquals(19, targetIndex.getValue());
+   }
+   
+   public void testSuffixMatcher10()
+   {
+      targetIndex.increment(2);
+      MatchingResult result = suffixMatcherSequence[0].matches(
+            "toComtoComtoComp", 16, targetIndex, comparableIndex, looseState);
+      assertEquals(MatchingResult.NEGATIVE_MATCH, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(8, targetIndex.getValue());
+   }
+   
+   public void testSuffixMatcher11()
+   {
+      targetIndex.increment(2);
+      MatchingResult result = suffixMatcherSequence[0].matches(
+            "toComtoComtoComp",
+            new LengthRange((byte) 16, (byte) 19, (byte) 21), targetIndex,
+            comparableIndex, looseState);
+      assertEquals(MatchingResult.PARTIAL_MATCH, result);
+      assertEquals(6, comparableIndex.getValue());
+      assertEquals(16, targetIndex.getValue());
+   }
+   
+   public void testSuffixMatcher12()
+   {
+      targetIndex.increment(2);
+      MatchingResult result = suffixMatcherSequence[0].matches("toComtoComtoCo",
+            14, targetIndex, comparableIndex, looseState);
+      assertEquals(MatchingResult.NEGATIVE_MATCH, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(10, targetIndex.getValue());
+   }
+   
+   public void testSuffixMatcher13()
+   {
+      targetIndex.increment(2);
+      MatchingResult result = suffixMatcherSequence[0].matches("atoComtoComtoC",
+            new LengthRange((byte) 14, (byte) 15, (byte) 16), targetIndex,
+            comparableIndex, looseState);
+      assertEquals(MatchingResult.NEGATIVE_MATCH, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(11, targetIndex.getValue());
+   }
+   
+   public void testPatternMatcher1()
+   {
+      MatchingResult result = patternMatcherSequence[0].matches("uniqueElement",
+            13, targetIndex, comparableIndex, looseState);
+      assertEquals(MatchingResult.POSITIVE_MATCH, result);
+      assertEquals(13, comparableIndex.getValue());
+      assertEquals(13, targetIndex.getValue());
+   }
+   
+   public void testPatternMatcher2()
+   {
+      MatchingResult result = patternMatcherSequence[0].matches("uniqueElement",
+            new LengthRange((byte) 13, (byte) 13, (byte) 21),
+            targetIndex, comparableIndex, looseState);
+      assertEquals(MatchingResult.POSITIVE_MATCH, result);
+      assertEquals(13, comparableIndex.getValue());
+      assertEquals(13, targetIndex.getValue());
+   }
+   
+   public void testPatternMatcher3()
+   {
+      MatchingResult result = patternMatcherSequence[0].matches(
+            "uniqueuniqueuniqueElementunique",
+            new LengthRange((byte) 31, (byte) 40, (byte) 51),
+            targetIndex, comparableIndex, looseState);
+      assertEquals(MatchingResult.POSITIVE_MATCH, result);
+      assertEquals(13, comparableIndex.getValue());
+      assertEquals(25, targetIndex.getValue());
+   }
+   
+   public void testPatternMatcher4()
+   {
+      targetIndex.increment(5);
+      MatchingResult result = patternMatcherSequence[0].matches(
+            "uniqueuniqueuniqueElemen",
+            new LengthRange((byte) 24, (byte) 40, (byte) 51),
+            targetIndex, comparableIndex, looseState);
+      assertEquals(MatchingResult.PARTIAL_MATCH, result);
+      assertEquals(12, comparableIndex.getValue());
+      assertEquals(24, targetIndex.getValue());
+   }
+   
+   public void testPatternMatcher5()
+   {
+      targetIndex.increment(5);
+      MatchingResult result = patternMatcherSequence[0].matches(
+            "uniqueuniqueuniqueElem",
+            new LengthRange((byte) 22, (byte) 23, (byte) 24),
+            targetIndex, comparableIndex, looseState);
+      assertEquals(MatchingResult.NEGATIVE_MATCH, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(12, targetIndex.getValue());
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/MatchingStateTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/MatchingStateTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/match/MatchingStateTest.java	2008-01-03 18:54:24 UTC (rev 68603)
@@ -0,0 +1,622 @@
+/*
+ * 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.lang.reflect.Field;
+
+import org.jboss.aop.joinpoint.graph.tree.search.Flags;
+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.ComparisonEndState;
+import org.jboss.aop.joinpoint.graph.tree.search.match.ComparisonStartState;
+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.MatcherProfile;
+import org.jboss.aop.joinpoint.graph.tree.search.match.MatchingState;
+
+import junit.framework.TestCase;
+
+/**
+ * Test of the {@link MatchingState} class.
+ * 
+ * @author Flavia Rainone
+ */
+public class MatchingStateTest extends TestCase
+{
+   MatchingState state;
+   ExtendedIndex comparableIndex;
+   ExtendedIndex targetIndex;
+   Comparable comparable;
+   Comparable unitaryComparable;
+   Comparable emptyComparable;
+   Field comparisonEndStateField;
+   Field comparisonStartStateField;
+   Field postponedComparisonField;
+   
+   public void setUp() throws Exception
+   {
+      // create indexes
+      comparableIndex = new ExtendedIndex();
+      targetIndex = new ExtendedIndex();
+      // create comparable
+      ComparableElementFactory factory = ComparableElementFactory.getInstance();
+      factory.performCreationForProfile(MatcherProfile.PATTERN);
+      factory.startCreation();
+      comparable = factory.create("abcabca", null);
+      unitaryComparable = factory.create("a", null);
+      emptyComparable = factory.create("", null);
+      factory.stopCreation();
+      // initialize comparisonStartStateField
+      comparisonStartStateField = MatchingState.class.getDeclaredField(
+            "comparisonStartState");
+      comparisonStartStateField.setAccessible(true);
+      // initialize comparisonEndStateField
+      comparisonEndStateField = MatchingState.class.getDeclaredField(
+            "comparisonEndState");
+      comparisonEndStateField.setAccessible(true);
+      // create and assert state
+      state = new MatchingState();
+      assertStateValues(ComparisonStartState.CURRENT_TARGET,
+            ComparisonEndState.LOOSE);
+      // postponedComparison field
+      postponedComparisonField = Index.class.getDeclaredField(
+            "postponedComparison");
+      postponedComparisonField.setAccessible(true);
+   }
+   
+   public void testGetNextCharTightComparison1() throws Exception
+   {
+      char nextChar = state.getNextCharacter(comparable, comparableIndex, "abc",
+            new LengthRange( (byte) 3, (byte) 10, (byte) 10));
+      assertEquals('a', nextChar);
+      assertStateValues(ComparisonStartState.CURRENT_TARGET,
+            ComparisonEndState.TIGHT);
+   }
+   
+   public void testGetNextCharTightComparison2() throws Exception
+   {
+      comparableIndex.increment(5);
+      char nextChar = state.getNextCharacter(comparable, comparableIndex, "x",
+            new LengthRange( (byte) 1, (byte) 3, (byte) 3));
+      assertEquals('c', nextChar);
+      assertStateValues(ComparisonStartState.CURRENT_TARGET,
+            ComparisonEndState.TIGHT);
+   }
+
+   public void testGetNextCharTightComparison3() throws Exception
+   {
+      comparableIndex.increment(4);
+      char nextChar = state.getNextCharacter(comparable, comparableIndex, "abc",
+            new LengthRange( (byte) 3, (byte) 6, (byte) 6));
+      assertEquals('b', nextChar);
+      assertStateValues(ComparisonStartState.CURRENT_TARGET,
+            ComparisonEndState.TIGHT);
+   }
+   
+   public void testGetNextCharLooseComparison() throws Exception
+   {
+      char nextChar = state.getNextCharacter(comparable, comparableIndex, "abc",
+            new LengthRange( (byte) 3, (byte) 10, (byte) 15));
+      assertEquals(Flags.ALL, nextChar);
+      assertStateValues(ComparisonStartState.CURRENT_TARGET,
+            ComparisonEndState.LOOSE);
+   }
+
+   public void testGetNextCharComparisonPostponed() throws Exception
+   {
+      LengthRange lengthRange = new LengthRange((byte) 1, (byte) 10, (byte) 11);
+      state.tightenComparison(comparable, comparableIndex, lengthRange,
+            targetIndex);
+      assertStateValues(ComparisonStartState.NEXT_SUFFIXES,
+            ComparisonEndState.LOOSE);
+      char nextChar = state.getNextCharacter(comparable, comparableIndex, "abc",
+            lengthRange);
+      assertEquals(Flags.ALL, nextChar);
+      assertStateValues(ComparisonStartState.NEXT_SUFFIXES,
+            ComparisonEndState.LOOSE);
+   }
+
+   public void testGetNextCharTightIndex() throws Exception
+   {
+      LengthRange lengthRange = new LengthRange((byte) 1, (byte) 10, (byte) 11);
+      state.tightenComparison(comparable, comparableIndex, lengthRange,
+            targetIndex);
+      assertStateValues(ComparisonStartState.NEXT_SUFFIXES,
+            ComparisonEndState.LOOSE);
+      targetIndex.update(lengthRange);
+      lengthRange = new LengthRange((byte) 1, (byte) 9, (byte) 9);
+      state.tightenComparison(comparable, comparableIndex, lengthRange,
+            targetIndex);
+      assertStateValues(ComparisonStartState.NEXT_SUFFIXES,
+            ComparisonEndState.TIGHT);
+      char nextChar = state.getNextCharacter(comparable, comparableIndex, "abc",
+            lengthRange);
+      assertEquals(Flags.ALL, nextChar);
+      assertStateValues(ComparisonStartState.NEXT_SUFFIXES,
+            ComparisonEndState.TIGHT);
+   }
+   
+   public void testGetNextCharStateless() throws Exception
+   {
+      char nextChar = state.getNextCharacter(comparable, comparableIndex);
+      assertEquals(Flags.ALL, nextChar);
+      assertStateValues(ComparisonStartState.CURRENT_TARGET,
+            ComparisonEndState.LOOSE);
+      comparableIndex.increment(6);
+      nextChar = state.getNextCharacter(comparable, comparableIndex);
+      assertEquals(Flags.ALL, nextChar);
+      assertStateValues(ComparisonStartState.CURRENT_TARGET,
+            ComparisonEndState.LOOSE);
+      comparableIndex.increment();
+      nextChar = state.getNextCharacter(comparable, comparableIndex);
+      assertEquals(Flags.ALL, nextChar);
+      assertStateValues(ComparisonStartState.CURRENT_TARGET,
+            ComparisonEndState.LOOSE);
+   }
+   
+   public void testTightenTightComparison1() throws Exception
+   {
+      state.tightenComparison(comparable, comparableIndex, 7, targetIndex);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertStateValues(ComparisonStartState.CURRENT_TARGET,
+            ComparisonEndState.TIGHT);
+   }
+
+   public void testTightenTightComparison2() throws Exception
+   {
+      comparableIndex.increment(3);
+      state.tightenComparison(comparable, comparableIndex, 4, targetIndex);
+      assertEquals(3, comparableIndex.getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertStateValues(ComparisonStartState.CURRENT_TARGET,
+            ComparisonEndState.TIGHT);
+   }
+   
+   public void testTightenTightComparison3() throws Exception
+   {
+      // tight comparison with negative difference
+      comparableIndex.increment(5);
+      targetIndex.increment(9);
+      state.tightenComparison(comparable, comparableIndex, 10, targetIndex);
+      assertEquals(5, comparableIndex.getValue());
+      assertEquals(9, targetIndex.getValue());
+      assertStateValues(ComparisonStartState.CURRENT_TARGET,
+            ComparisonEndState.TIGHT);
+   }
+   
+   public void testTightenLooseComparison1() throws Exception
+   {
+      state.tightenComparison(comparable, comparableIndex, 10, targetIndex);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertStateValues(ComparisonStartState.CURRENT_TARGET,
+            ComparisonEndState.LOOSE);
+   }
+   
+   public void testTightenLooseComparison2() throws Exception
+   {
+      comparableIndex.increment();
+      state.tightenComparison(comparable, comparableIndex, 10, targetIndex);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertStateValues(ComparisonStartState.CURRENT_TARGET,
+            ComparisonEndState.LOOSE);
+   }
+   
+   public void testTightenLooseComparison3() throws Exception
+   {
+      comparableIndex.increment(5);
+      targetIndex.increment(2);
+      state.tightenComparison(comparable, comparableIndex, 10, targetIndex);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertStateValues(ComparisonStartState.CURRENT_TARGET,
+            ComparisonEndState.LOOSE);
+   }
+      
+   public void testTightenLooseComparison4() throws Exception
+   {
+      comparableIndex.increment(3);
+      targetIndex.increment(3);
+      state.tightenComparison(comparable, comparableIndex, 10, targetIndex);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertStateValues(ComparisonStartState.CURRENT_TARGET,
+            ComparisonEndState.LOOSE);
+   }
+   
+   public void testTightenLooseComparison5() throws Exception
+   {
+      comparableIndex.increment(3);
+      targetIndex.increment(4);
+      state.tightenComparison(comparable, comparableIndex, 10, targetIndex);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(4, targetIndex.getValue());
+      assertStateValues(ComparisonStartState.CURRENT_TARGET,
+            ComparisonEndState.LOOSE);
+   }
+   
+   public void testTightenLooseComparison6() throws Exception
+   {
+      comparableIndex.increment(4);
+      targetIndex.increment(5);
+      state.tightenComparison(comparable, comparableIndex, 10, targetIndex);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(5, targetIndex.getValue());
+      assertStateValues(ComparisonStartState.CURRENT_TARGET,
+            ComparisonEndState.LOOSE);
+   }
+   
+   public void testTightenLooseComparison7() throws Exception
+   {
+      comparableIndex.increment(6);
+      targetIndex.increment(3);
+      state.tightenComparison(comparable, comparableIndex, 10, targetIndex);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertStateValues(ComparisonStartState.CURRENT_TARGET,
+            ComparisonEndState.LOOSE);
+   }
+   
+   public void testTightenLooseComparison8() throws Exception
+   {
+      comparableIndex.increment(6);
+      targetIndex.increment(6);
+      state.tightenComparison(comparable, comparableIndex, 10, targetIndex);
+      assertEquals(3, comparableIndex.getValue());
+      assertEquals(6, targetIndex.getValue());
+      assertStateValues(ComparisonStartState.CURRENT_TARGET,
+            ComparisonEndState.LOOSE);
+   }
+
+   public void testTightenLooseComparison9() throws Exception
+   {
+      comparableIndex.increment(2);
+      targetIndex.increment(2);
+      LengthRange lengthRange = new LengthRange((byte) 7, (byte) 7, (byte) 10);
+      state.tightenComparison(comparable, comparableIndex, lengthRange,
+            targetIndex);
+      assertEquals(2, comparableIndex.getValue());
+      assertEquals(2, targetIndex.getValue());
+      assertStateValues(ComparisonStartState.CURRENT_TARGET,
+            ComparisonEndState.LOOSE);
+   }
+
+   public void testTightenLooseComparison10() throws Exception
+   {
+      comparableIndex.increment(2);
+      LengthRange lengthRange = new LengthRange((byte) 1, (byte) 5, (byte) 8);
+      state.tightenComparison(comparable, comparableIndex, lengthRange,
+            targetIndex);
+      assertEquals(2, comparableIndex.getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertStateValues(ComparisonStartState.CURRENT_TARGET,
+            ComparisonEndState.LOOSE);
+   }
+
+   public void testTightenLooseComparison11() throws Exception
+   {
+      LengthRange lengthRange = new LengthRange((byte) 1, (byte) 7, (byte) 8);
+      state.tightenComparison(comparable, comparableIndex, lengthRange,
+            targetIndex);
+      assertEquals(0, comparableIndex.getValue());
+      assertFalse(comparableIndex.isValueChanged());
+      assertEquals(0, targetIndex.getValue());
+      assertStateValues(ComparisonStartState.CURRENT_TARGET,
+            ComparisonEndState.LOOSE);
+   }
+   
+   public void testTightenPostponedComparison1() throws Exception
+   {
+      LengthRange lengthRange = new LengthRange((byte) 1, (byte) 8, (byte) 8);
+      state.tightenComparison(comparable, comparableIndex, lengthRange,
+            targetIndex);
+      assertEquals(0, comparableIndex.getValue());
+      assertTrue(comparableIndex.isValueChanged());
+      assertEquals(1, targetIndex.getValue());
+      assertStateValues(ComparisonStartState.NEXT_SUFFIX_FIRST_COMPONENT,
+            ComparisonEndState.LOOSE);
+      assertPostponedComparisonValue(true);
+   }
+   
+   public void testTightenPostponedComparison2() throws Exception
+   {
+      LengthRange lengthRange = new LengthRange((byte) 4, (byte) 12, (byte) 20);
+      state.tightenComparison(comparable, comparableIndex, lengthRange,
+            targetIndex);
+      assertEquals(0, comparableIndex.getValue());
+      assertTrue(comparableIndex.isValueChanged());
+      assertEquals(5, targetIndex.getValue());
+      assertStateValues(ComparisonStartState.NEXT_SUFFIXES,
+            ComparisonEndState.LOOSE);
+      assertPostponedComparisonValue(true);
+   }
+   
+   public void testTightenPostPonedComparison3() throws Exception
+   {
+      testTightenLooseComparison2();
+      LengthRange lengthRange = new LengthRange((byte) 1, (byte) 9, (byte) 13);
+      targetIndex.update(lengthRange);
+      state.tightenComparison(comparable, comparableIndex, lengthRange,
+            targetIndex);
+      assertEquals(0, comparableIndex.getValue());
+      assertTrue(comparableIndex.isValueChanged());
+      assertEquals(2, targetIndex.getValue());
+      assertStateValues(ComparisonStartState.NEXT_SUFFIXES,
+            ComparisonEndState.LOOSE);
+      assertPostponedComparisonValue(true);
+   }
+   
+   public void testTightenPostPonedComparison4() throws Exception
+   {
+      testTightenLooseComparison2();
+      LengthRange lengthRange = new LengthRange((byte) 3, (byte) 9, (byte) 13);
+      targetIndex.update(lengthRange);
+      state.tightenComparison(comparable, comparableIndex, lengthRange,
+            targetIndex);
+      assertEquals(0, comparableIndex.getValue());
+      assertTrue(comparableIndex.isValueChanged());
+      assertEquals(2, targetIndex.getValue());
+      assertStateValues(ComparisonStartState.CURRENT_TARGET,
+            ComparisonEndState.LOOSE);
+      assertPostponedComparisonValue(false);
+   }
+   
+   public void testTightenTightIndex1() throws Exception
+   {
+      this.testTightenPostponedComparison2();
+      LengthRange lengthRange = new LengthRange((byte) 3, (byte) 13, (byte) 13);
+      state.tightenComparison(comparable, comparableIndex, lengthRange,
+            targetIndex);
+      assertEquals(0, comparableIndex.getValue());
+      assertTrue(comparableIndex.isValueChanged());
+      assertEquals(6, targetIndex.getValue());
+      assertTrue(targetIndex.isValueChanged());
+      assertStateValues(ComparisonStartState.NEXT_SUFFIXES,
+            ComparisonEndState.LOOSE);
+      assertPostponedComparisonValue(true);
+      
+      targetIndex.update(lengthRange);
+      lengthRange = new LengthRange((byte) 2, (byte) 9, (byte) 10);
+      state.tightenComparison(comparable, comparableIndex, lengthRange,
+            targetIndex);
+      assertEquals(0, comparableIndex.getValue());
+      assertFalse(comparableIndex.isValueChanged());
+      assertEquals(3, targetIndex.getValue());
+      assertFalse(targetIndex.isValueChanged());
+      assertStateValues(ComparisonStartState.NEXT_SUFFIXES,
+            ComparisonEndState.TIGHT);
+      assertPostponedComparisonValue(true);
+   }
+
+   public void testTightenTightIndex2() throws Exception
+   {
+      this.testTightenPostponedComparison2();
+      LengthRange lengthRange = new LengthRange((byte) 3, (byte) 13, (byte) 13);
+      state.tightenComparison(comparable, comparableIndex, lengthRange,
+            targetIndex);
+      assertEquals(0, comparableIndex.getValue());
+      assertTrue(comparableIndex.isValueChanged());
+      assertEquals(6, targetIndex.getValue());
+      assertTrue(targetIndex.isValueChanged());
+      assertStateValues(ComparisonStartState.NEXT_SUFFIXES,
+            ComparisonEndState.LOOSE);
+      assertPostponedComparisonValue(true);
+      
+      targetIndex.update(lengthRange);
+      lengthRange = new LengthRange((byte) 1, (byte) 10, (byte) 10);
+      state.tightenComparison(comparable, comparableIndex, lengthRange,
+            targetIndex);
+      assertEquals(0, comparableIndex.getValue());
+      assertFalse(comparableIndex.isValueChanged());
+      assertEquals(3, targetIndex.getValue());
+      assertFalse(targetIndex.isValueChanged());
+      assertStateValues(ComparisonStartState.NEXT_SUFFIXES,
+            ComparisonEndState.TIGHT);
+      assertPostponedComparisonValue(true);
+      
+      targetIndex.update(lengthRange);
+      lengthRange = new LengthRange((byte) 4, (byte) 9, (byte) 9);
+      state.tightenComparison(comparable, comparableIndex, lengthRange,
+            targetIndex);
+      assertEquals(0, comparableIndex.getValue());
+      assertFalse(comparableIndex.isValueChanged());
+      assertEquals(2, targetIndex.getValue());
+      assertFalse(targetIndex.isValueChanged());
+      assertStateValues(ComparisonStartState.CURRENT_TARGET,
+            ComparisonEndState.TIGHT);
+      assertPostponedComparisonValue(false);
+   }
+   
+   public void testLoosePostponeComparisonTransition() throws Exception
+   {
+      LengthRange lengthRange = new LengthRange((byte) 5, (byte) 15, (byte) 30);
+      state.tightenComparison(comparable, comparableIndex, lengthRange,
+            targetIndex);
+      assertStateValues(ComparisonStartState.NEXT_SUFFIXES,
+            ComparisonEndState.LOOSE);
+      targetIndex.update(lengthRange);
+   }
+
+   public void testPostponeComparisonLooseTransition1() throws Exception
+   {
+      this.testLoosePostponeComparisonTransition();
+      LengthRange lengthRange = new LengthRange((byte) 20, (byte) 25,
+            (byte) 25);
+      state.tightenComparison(comparable, comparableIndex, lengthRange,
+            targetIndex);
+      assertStateValues(ComparisonStartState.CURRENT_TARGET,
+            ComparisonEndState.LOOSE);
+   }
+
+   public void testPostponeComparisonLooseTransition2() throws Exception
+   {
+      this.testLoosePostponeComparisonTransition();
+      state.tightenComparison(comparable, comparableIndex, 21, targetIndex);
+      assertStateValues(ComparisonStartState.NEXT_SUFFIXES,
+            ComparisonEndState.LOOSE);
+   }
+   
+   public void testPostponeComparisonLooseTransition3() throws Exception
+   {
+      this.testLoosePostponeComparisonTransition();
+      LengthRange lengthRange = new LengthRange((byte) 7, (byte) 12, (byte) 13);
+      state.tightenComparison(comparable, comparableIndex, lengthRange,
+            targetIndex);
+      assertStateValues(ComparisonStartState.CURRENT_TARGET,
+            ComparisonEndState.LOOSE);
+   }
+   
+   public void testPostponeComparisonTightIndexTransition() throws Exception
+   {
+      this.testLoosePostponeComparisonTransition();
+      LengthRange lengthRange = new LengthRange((byte) 1, (byte) 10, (byte) 10);
+      state.tightenComparison(comparable, comparableIndex, lengthRange,
+            targetIndex);
+      assertStateValues(ComparisonStartState.NEXT_SUFFIXES,
+            ComparisonEndState.TIGHT);
+      targetIndex.update(lengthRange);
+   }
+   
+   public void testPostponeComparisonTightTransition1() throws Exception
+   {
+      this.testLoosePostponeComparisonTransition();
+      LengthRange lengthRange = new LengthRange((byte) 4, (byte) 10, (byte) 10);
+      state.tightenComparison(comparable, comparableIndex, lengthRange,
+            targetIndex);
+      assertStateValues(ComparisonStartState.CURRENT_TARGET,
+            ComparisonEndState.TIGHT);
+   }
+   
+   public void testPostponeComparisonTightTransition() throws Exception
+   {
+      this.testLoosePostponeComparisonTransition();
+      state.tightenComparison(comparable, comparableIndex, 10, targetIndex);
+      assertStateValues(ComparisonStartState.NEXT_SUFFIXES,
+            ComparisonEndState.TIGHT);
+   }
+   
+   public void testTightIndexTightTransition1() throws Exception
+   {
+      this.testPostponeComparisonTightIndexTransition();
+      LengthRange lengthRange = new LengthRange((byte) 3, (byte) 9, (byte) 9);
+      state.tightenComparison(comparable, comparableIndex, lengthRange,
+            targetIndex);
+      assertStateValues(ComparisonStartState.CURRENT_TARGET,
+            ComparisonEndState.TIGHT);
+   }
+
+   public void testTightIndexTightTransition2() throws Exception
+   {
+      this.testPostponeComparisonTightIndexTransition();
+      LengthRange lengthRange = new LengthRange((byte) 5, (byte) 6, (byte) 9);
+      state.tightenComparison(comparable, comparableIndex, lengthRange,
+            targetIndex);
+      assertStateValues(ComparisonStartState.CURRENT_TARGET,
+            ComparisonEndState.TIGHT);
+   }
+
+   public void testTightIndexTightTransition3() throws Exception
+   {
+      this.testPostponeComparisonTightIndexTransition();
+      state.tightenComparison(comparable, comparableIndex, 9, targetIndex);
+      assertStateValues(ComparisonStartState.NEXT_SUFFIXES,
+            ComparisonEndState.TIGHT);
+   }
+   
+   public void testTightIndexTightTransition4() throws Exception
+   {
+      this.testPostponeComparisonTightIndexTransition();
+      state.tightenComparison(comparable, comparableIndex, 7, targetIndex);
+      assertStateValues(ComparisonStartState.NEXT_SUFFIXES,
+            ComparisonEndState.TIGHT);
+   }
+   
+   public void testConstructionAndReset() throws Exception
+   {
+      //change to tight state
+      state.getNextCharacter(comparable, comparableIndex, "abc",
+            new LengthRange((byte) 3, (byte) 10, (byte) 10));
+      assertStateValues(ComparisonStartState.CURRENT_TARGET,
+            ComparisonEndState.TIGHT);
+      
+      // copy tight state
+      MatchingState state2 = new MatchingState();
+      state2.copy(state);
+      assertSame(ComparisonEndState.TIGHT, comparisonEndStateField.get(state2));
+      
+      // reset to loose
+      state.reset();
+      assertStateValues(ComparisonStartState.CURRENT_TARGET,
+            ComparisonEndState.LOOSE);
+   }
+   
+   /**
+    * Asserts that the state comparison start value is the same as <code>start
+    * </code>, and that state comparison end, the same as <code>end</code>.
+    * 
+    * @param start      the expected comaprison start state value
+    * @param end        the expected comparison end state value
+    */
+   public void assertStateValues(ComparisonStartState start,
+         ComparisonEndState end)
+      throws Exception
+   {
+      assertSame(start, comparisonStartStateField.get(state));
+      assertSame(end, comparisonEndStateField.get(state));
+   }
+   
+   /**
+    * Asserts that <code>targetIndex.postponedComparison</code> field value
+    * equals <code>expected</code>.
+    * 
+    * @param expected  the expected value of comparison postponed
+    */
+   public void assertPostponedComparisonValue(boolean expected) throws Exception
+   {
+      assertEquals(Boolean.valueOf(expected),
+            postponedComparisonField.get(targetIndex));
+   }
+   
+   /**
+    * Extends index to test when <code>valueChanged</code> is invoked.
+    * 
+    * @author Flavia Rainone
+    */
+   private class ExtendedIndex extends Index
+   {
+      private boolean valueChanged = false;
+      
+      protected void valueChanged()
+      {
+         this.valueChanged = true;
+      }
+      
+      protected boolean isValueChanged()
+      {
+         boolean result = this.valueChanged;
+         this.valueChanged = false;
+         return result;
+      }
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/part/AllTests.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/part/AllTests.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/part/AllTests.java	2008-01-03 18:54:24 UTC (rev 68603)
@@ -0,0 +1,49 @@
+/*
+ * 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 junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * Test suite that contains all test cases of this package.
+ * 
+ * @author Flavia Rainone
+ */
+public class AllTests
+{
+
+   public static Test suite()
+   {
+      TestSuite suite = new TestSuite(
+            "Test for org.jboss.aop.joinpoint.graph.tree.search.part");
+      //$JUnit-BEGIN$
+      suite.addTestSuite(ComparableKeyPartPatternTest.class);
+      suite.addTestSuite(ComparableKeyPartSuffixTest.class);
+      suite.addTestSuite(ComparableKeyPartSimpleTest.class);
+      suite.addTestSuite(ComparableKeyPartFactoryTest.class);
+      suite.addTestSuite(ComparableKeyPartPrefixTest.class);
+      //$JUnit-END$
+      return suite;
+   }
+
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/part/ComparableKeyPartFactoryTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/part/ComparableKeyPartFactoryTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/part/ComparableKeyPartFactoryTest.java	2008-01-03 18:54:24 UTC (rev 68603)
@@ -0,0 +1,92 @@
+/*
+ * 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.MatcherProfile;
+import org.jboss.aop.joinpoint.graph.tree.search.part.ComparableKeyPart;
+import org.jboss.aop.joinpoint.graph.tree.search.part.ComparableKeyPartFactory;
+
+import junit.framework.TestCase;
+
+/**
+ * Test of the {@link ComparableKeyPartFactory} class.
+ * 
+ * @author Flavia Rainone
+ */
+public class ComparableKeyPartFactoryTest extends TestCase
+{
+   public void testSeparator()
+   {
+      assertEquals('*', ComparableKeyPartFactory.getInstance().getSeparator());
+   }
+   
+   public void testCreation()
+   {
+      ComparableKeyPartFactory factory = ComparableKeyPartFactory.getInstance();
+      factory.startCreation();
+      
+      ComparableKeyPart keyPart1 = (ComparableKeyPart) factory.create(
+            "an.expression", MatcherProfile.PATTERN);
+      assertNotNull(keyPart1);
+      assertEquals(2, keyPart1.getLength());
+      assertEquals(2, keyPart1.postPrefixLength);
+      
+      ComparableKeyPart keyPart2 = (ComparableKeyPart) factory.create(
+            "that.is.a.", MatcherProfile.SIMPLE);
+      assertNotNull(keyPart2);
+      assertEquals(4, keyPart2.getLength());
+      assertEquals(5, keyPart1.postPrefixLength);
+      assertEquals(4, keyPart2.postPrefixLength);
+      
+      
+      ComparableKeyPart keyPart3 = (ComparableKeyPart) factory.create(
+            "little.bit", MatcherProfile.PREFIX);
+      assertNotNull(keyPart3);
+      assertEquals(2, keyPart3.getLength());
+      assertEquals(6, keyPart1.postPrefixLength);
+      assertEquals(5, keyPart2.postPrefixLength);
+      assertEquals(2, keyPart3.postPrefixLength);
+      
+      ComparableKeyPart keyPart4 = (ComparableKeyPart) factory.create(
+            ".long", MatcherProfile.SUFFIX);
+      assertNotNull(keyPart4);
+      assertEquals(2, keyPart4.getLength());
+      assertEquals(7, keyPart1.postPrefixLength);
+      assertEquals(6, keyPart2.postPrefixLength);
+      assertEquals(3, keyPart3.postPrefixLength);
+      assertEquals(2, keyPart4.postPrefixLength);
+      
+      factory.stopCreation();
+      
+      factory.startCreation();
+      ComparableKeyPart keyPart5 = (ComparableKeyPart) factory.create(
+            "another.different.expresion", MatcherProfile.SIMPLE);
+      assertNotNull(keyPart5);
+      assertEquals(3, keyPart5.postPrefixLength);
+      // assert lengths of previous key are unchanged
+      assertEquals(7, keyPart1.postPrefixLength);
+      assertEquals(6, keyPart2.postPrefixLength);
+      assertEquals(3, keyPart3.postPrefixLength);
+      assertEquals(2, keyPart4.postPrefixLength);
+      factory.stopCreation();
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/part/ComparableKeyPartPatternTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/part/ComparableKeyPartPatternTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/part/ComparableKeyPartPatternTest.java	2008-01-03 18:54:24 UTC (rev 68603)
@@ -0,0 +1,887 @@
+/*
+ * 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.KeyPart;
+import org.jboss.aop.joinpoint.graph.tree.search.Flags;
+import org.jboss.aop.joinpoint.graph.tree.search.match.ComparisonResult;
+import org.jboss.aop.joinpoint.graph.tree.search.match.MatcherProfile;
+import org.jboss.aop.joinpoint.graph.tree.search.match.MatchingState;
+
+
+/**
+ * Asserts the expected result of every test scenario defined by the superclass
+ * with the target of the test being a comparable key part pattern.
+ * 
+ * @author Flavia Rainone
+ */
+public class ComparableKeyPartPatternTest extends ComparableKeyPartTest
+{
+   protected MatcherProfile getProfile()
+   {
+      return MatcherProfile.PATTERN;
+   }
+   
+   protected void assertEmptyKeyPartSameTarget(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, emptyKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(),
+            new MatchingState()));
+   }
+   
+   protected void assertEmptyKeyPartEmptyTarget(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(Flags.ALL, emptyKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertEmptyKeyPartNonEmptyTarget1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, emptyKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertEmptyKeyPartNonEmptyTarget2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, emptyKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertEmptyKeyPartSequence1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, emptyKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertEmptyKeyPartSequence2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, emptyKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertOneElSameTarget(KeyPart target, ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(oneElExpression.length(),
+            targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertOneElSameTargetIncIndex(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(oneElExpression.length(),
+            targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertOneElSameTargetDiffIndex1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(Flags.ALL, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   public void assertOneElSameTargetDiffIndex2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(oneElExpression.length(),
+            targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   public void assertOneElSameTargetDiffIndex3(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(oneElExpression.length(),
+            targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertOneElSameTargetIncomplete(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(4, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(oneElExpression.charAt(4), oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertOneElSamePrefix(KeyPart target, ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(oneElExpression.length(),
+            targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertOneElSamePrefixIncomplete(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(5, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(oneElExpression.charAt(5), oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertOneElSamePrefixIncIndexes(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(oneElExpression.length() + 3,
+            targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertOneElSamePrefixDiffLength(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(6, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(Flags.ALL, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertOneElSamePattern1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(oneElExpression.length() + 9,
+            targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertOneElSamePattern2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(24, targetIndex.getElementIndex().getValue());
+   }
+   
+   protected void assertOneElSamePattern3(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(46, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   protected void assertOneElSamePatternIncomplete1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(8, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(Flags.ALL, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertOneElSamePatternIncomplete2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(2, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(Flags.ALL, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertOneElSamePatternIncIndexes(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(26, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   protected void assertOneElSameSuffix1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(29, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   protected void assertOneElSameSuffix2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(29, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertOneElSameSuffix3(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(38, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   protected void assertOneElSameSuffixIncomplete1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(Flags.ALL, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertOneElSameSuffixIncomplete2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(2, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(oneElExpression.charAt(2), oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertOneElSameSuffixIncIndex1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(38, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertOneElSameSuffixIncIndex2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(22, targetIndex.getElementIndex().getValue());
+   }
+   
+   public void assertOneElMismatch1(ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(13, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertOneElMismatch2(ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(33, targetIndex.getElementIndex().getValue());
+   }
+   
+   public void assertOneElMismatch3(KeyPart target, ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(oneElExpression.length(),
+            targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   public void assertSameTarget(KeyPart target, ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(7, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   public void assertSameTargetIncIndex1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(7, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+
+   public void assertSameTargetIncIndex2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(7, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertSameTargetIncIndex3(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(7, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertSameTargetDiffIndex1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(4, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(Flags.ALL, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   public void assertSameTargetDiffIndex2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(7, targetIndex.getValue());
+      assertEquals(7, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   public void assertSameTargetDiffIndex3(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(4, targetIndex.getElementIndex().getValue());
+   }
+   
+   public void assertSameTargetIncomplete1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(1, comparableIndex.getElementIndex().getValue());
+      assertEquals(2, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(expression.charAt(4 + 1 + 1), keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertSameTargetIncomplete2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(2, comparableIndex.getValue());
+      assertEquals(3, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertSameTargetIncomplete3(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(3, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      int index = target.getKeyElements()[0].length() +
+      target.getKeyElements()[1].length() +
+      target.getKeyElements()[2].length() + 3;
+      assertEquals(expression.charAt(index), keyPart.getNextCharacter(
+         comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   public void assertSamePrefix(KeyPart target, ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(7, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertSamePrefixIncomplete(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(7, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertSamePrefixIncIndexes(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(5, targetIndex.getValue());
+      assertEquals(7, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertSamePrefixDiffLength1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(3, comparableIndex.getValue());
+      assertEquals(4, comparableIndex.getElementIndex().getValue());
+      assertEquals(4, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      int index = target.getKeyElements()[0].length() +
+      target.getKeyElements()[1].length() +
+      target.getKeyElements()[2].length() + 4 + 3; 
+      assertEquals(expression.charAt(index), keyPart.getNextCharacter(
+         comparableIndex, target, target.getLengthRange(), state));
+      
+   }
+
+   public void assertSamePrefixDiffLength2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(7, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertSamePattern1(KeyPart target, ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(7, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertSamePattern2(KeyPart target, ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(6, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertSamePattern3(KeyPart target, ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(7, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertSamePatternIncomplete1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(2, comparableIndex.getValue());
+      assertEquals(3, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+         comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertSamePatternIncomplete2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(1, comparableIndex.getElementIndex().getValue());
+      assertEquals(2, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(expression.charAt(6), keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertSamePatternIncIndexes1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(4, targetIndex.getValue());
+      assertEquals(7, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   protected void assertSamePatternIncIndexes2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(4, targetIndex.getValue());
+      assertEquals(7, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertSamePatternIncIndexes3(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(7, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertSameSuffix1(KeyPart target, ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(7, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   protected void assertSameSuffix2(KeyPart target, ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(7, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertSameSuffix3(KeyPart target, ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(7, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   protected void assertSameSuffixIncomplete1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(3, comparableIndex.getValue());
+      assertEquals(1, comparableIndex.getElementIndex().getValue());
+      assertEquals(4, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(expression.charAt(15), keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   protected void assertSameSuffixIncomplete2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(3, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(expression.charAt(14), keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   protected void assertSameSuffixIncomplete3(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(8, targetIndex.getElementIndex().getValue());
+      assertEquals(Flags.ALL, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertSameSuffixIncomplete4(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(2, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(expression.charAt(2), keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertSameSuffixIncIndex1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(7, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   protected void assertSameSuffixIncIndex2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(7, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   protected void assertSameSuffixIncIndex3(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(7, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertMismatch1(ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(1, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertMismatch2(ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(3, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertMismatch3(ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(4, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertMismatch4(ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(3, comparableIndex.getValue());
+      assertEquals(4, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(4, targetIndex.getElementIndex().getValue());
+   }
+   
+   public void assertMismatch5(ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(2, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(2, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+   
+   protected void assertMismatch6(ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(9, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertMismatch7(ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(2, comparableIndex.getValue());
+      assertEquals(1, comparableIndex.getElementIndex().getValue());
+      assertEquals(2, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+   
+   public void assertMismatch8(ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(17, targetIndex.getElementIndex().getValue());
+   }  
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/part/ComparableKeyPartPrefixTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/part/ComparableKeyPartPrefixTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/part/ComparableKeyPartPrefixTest.java	2008-01-03 18:54:24 UTC (rev 68603)
@@ -0,0 +1,855 @@
+/*
+ * 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.KeyPart;
+import org.jboss.aop.joinpoint.graph.tree.search.Flags;
+import org.jboss.aop.joinpoint.graph.tree.search.match.ComparisonResult;
+import org.jboss.aop.joinpoint.graph.tree.search.match.MatcherProfile;
+
+
+/**
+ * Asserts the expected result of every test scenario defined by the superclass
+ * with the target of the test being a comparable key part prefix.
+ * 
+ * @author Flavia Rainone
+ */
+public class ComparableKeyPartPrefixTest extends ComparableKeyPartTest
+{
+   protected MatcherProfile getProfile()
+   {
+      return MatcherProfile.PREFIX;
+   }
+   
+   /**
+    * Tests the getNextCharacter method.
+    */
+   public void testEmptyNextCharacter()
+   {
+      KeyPart target = new KeyPart("");
+      assertEquals(Flags.ALL, emptyKeyPart.getNextCharacter(comparableIndex,
+            target, target.getLengthRange(), state));
+      comparableIndex.getElementIndex().increment();
+      assertEquals(Flags.ALL, emptyKeyPart.getNextCharacter(comparableIndex,
+            target, target.getLengthRange(), state));
+      comparableIndex.increment();
+      assertEquals(KeyPart.KEY_ELEMENT_END, emptyKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertEmptyKeyPartSameTarget(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, emptyKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertEmptyKeyPartEmptyTarget(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(Flags.ALL, emptyKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertEmptyKeyPartNonEmptyTarget1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, emptyKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertEmptyKeyPartNonEmptyTarget2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, emptyKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertEmptyKeyPartSequence1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, emptyKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertEmptyKeyPartSequence2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, emptyKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   public void assertOneElSameTarget(KeyPart target, ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(oneElExpression.length(),
+            targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertOneElSameTargetIncIndex(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(oneElExpression.length(),
+            targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertOneElSameTargetDiffIndex1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(oneElExpression.charAt(0), oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   public void assertOneElSameTargetDiffIndex2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(oneElExpression.length(),
+            targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   public void assertOneElSameTargetDiffIndex3(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(1, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(oneElExpression.charAt(1), oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertOneElSameTargetIncomplete(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(4, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(oneElExpression.charAt(4), oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertOneElSamePrefix(KeyPart target, ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(oneElExpression.length(),
+            targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertOneElSamePrefixIncomplete(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(5, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(oneElExpression.charAt(5), oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertOneElSamePrefixIncIndexes(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(oneElExpression.length() + 3,
+            targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertOneElSamePrefixDiffLength(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(6, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(oneElExpression.charAt(6), oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertOneElSamePattern1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+   
+   protected void assertOneElSamePattern2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(6, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(6, targetIndex.getElementIndex().getValue());
+   }
+   
+   protected void assertOneElSamePattern3(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(7, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(7, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertOneElSamePatternIncomplete1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(7, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(7, targetIndex.getElementIndex().getValue());
+      assertEquals(oneElExpression.charAt(7), oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertOneElSamePatternIncomplete2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+   
+   protected void assertOneElSamePatternIncIndexes(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(3, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(2, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertOneElSameSuffix1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertOneElSameSuffix2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+   
+   protected void assertOneElSameSuffix3(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(3, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(3, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertOneElSameSuffixIncomplete1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(oneElExpression.charAt(0), oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertOneElSameSuffixIncomplete2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(3, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(3, targetIndex.getElementIndex().getValue());
+   }
+   
+   protected void assertOneElSameSuffixIncIndex1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(6, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(15, targetIndex.getElementIndex().getValue());
+   }
+   
+   protected void assertOneElSameSuffixIncIndex2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(22, targetIndex.getElementIndex().getValue());
+   }
+   
+   public void assertOneElMismatch1(ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(13, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(13, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertOneElMismatch2(ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(6, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(6, targetIndex.getElementIndex().getValue());
+   }
+   
+   public void assertOneElMismatch3(KeyPart target, ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(oneElExpression.length(),
+            targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertSameTarget(KeyPart target, ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(7, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertSameTargetIncIndex1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(7, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertSameTargetIncIndex2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(7, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertSameTargetIncIndex3(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(7, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertSameTargetDiffIndex1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(4, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(expression.charAt(0), keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   public void assertSameTargetDiffIndex2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(7, targetIndex.getValue());
+      assertEquals(7, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   public void assertSameTargetDiffIndex3(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(1, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+   
+   public void assertSameTargetIncomplete1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(1, comparableIndex.getElementIndex().getValue());
+      assertEquals(2, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(expression.charAt(4 + 1 + 1), keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertSameTargetIncomplete2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(2, comparableIndex.getValue());
+      assertEquals(3, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertSameTargetIncomplete3(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(3, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      int index = target.getKeyElements()[0].length() +
+      target.getKeyElements()[1].length() +
+      target.getKeyElements()[2].length() + 3;
+      assertEquals(expression.charAt(index), keyPart.getNextCharacter(
+         comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   public void assertSamePrefix(KeyPart target, ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(7, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertSamePrefixIncomplete(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(7, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertSamePrefixIncIndexes(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(5, targetIndex.getValue());
+      assertEquals(7, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertSamePrefixDiffLength1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(3, comparableIndex.getValue());
+      assertEquals(4, comparableIndex.getElementIndex().getValue());
+      assertEquals(4, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      int index = target.getKeyElements()[0].length() +
+         target.getKeyElements()[1].length() +
+         target.getKeyElements()[2].length() + 4 + 3; 
+      assertEquals(expression.charAt(index), keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   public void assertSamePrefixDiffLength2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(7, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+         comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertSamePattern1(KeyPart target, ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+   
+   protected void assertSamePattern2(KeyPart target, ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertSamePattern3(KeyPart target, ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+   
+   protected void assertSamePatternIncomplete1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(2, comparableIndex.getValue());
+      assertEquals(3, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+         comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertSamePatternIncomplete2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+   
+   protected void assertSamePatternIncIndexes1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(1, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(4, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertSamePatternIncIndexes2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(4, targetIndex.getValue());
+      assertEquals(7, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertSamePatternIncIndexes3(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(7, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertSameSuffix1(KeyPart target, ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertSameSuffix2(KeyPart target, ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+   
+   protected void assertSameSuffix3(KeyPart target, ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertSameSuffixIncomplete1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertSameSuffixIncomplete2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertSameSuffixIncomplete3(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+   
+   protected void assertSameSuffixIncomplete4(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+   
+   protected void assertSameSuffixIncIndex1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(4, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertSameSuffixIncIndex2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(7, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   protected void assertSameSuffixIncIndex3(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(7, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertMismatch1(ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertMismatch2(ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(3, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertMismatch3(ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertMismatch4(ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(3, comparableIndex.getValue());
+      assertEquals(4, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(4, targetIndex.getElementIndex().getValue());
+   }
+   
+   public void assertMismatch5(ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(2, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(2, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+   
+   protected void assertMismatch6(ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(9, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertMismatch7(ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(2, comparableIndex.getValue());
+      assertEquals(1, comparableIndex.getElementIndex().getValue());
+      assertEquals(2, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+   
+   public void assertMismatch8(ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }  
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/part/ComparableKeyPartSimpleTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/part/ComparableKeyPartSimpleTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/part/ComparableKeyPartSimpleTest.java	2008-01-03 18:54:24 UTC (rev 68603)
@@ -0,0 +1,814 @@
+/*
+ * 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.KeyPart;
+import org.jboss.aop.joinpoint.graph.tree.search.Flags;
+import org.jboss.aop.joinpoint.graph.tree.search.match.ComparisonResult;
+import org.jboss.aop.joinpoint.graph.tree.search.match.MatcherProfile;
+
+
+/**
+ * Asserts the expected result of every test scenario defined by the superclass
+ * with the target of the test being a simple comparable key part.
+ * 
+ * @author Flavia Rainone
+ */
+public class ComparableKeyPartSimpleTest extends ComparableKeyPartTest
+{
+   protected MatcherProfile getProfile()
+   {
+      return MatcherProfile.SIMPLE;
+   }
+   
+   protected void assertEmptyKeyPartSameTarget(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, emptyKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertEmptyKeyPartEmptyTarget(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(Flags.ALL, emptyKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertEmptyKeyPartNonEmptyTarget1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+   
+   protected void assertEmptyKeyPartNonEmptyTarget2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+   
+   protected void assertEmptyKeyPartSequence1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, emptyKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertEmptyKeyPartSequence2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(Flags.ALL, emptyKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   public void assertOneElSameTarget(KeyPart target, ComparisonResult result)
+   {
+      assertSame(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertOneElSameTargetIncIndex(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertOneElSameTargetDiffIndex1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(oneElExpression.charAt(0), oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   public void assertOneElSameTargetDiffIndex2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(2, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   public void assertOneElSameTargetDiffIndex3(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(1, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(oneElExpression.charAt(1), oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertOneElSameTargetIncomplete(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(4, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(oneElExpression.charAt(4), oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertOneElSamePrefix(KeyPart target, ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertOneElSamePrefixIncomplete(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(5, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(oneElExpression.charAt(5), oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertOneElSamePrefixIncIndexes(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(2, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertOneElSamePrefixDiffLength(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(oneElExpression.charAt(0), oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertOneElSamePattern1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+   
+   protected void assertOneElSamePattern2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+   
+   protected void assertOneElSamePattern3(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertOneElSamePatternIncomplete1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+   
+   protected void assertOneElSamePatternIncomplete2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+   
+   protected void assertOneElSamePatternIncIndexes(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(3, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(2, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertOneElSameSuffix1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertOneElSameSuffix2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertOneElSameSuffix3(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertOneElSameSuffixIncomplete1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+   
+   protected void assertOneElSameSuffixIncomplete2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+   
+   protected void assertOneElSameSuffixIncIndex1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(9, targetIndex.getElementIndex().getValue());
+   }
+   
+   protected void assertOneElSameSuffixIncIndex2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(22, targetIndex.getElementIndex().getValue());
+   }
+   
+   public void assertOneElMismatch1(ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(13, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(13, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertOneElMismatch2(ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+   
+   public void assertOneElMismatch3(KeyPart target, ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+
+   
+   public void assertSameTarget(KeyPart target, ComparisonResult result)
+   {
+      assertSame(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(4, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+
+   public void assertSameTargetIncIndex1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(4, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   public void assertSameTargetIncIndex2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(4, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertSameTargetIncIndex3(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(4, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertSameTargetDiffIndex1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(4, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(expression.charAt(0), keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   public void assertSameTargetDiffIndex2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(8, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   public void assertSameTargetDiffIndex3(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(1, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+   
+   public void assertSameTargetIncomplete1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(1, comparableIndex.getElementIndex().getValue());
+      assertEquals(2, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(expression.charAt(4 + 1 + 1), keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertSameTargetIncomplete2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(2, comparableIndex.getValue());
+      assertEquals(3, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   protected void assertSameTargetIncomplete3(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(3, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      int index = target.getKeyElements()[0].length() +
+      target.getKeyElements()[1].length() +
+      target.getKeyElements()[2].length() + 3;
+      assertEquals(expression.charAt(index), keyPart.getNextCharacter(
+         comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   public void assertSamePrefix(KeyPart target, ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(4, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertSamePrefixIncomplete(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(4, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertSamePrefixIncIndexes(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(6, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertSamePrefixDiffLength1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(3, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+
+   public void assertSamePrefixDiffLength2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(3, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+   
+   protected void assertSamePattern1(KeyPart target, ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+   
+   protected void assertSamePattern2(KeyPart target, ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertSamePattern3(KeyPart target, ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+   
+   protected void assertSamePatternIncomplete1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(2, comparableIndex.getValue());
+      assertEquals(3, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+         comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertSamePatternIncomplete2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+   
+   protected void assertSamePatternIncIndexes1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(1, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(4, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertSamePatternIncIndexes2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(3, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(4, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+   
+   protected void assertSamePatternIncIndexes3(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(3, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertSameSuffix1(KeyPart target, ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertSameSuffix2(KeyPart target, ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+   
+   protected void assertSameSuffix3(KeyPart target, ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertSameSuffixIncomplete1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertSameSuffixIncomplete2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertSameSuffixIncomplete3(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+   
+   protected void assertSameSuffixIncomplete4(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+   
+   protected void assertSameSuffixIncIndex1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(4, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertSameSuffixIncIndex2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(4, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   protected void assertSameSuffixIncIndex3(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(4, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertMismatch1(ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertMismatch2(ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(3, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+   
+   protected void assertMismatch3(ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertMismatch4(ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(3, comparableIndex.getValue());
+      assertEquals(4, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(4, targetIndex.getElementIndex().getValue());
+   }
+   
+   public void assertMismatch5(ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(2, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(2, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+   
+   protected void assertMismatch6(ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(9, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertMismatch7(ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(2, comparableIndex.getValue());
+      assertEquals(1, comparableIndex.getElementIndex().getValue());
+      assertEquals(2, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+   
+   public void assertMismatch8(ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/part/ComparableKeyPartSuffixTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/part/ComparableKeyPartSuffixTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/part/ComparableKeyPartSuffixTest.java	2008-01-03 18:54:24 UTC (rev 68603)
@@ -0,0 +1,852 @@
+/*
+ * 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.KeyPart;
+import org.jboss.aop.joinpoint.graph.tree.search.Flags;
+import org.jboss.aop.joinpoint.graph.tree.search.match.ComparisonResult;
+import org.jboss.aop.joinpoint.graph.tree.search.match.MatcherProfile;
+
+
+/**
+ * Asserts the expected result of every test scenario defined by the superclass
+ * with the target of the test being a comparable key part suffix.
+ * 
+ * @author Flavia Rainone
+ */
+public class ComparableKeyPartSuffixTest extends ComparableKeyPartTest
+{
+   protected MatcherProfile getProfile()
+   {
+      return MatcherProfile.SUFFIX;
+   }
+   
+   protected void assertEmptyKeyPartSameTarget(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, emptyKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertEmptyKeyPartEmptyTarget(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+   
+   protected void assertEmptyKeyPartNonEmptyTarget1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, emptyKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertEmptyKeyPartNonEmptyTarget2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, emptyKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertEmptyKeyPartSequence1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, emptyKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertEmptyKeyPartSequence2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, emptyKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertOneElSameTarget(KeyPart target, ComparisonResult result)
+   {
+      assertSame(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertOneElSameTargetIncIndex(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertOneElSameTargetDiffIndex1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(Flags.ALL, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   public void assertOneElSameTargetDiffIndex2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(2, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   public void assertOneElSameTargetDiffIndex3(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertOneElSameTargetIncomplete(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(4, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(oneElExpression.charAt(4), oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertOneElSamePrefix(KeyPart target, ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertOneElSamePrefixIncomplete(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(5, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(oneElExpression.charAt(5), oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertOneElSamePrefixIncIndexes(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(2, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertOneElSamePrefixDiffLength(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(oneElExpression.charAt(0), oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertOneElSamePattern1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(16, targetIndex.getElementIndex().getValue());
+   }
+   
+   protected void assertOneElSamePattern2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(21, targetIndex.getElementIndex().getValue());
+   }
+   
+   protected void assertOneElSamePattern3(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(31, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertOneElSamePatternIncomplete1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(11, targetIndex.getElementIndex().getValue());
+      assertEquals(Flags.ALL, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertOneElSamePatternIncomplete2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(4, targetIndex.getElementIndex().getValue());
+      assertEquals(Flags.ALL, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertOneElSamePatternIncIndexes(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(13, targetIndex.getElementIndex().getValue());
+   }
+   
+   protected void assertOneElSameSuffix1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   protected void assertOneElSameSuffix2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertOneElSameSuffix3(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   protected void assertOneElSameSuffixIncomplete1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(18, targetIndex.getElementIndex().getValue());
+      assertEquals(Flags.ALL, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertOneElSameSuffixIncomplete2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(2, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(oneElExpression.charAt(2), oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertOneElSameSuffixIncIndex1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertOneElSameSuffixIncIndex2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(22, targetIndex.getElementIndex().getValue());
+   }
+   
+   public void assertOneElMismatch1(ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(13, targetIndex.getElementIndex().getValue());
+   }
+   
+   protected void assertOneElMismatch2(ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(18, targetIndex.getElementIndex().getValue());
+   }
+   
+   public void assertOneElMismatch3(KeyPart target, ComparisonResult result)
+   {
+      assertSame(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertSameTarget(KeyPart target, ComparisonResult result)
+   {
+      assertSame(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(4, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+
+   public void assertSameTargetIncIndex1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(4, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+
+   public void assertSameTargetIncIndex2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(4, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertSameTargetIncIndex3(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(4, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertSameTargetDiffIndex1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(4, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(Flags.ALL, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   public void assertSameTargetDiffIndex2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(8, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   public void assertSameTargetDiffIndex3(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(4, targetIndex.getElementIndex().getValue());
+   }
+   
+   public void assertSameTargetIncomplete1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(1, comparableIndex.getElementIndex().getValue());
+      assertEquals(2, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(expression.charAt(4 + 1 + 1), keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertSameTargetIncomplete2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(2, comparableIndex.getValue());
+      assertEquals(3, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertSameTargetIncomplete3(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(3, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      int index = target.getKeyElements()[0].length() +
+         target.getKeyElements()[1].length() +
+         target.getKeyElements()[2].length() + 3;
+      assertEquals(expression.charAt(index), keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   public void assertSamePrefix(KeyPart target, ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(4, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertSamePrefixIncomplete(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(4, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertSamePrefixIncIndexes(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(6, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void assertSamePrefixDiffLength1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(3, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+
+   public void assertSamePrefixDiffLength2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(3, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+   
+   protected void assertSamePattern1(KeyPart target, ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(3, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+   
+   protected void assertSamePattern2(KeyPart target, ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(6, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertSamePattern3(KeyPart target, ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(3, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+   
+   protected void assertSamePatternIncomplete1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(2, comparableIndex.getValue());
+      assertEquals(3, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+         comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertSamePatternIncomplete2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(1, comparableIndex.getValue());
+      assertEquals(1, comparableIndex.getElementIndex().getValue());
+      assertEquals(2, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(expression.charAt(6), keyPart.getNextCharacter(
+         comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertSamePatternIncIndexes1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(3, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(4, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertSamePatternIncIndexes2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(3, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(4, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+   
+   protected void assertSamePatternIncIndexes3(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(3, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+   
+   protected void assertSameSuffix1(KeyPart target, ComparisonResult result)
+   {
+      assertSame(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(4, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   protected void assertSameSuffix2(KeyPart target, ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(4, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertSameSuffix3(KeyPart target, ComparisonResult result)
+   {
+      assertSame(ComparisonResult.COMPARABLE_END, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(4, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   protected void assertSameSuffixIncomplete1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(3, comparableIndex.getValue());
+      assertEquals(1, comparableIndex.getElementIndex().getValue());
+      assertEquals(4, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(expression.charAt(15), keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   protected void assertSameSuffixIncomplete2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(3, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(expression.charAt(14), keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   protected void assertSameSuffixIncomplete3(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(8, targetIndex.getElementIndex().getValue());
+      assertEquals(Flags.ALL, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertSameSuffixIncomplete4(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.TARGET_END, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(2, comparableIndex.getElementIndex().getValue());
+      assertEquals(1, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(expression.charAt(2), keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   protected void assertSameSuffixIncIndex1(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(4, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   protected void assertSameSuffixIncIndex2(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(4, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   protected void assertSameSuffixIncIndex3(KeyPart target,
+         ComparisonResult result)
+   {
+      assertSame(ComparisonResult.BOTH_ENDS, result);
+      assertEquals(4, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(4, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+      assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+
+   public void assertMismatch1(ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(1, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertMismatch2(ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(3, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertMismatch3(ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(4, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertMismatch4(ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(3, comparableIndex.getValue());
+      assertEquals(4, comparableIndex.getElementIndex().getValue());
+      assertEquals(3, targetIndex.getValue());
+      assertEquals(4, targetIndex.getElementIndex().getValue());
+   }
+
+   public void assertMismatch5(ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(2, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(2, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+   
+   protected void assertMismatch6(ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(9, targetIndex.getElementIndex().getValue());
+   }
+
+   protected void assertMismatch7(ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(2, comparableIndex.getValue());
+      assertEquals(1, comparableIndex.getElementIndex().getValue());
+      assertEquals(2, targetIndex.getValue());
+      assertEquals(0, targetIndex.getElementIndex().getValue());
+   }
+   
+   public void assertMismatch8(ComparisonResult result)
+   {
+      assertSame(ComparisonResult.MISMATCH_FOUND, result);
+      assertEquals(0, comparableIndex.getValue());
+      assertEquals(0, comparableIndex.getElementIndex().getValue());
+      assertEquals(0, targetIndex.getValue());
+      assertEquals(17, targetIndex.getElementIndex().getValue());
+   }  
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/part/ComparableKeyPartTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/part/ComparableKeyPartTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/search/part/ComparableKeyPartTest.java	2008-01-03 18:54:24 UTC (rev 68603)
@@ -0,0 +1,994 @@
+/*
+ * 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.KeyPart;
+import org.jboss.aop.joinpoint.graph.tree.search.match.ComparisonResult;
+import org.jboss.aop.joinpoint.graph.tree.search.match.MatcherProfile;
+import org.jboss.aop.joinpoint.graph.tree.search.match.MatchingState;
+import org.jboss.aop.joinpoint.graph.tree.search.part.ComparableKeyPart;
+import org.jboss.aop.joinpoint.graph.tree.search.part.KeyPartIndex;
+
+import junit.framework.TestCase;
+
+/**
+ * Abstract test of the {@link ComparableKeyPart} class.
+ * <p>
+ * Defines the test cenarios and delegates the assertion to the subclass, that
+ * also {@link #getProfile() defines} the profile of the matcher that contains
+ * the comparable key part to be tested.
+ * 
+ * @author Flavia Rainone
+ */
+public abstract class ComparableKeyPartTest extends TestCase
+{
+   protected ComparableKeyPart emptyKeyPart;
+   protected String oneElExpression;
+   protected ComparableKeyPart oneElKeyPart;
+   protected String expression;
+   protected ComparableKeyPart keyPart;
+   protected KeyPartIndex comparableIndex;
+   protected KeyPartIndex targetIndex;
+   protected MatchingState state;
+   
+   /**
+    * Initializes the target of the test.
+    */
+   public void setUp()
+   {
+      emptyKeyPart = new ComparableKeyPart("", getProfile());
+      oneElExpression = "oneElementExpression";
+      expression = "more.than.one.element";
+      oneElKeyPart = new ComparableKeyPart(oneElExpression, getProfile());
+      keyPart = new ComparableKeyPart(expression, getProfile());
+      comparableIndex = new KeyPartIndex();
+      targetIndex = new KeyPartIndex();
+      state = new MatchingState();
+   }
+
+   /**
+    * Returns the profile of the matcher that contains the comparable key part
+    * to be tested.
+    * 
+    * @return the profile of the matcher that contains the comparable key part
+    * to be tested.
+    */
+   protected abstract MatcherProfile getProfile();
+   
+   /**
+    * Tests the getNextCharacter method.
+    */
+   public void testOneElNextCharacter()
+   {
+      KeyPart keyPart = new KeyPart(oneElExpression);
+      KeyPart target = keyPart.extractPrefixPart(0, 0);
+      for (int i = 0; i < 20; i++)
+      {
+         char expected = oneElExpression.charAt(i);
+         assertEquals(expected, oneElKeyPart.getNextCharacter(comparableIndex,
+               target, target.getLengthRange(), state));
+         comparableIndex.getElementIndex().increment();
+         target = keyPart.extractPrefixPart(0, 1);
+      }
+      assertEquals(KeyPart.KEY_ELEMENT_END, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+      target = keyPart.extractPrefixPart(1, 0);
+      assertEquals(KeyPart.KEY_ELEMENT_END, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   /**
+    * Tests the getNextCharacter method.
+    */
+   public void testNextCharacter()
+   {
+      KeyPart targetKeyPart = new KeyPart(expression);
+      KeyPart target = targetKeyPart.extractPrefixPart(0, 0);
+      int count = 0;
+      for (int i = 0; i < keyPart.getLength(); i++)
+      {
+         while(targetKeyPart.getKeyElements()[0].length() > 0)
+         {
+            char expected = expression.charAt(count ++);
+            assertEquals("Expected character of index " +
+                  comparableIndex.toString() + " is wrong", expected,
+                  keyPart.getNextCharacter(comparableIndex, target,
+                        target.getLengthRange(), state));
+            comparableIndex.getElementIndex().increment();
+            target = targetKeyPart.extractPrefixPart(0, 1);
+         }
+         assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+               comparableIndex, target, target.getLengthRange(), state));
+         target = targetKeyPart.extractPrefixPart(1, 0);
+         assertEquals(KeyPart.KEY_ELEMENT_END, keyPart.getNextCharacter(
+               comparableIndex, target, target.getLengthRange(), state));
+         count ++;
+         comparableIndex.increment();
+      }
+      assertEquals(KeyPart.KEY_ELEMENT_END, oneElKeyPart.getNextCharacter(
+            comparableIndex, target, target.getLengthRange(), state));
+   }
+   
+   public void testEmptyKeyPartSameTarget()
+   {
+      KeyPart target = new KeyPart("");
+      ComparisonResult result = emptyKeyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertEmptyKeyPartSameTarget(target, result);
+   }
+   
+   protected abstract void assertEmptyKeyPartSameTarget(KeyPart target,
+         ComparisonResult result);
+   
+   public void testEmptyKeyPartEmptyTarget()
+   {
+      ComparisonResult result = emptyKeyPart.compare(KeyPart.EMPTY_KEY_END,
+            targetIndex, comparableIndex, state);
+      assertEmptyKeyPartEmptyTarget(KeyPart.EMPTY_KEY_END, result);
+   }
+   
+   protected abstract void assertEmptyKeyPartEmptyTarget(KeyPart target,
+         ComparisonResult result);
+
+   public void testEmptyKeyPartNonEmptyTarget1()
+   {
+      KeyPart target = new KeyPart(oneElExpression);
+      ComparisonResult result = emptyKeyPart.compare(target,
+            targetIndex, comparableIndex, state);
+      assertEmptyKeyPartNonEmptyTarget1(target, result);
+   }
+   
+   protected abstract void assertEmptyKeyPartNonEmptyTarget1(KeyPart target,
+         ComparisonResult result);
+   
+   public void testEmptyKeyPartNonEmptyTarget2()
+   {
+      KeyPart target = new KeyPart(expression);
+      ComparisonResult result = emptyKeyPart.compare(target,
+            targetIndex, comparableIndex, state);
+      assertEmptyKeyPartNonEmptyTarget2(target, result);
+   }
+   
+   protected abstract void assertEmptyKeyPartNonEmptyTarget2(KeyPart target,
+         ComparisonResult result);
+   
+   public void testEmptyKeyPartSequence1()
+   {
+      testEmptyKeyPartSameTarget();
+      targetIndex.reset();
+      ComparisonResult result = emptyKeyPart.compare(KeyPart.EMPTY_KEY_END,
+            targetIndex, comparableIndex, state);
+      assertEmptyKeyPartSequence1(KeyPart.EMPTY_KEY_END, result);
+   }
+   
+   protected abstract void assertEmptyKeyPartSequence1(KeyPart target,
+         ComparisonResult result);
+   
+   public void testEmptyKeyPartSequence2()
+   {
+      testEmptyKeyPartNonEmptyTarget1();
+      targetIndex.reset();
+      ComparisonResult result = emptyKeyPart.compare(KeyPart.EMPTY_KEY_END,
+            targetIndex, comparableIndex, state);
+      assertEmptyKeyPartSequence2(KeyPart.EMPTY_KEY_END, result);
+   }
+   
+   protected abstract void assertEmptyKeyPartSequence2(KeyPart target,
+         ComparisonResult result);
+   
+   public void testOneElSameTarget()
+   {
+      KeyPart target = new KeyPart(oneElExpression);
+      ComparisonResult result = oneElKeyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertOneElSameTarget(target, result);
+   }
+   
+   protected abstract void assertOneElSameTarget(KeyPart target,
+         ComparisonResult result);
+
+   public void testOneElSameTargetIncIndex()
+   {
+      KeyPart target = new KeyPart(oneElExpression);
+      comparableIndex.getElementIndex().increment(3);
+      targetIndex.getElementIndex().increment(3);
+      ComparisonResult result = oneElKeyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertOneElSameTargetIncIndex(target, result);
+   }
+   
+   public abstract void assertOneElSameTargetIncIndex(KeyPart target,
+         ComparisonResult result);
+
+   public void testOneElSameTargetDiffIndex1()
+   {
+      KeyPart target = new KeyPart(oneElExpression);
+      targetIndex.increment();
+      ComparisonResult result = oneElKeyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertOneElSameTargetDiffIndex1(target, result);
+   }
+   
+   public abstract void assertOneElSameTargetDiffIndex1(KeyPart target,
+         ComparisonResult result);
+
+   public void testOneElSameTargetDiffIndex2()
+   {
+      KeyPart target = new KeyPart(oneElExpression + "." + oneElExpression);
+      targetIndex.increment();
+      ComparisonResult result = oneElKeyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertOneElSameTargetDiffIndex2(target, result);
+   }
+
+   protected abstract void assertOneElSameTargetDiffIndex2(KeyPart target,
+         ComparisonResult result);
+   
+   public void testOneElSameTargetDiffIndex3()
+   {
+      KeyPart target = new KeyPart(oneElExpression + "." + oneElExpression);
+      comparableIndex.getElementIndex().increment();
+      ComparisonResult result = oneElKeyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertOneElSameTargetDiffIndex3(target, result);
+   }
+   
+   protected abstract void assertOneElSameTargetDiffIndex3(KeyPart target,
+         ComparisonResult result);
+
+   public void testOneElSameTargetIncomplete()
+   {
+      KeyPart target = new KeyPart(oneElExpression);
+      target = target.extractPrefixPart(0, 4);
+      ComparisonResult result = oneElKeyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertOneElSameTargetIncomplete(target, result);
+   }
+   
+   protected abstract void assertOneElSameTargetIncomplete(KeyPart target,
+         ComparisonResult result);
+   
+   public void testOneElSamePrefix()
+   {
+      KeyPart target = new KeyPart(oneElExpression + ".anysuffix");
+      ComparisonResult result = oneElKeyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertOneElSamePrefix(target, result);
+   }
+   
+   protected abstract void assertOneElSamePrefix(KeyPart target,
+         ComparisonResult result);
+   
+   public void testOneElSamePrefixIncomplete()
+   {
+      KeyPart target = new KeyPart(oneElExpression + ".any.suffix");
+      target = target.extractPrefixPart(0, 5);
+      ComparisonResult result = oneElKeyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertOneElSamePrefixIncomplete(target, result);
+   }
+   
+   protected abstract void assertOneElSamePrefixIncomplete(KeyPart target,
+         ComparisonResult result);
+   
+   public void testOneElSamePrefixIncIndexes()
+   {
+      KeyPart target = new KeyPart("anything.any" + oneElExpression +
+            ".suffix");
+      targetIndex.increment();
+      targetIndex.getElementIndex().increment(4);
+      comparableIndex.getElementIndex().increment();
+      ComparisonResult result = oneElKeyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertOneElSamePrefixIncIndexes(target, result);
+   }
+   
+   protected abstract void assertOneElSamePrefixIncIndexes(KeyPart target,
+         ComparisonResult result);
+   
+   public void testOneElSamePrefixDiffLength()
+   {
+      KeyPart target = new KeyPart(oneElExpression + "suffix");
+      target = target.extractPrefixPart(0, 6);
+      ComparisonResult result = oneElKeyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertOneElSamePrefixDiffLength(target, result);
+   }
+   
+   protected abstract void assertOneElSamePrefixDiffLength(KeyPart target,
+         ComparisonResult result);
+   
+   public void testOneElSamePattern1()
+   {
+      KeyPart target = new KeyPart("anyprefix" + oneElExpression + "suffix");
+      ComparisonResult result = oneElKeyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertOneElSamePattern1(target, result);
+   }
+
+   protected abstract void assertOneElSamePattern1(KeyPart target,
+         ComparisonResult result);
+   
+   public void testOneElSamePattern2()
+   {
+      KeyPart target = new KeyPart("oneEleoneElemoneElementElementoneElement");
+      ComparisonResult result = oneElKeyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertOneElSamePattern2(target, result);
+   }
+   
+   protected abstract void assertOneElSamePattern2(KeyPart target,
+         ComparisonResult result);
+      
+   public void testOneElSamePattern3()
+   {
+      KeyPart target = new KeyPart(
+            "oneElemoneElementExpressiooneElementExpressionelem");
+      ComparisonResult result = oneElKeyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertOneElSamePattern3(target, result);
+   }
+   
+   protected abstract void assertOneElSamePattern3(KeyPart target,
+         ComparisonResult result);
+   
+   public void testOneElSamePatternIncomplete1()
+   {                       
+      KeyPart target = new KeyPart("oneElemoneElementExpressio" +
+            oneElExpression);
+      target = target.extractPrefixPart(0, 15);
+      ComparisonResult result = oneElKeyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertOneElSamePatternIncomplete1(target, result);
+   }
+   
+   protected abstract void assertOneElSamePatternIncomplete1(KeyPart target,
+         ComparisonResult result);
+   
+   public void testOneElSamePatternIncomplete2()
+   {
+      KeyPart target = new KeyPart("anyprefix" + oneElExpression + "suffix");
+      target = target.extractPrefixPart(0, 11);
+      ComparisonResult result = oneElKeyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertOneElSamePatternIncomplete2(target, result);
+   }
+   
+   protected abstract void assertOneElSamePatternIncomplete2(KeyPart target,
+         ComparisonResult result);
+   
+   public void testOneElSamePatternIncIndexes()
+   {
+      KeyPart target = new KeyPart("any.prefix" + oneElExpression + "suffix");
+      targetIndex.increment(1);
+      targetIndex.getElementIndex().increment(2);
+      comparableIndex.getElementIndex().increment(3);
+      ComparisonResult result = oneElKeyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertOneElSamePatternIncIndexes(target, result);
+   }
+   
+   protected abstract void assertOneElSamePatternIncIndexes(KeyPart target,
+         ComparisonResult result);
+   
+   public void testOneElSameSuffix1()
+   {
+      KeyPart target = new KeyPart("anyPrefix" + oneElExpression);
+      ComparisonResult result = oneElKeyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertOneElSameSuffix1(target, result);
+   }
+   
+   protected abstract void assertOneElSameSuffix1(KeyPart target,
+         ComparisonResult result);
+
+   public void testOneElSameSuffix2()
+   {
+      KeyPart target = new KeyPart("anyPrefix" + oneElExpression +
+            ".anySuffix");
+      ComparisonResult result = oneElKeyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertOneElSameSuffix2(target, result);
+   }
+   
+   protected abstract void assertOneElSameSuffix2(KeyPart target,
+         ComparisonResult result);
+   
+   public void testOneElSameSuffix3()
+   {
+      KeyPart target = new KeyPart("oneononononeEleone" + oneElExpression +
+            ".anySuffix");
+      ComparisonResult result = oneElKeyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertOneElSameSuffix3(target, result);
+   }
+   
+   protected abstract void assertOneElSameSuffix3(KeyPart target,
+         ComparisonResult result);
+
+   public void testOneElSameSuffixIncomplete1()
+   {
+      KeyPart target = new KeyPart("oneononononeEleone" + oneElExpression);
+      target = target.extractPrefixPart(0, 0);
+      ComparisonResult result = oneElKeyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertOneElSameSuffixIncomplete1(target, result);
+   }
+   
+   protected abstract void assertOneElSameSuffixIncomplete1(KeyPart target,
+         ComparisonResult result);
+ 
+   public void testOneElSameSuffixIncomplete2()
+   {
+      KeyPart target = new KeyPart("oneononononeEleone" + oneElExpression);
+      target = target.extractPrefixPart(0, 20);
+      ComparisonResult result = oneElKeyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertOneElSameSuffixIncomplete2(target, result);
+   }
+   
+   protected abstract void assertOneElSameSuffixIncomplete2(KeyPart target,
+         ComparisonResult result);
+   
+   public void testOneElSameSuffixIncIndex1()
+   {
+      KeyPart target = new KeyPart("oneononononeEleone" + oneElExpression);
+      targetIndex.getElementIndex().increment(9);
+      ComparisonResult result = oneElKeyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertOneElSameSuffixIncIndex1(target, result);
+   }
+   
+   protected abstract void assertOneElSameSuffixIncIndex1(KeyPart target,
+         ComparisonResult result);
+
+   public void testOneElSameSuffixIncIndex2()
+   {
+      KeyPart target = new KeyPart("oneononononeEleone" + oneElExpression);
+      targetIndex.getElementIndex().increment(22);
+      ComparisonResult result = oneElKeyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertOneElSameSuffixIncIndex2(target, result);
+   }
+   
+   protected abstract void assertOneElSameSuffixIncIndex2(KeyPart target,
+         ComparisonResult result);
+   
+   public void testOneElMismatch1()
+   {
+      KeyPart target = new KeyPart("oneElementExppession");
+      ComparisonResult result = oneElKeyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertOneElMismatch1(result);
+   }
+   
+   protected abstract void assertOneElMismatch1(ComparisonResult result);
+   
+   public void testOneElMismatch2()
+   {
+      KeyPart target = new KeyPart("oneEleoneElemoneElementExpressiononon");
+      ComparisonResult result = oneElKeyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertOneElMismatch2(result);
+   }
+   
+   protected abstract void assertOneElMismatch2(ComparisonResult result);
+   
+   public void testOneElMismatch3()
+   {
+      KeyPart target = new KeyPart(oneElExpression + oneElExpression);
+      ComparisonResult result = oneElKeyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertOneElMismatch3(target, result);
+   }
+   
+   protected abstract void assertOneElMismatch3(KeyPart target,
+         ComparisonResult result);
+   
+   public void testSameTarget()
+   {
+      KeyPart target = new KeyPart(expression);
+      ComparisonResult result = keyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertSameTarget(target, result);
+   }
+   
+   protected abstract void assertSameTarget(KeyPart target,
+         ComparisonResult result);
+   
+   public void testSameTargetIncIndex1()
+   {
+      KeyPart target = new KeyPart(expression);
+      comparableIndex.increment(2);
+      targetIndex.increment(2);
+      ComparisonResult result = keyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertSameTargetIncIndex1(target, result);
+   }
+   
+   protected abstract void assertSameTargetIncIndex1(KeyPart target,
+         ComparisonResult result);
+
+   public void testSameTargetIncIndex2()
+   {
+      KeyPart target = new KeyPart(expression);
+      comparableIndex.getElementIndex().increment(2);
+      targetIndex.getElementIndex().increment(2);
+      ComparisonResult result = keyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertSameTargetIncIndex2(target, result);
+   }
+   
+   protected abstract void assertSameTargetIncIndex2(KeyPart target,
+         ComparisonResult result);
+   
+   public void testSameTargetIncIndex3()
+   {
+      KeyPart target = new KeyPart(expression);
+      target.getKeyElements()[0] = target.getKeyElements()[0].substring(1);
+      comparableIndex.getElementIndex().increment();
+      ComparisonResult result = keyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertSameTargetIncIndex3(target, result);
+   }
+   
+   protected abstract void assertSameTargetIncIndex3(KeyPart target,
+         ComparisonResult result);
+
+   
+   public void testSameTargetDiffIndex1()
+   {
+      KeyPart target = new KeyPart(expression);
+      targetIndex.increment(4);
+      ComparisonResult result = keyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertSameTargetDiffIndex1(target, result);
+   }
+   
+   protected abstract void assertSameTargetDiffIndex1(KeyPart target,
+         ComparisonResult result);
+
+   public void testSameTargetDiffIndex2()
+   {
+      KeyPart target = new KeyPart(expression + "." + expression);
+      targetIndex.increment(4);
+      ComparisonResult result = keyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertSameTargetDiffIndex2(target, result);
+   }
+   
+   protected abstract void assertSameTargetDiffIndex2(KeyPart target,
+         ComparisonResult result);
+
+   public void testSameTargetDiffIndex3()
+   {
+      targetIndex.increment(3);
+      comparableIndex.getElementIndex().increment();
+      KeyPart target = new KeyPart(expression + "." + expression);
+      ComparisonResult result = keyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertSameTargetDiffIndex3(target, result);
+   }
+   
+   protected abstract void assertSameTargetDiffIndex3(KeyPart target,
+         ComparisonResult result);
+   
+   public void testSameTargetIncomplete1()
+   {
+      KeyPart target = new KeyPart(expression);
+      target = target.extractPrefixPart(1, 1);
+      ComparisonResult result = keyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertSameTargetIncomplete1(target, result);
+   }
+   
+   protected abstract void assertSameTargetIncomplete1(KeyPart target,
+         ComparisonResult result);
+   
+   public void testSameTargetIncomplete2()
+   {
+      KeyPart target = new KeyPart(expression);
+      target = target.extractPrefixPart(2, 3);
+      ComparisonResult result = keyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertSameTargetIncomplete2(target, result);
+   }
+   
+   protected abstract void assertSameTargetIncomplete2(KeyPart target,
+         ComparisonResult result);
+   
+   public void testSameTargetIncomplete3()
+   {
+      KeyPart target = new KeyPart(expression);
+      target = target.extractPrefixPart(3, 0);
+      ComparisonResult result = keyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertSameTargetIncomplete3(target, result);
+   }
+   
+   protected abstract void assertSameTargetIncomplete3(KeyPart target,
+         ComparisonResult result);
+
+   public void testSamePrefix()
+   {
+      KeyPart target = new KeyPart(expression + ".any.suffix");
+      ComparisonResult result = keyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertSamePrefix(target, result);
+   }
+   
+   protected abstract void assertSamePrefix(KeyPart target,
+         ComparisonResult result);
+   
+   public void testSamePrefixIncomplete()
+   {
+      KeyPart target = new KeyPart(expression + ".any.suffix");
+      target = target.extractPrefixPart(4, 1);
+      ComparisonResult result = keyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertSamePrefixIncomplete(target, result);
+   }
+   
+   protected abstract void assertSamePrefixIncomplete(KeyPart target,
+         ComparisonResult result);
+   
+   public void testSamePrefixIncIndexes()
+   {
+      KeyPart target = new KeyPart("something.to.ignore" + expression +
+            ".suffix");
+      targetIndex.increment(2);
+      targetIndex.getElementIndex().increment(7);
+      comparableIndex.getElementIndex().increment();
+      ComparisonResult result = keyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertSamePrefixIncIndexes(target, result);
+   }
+   
+   protected abstract void assertSamePrefixIncIndexes(KeyPart target,
+         ComparisonResult result);
+   
+   public void testSamePrefixDiffLength1()
+   {
+      KeyPart target = new KeyPart(expression +"suffix");
+      target = target.extractPrefixPart(3, 4);
+      ComparisonResult result = keyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertSamePrefixDiffLength1(target, result);
+   }
+   
+   protected abstract void assertSamePrefixDiffLength1(KeyPart target,
+         ComparisonResult result);
+   
+   
+   public void testSamePrefixDiffLength2()
+   {
+      KeyPart target = new KeyPart(expression +"suffix");
+      target = target.extractPrefixPart(3, 7);
+      ComparisonResult result = keyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertSamePrefixDiffLength2(target, result);
+   }
+   
+   protected abstract void assertSamePrefixDiffLength2(KeyPart target,
+         ComparisonResult result);
+   
+   public void testSamePattern1()
+   {
+      KeyPart target = new KeyPart("anyprefix" + expression + "suffix");
+      ComparisonResult result = keyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertSamePattern1(target, result);
+   }
+
+   protected abstract void assertSamePattern1(KeyPart target,
+         ComparisonResult result);
+
+   public void testSamePattern2()
+   {
+      KeyPart target = new KeyPart("anyprefix." + expression + ".suffix");
+      ComparisonResult result = keyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertSamePattern2(target, result);
+   }
+
+   protected abstract void assertSamePattern2(KeyPart target,
+         ComparisonResult result);
+   
+   public void testSamePattern3()
+   {
+      KeyPart target = new KeyPart("mormormore.than.one.elementelemore");
+      ComparisonResult result = keyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertSamePattern3(target, result);
+   }
+   
+   protected abstract void assertSamePattern3(KeyPart target,
+         ComparisonResult result);
+
+   public void testSamePatternIncomplete1()
+   {
+      KeyPart target = new KeyPart("more.than.one.elemore.than.one.el");
+      target = target.extractPrefixPart(2, 3);
+      ComparisonResult result = keyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertSamePatternIncomplete1(target, result);
+   }
+   
+   protected abstract void assertSamePatternIncomplete1(KeyPart target,
+         ComparisonResult result);
+   
+   public void testSamePatternIncomplete2()
+   {
+      KeyPart target = new KeyPart("anyprefix" + expression + "suffix");
+      target = target.extractPrefixPart(1, 1);
+      ComparisonResult result = keyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertSamePatternIncomplete2(target, result);
+   }
+   
+   protected abstract void assertSamePatternIncomplete2(KeyPart target,
+         ComparisonResult result);
+   
+   public void testSamePatternIncIndexes1()
+   {
+      KeyPart target = new KeyPart("any.prefix" + expression + "suffix");
+      targetIndex.increment();
+      targetIndex.getElementIndex().increment(4);
+      comparableIndex.getElementIndex().increment();
+      ComparisonResult result = keyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertSamePatternIncIndexes1(target, result);
+   }
+   
+   protected abstract void assertSamePatternIncIndexes1(KeyPart target,
+         ComparisonResult result);
+   
+   public void testSamePatternIncIndexes2()
+   {
+      KeyPart target = new KeyPart("any.prefix" + expression + "suffix");
+      targetIndex.increment(3);
+      comparableIndex.increment(2);
+      ComparisonResult result = keyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertSamePatternIncIndexes2(target, result);
+   }
+   
+   protected abstract void assertSamePatternIncIndexes2(KeyPart target,
+         ComparisonResult result);
+   
+   public void testSamePatternIncIndexes3()
+   {
+      KeyPart target = new KeyPart("element_suffix");
+      comparableIndex.increment(3);
+      ComparisonResult result = keyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertSamePatternIncIndexes3(target, result);
+   }
+   
+   protected abstract void assertSamePatternIncIndexes3(KeyPart target,
+         ComparisonResult result);
+   
+   public void testSameSuffix1()
+   {
+      KeyPart target = new KeyPart("anyPrefix" + expression);
+      ComparisonResult result = keyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertSameSuffix1(target, result);
+   }
+   
+   protected abstract void assertSameSuffix1(KeyPart target,
+         ComparisonResult result);
+
+   public void testSameSuffix2()
+   {
+      KeyPart target = new KeyPart("anyPrefix" + expression + ".anySuffix");
+      ComparisonResult result = keyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertSameSuffix2(target, result);
+   }
+   
+   protected abstract void assertSameSuffix2(KeyPart target,
+         ComparisonResult result);
+   
+   public void testSameSuffix3()
+   {
+      KeyPart target = new KeyPart("moromore" + expression + ".anySuffix");
+      ComparisonResult result = keyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertSameSuffix3(target, result);
+   }
+   
+   protected abstract void assertSameSuffix3(KeyPart target,
+         ComparisonResult result);
+
+   public void testSameSuffixIncomplete1()
+   {
+      KeyPart target = new KeyPart("moromore" + expression);
+      target = target.extractPrefixPart(3, 1);
+      ComparisonResult result = keyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertSameSuffixIncomplete1(target, result);
+   }
+   
+   protected abstract void assertSameSuffixIncomplete1(KeyPart target,
+         ComparisonResult result);
+   
+   public void testSameSuffixIncomplete2()
+   {
+      KeyPart target = new KeyPart("moromore" + expression);
+      target = target.extractPrefixPart(3, 0);
+      ComparisonResult result = keyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertSameSuffixIncomplete2(target, result);
+   }
+   
+   protected abstract void assertSameSuffixIncomplete2(KeyPart target,
+         ComparisonResult result);
+
+   public void testSameSuffixIncomplete3()
+   {
+      KeyPart target = new KeyPart("moromore" + expression);
+      target = target.extractPrefixPart(0, 0);
+      ComparisonResult result = keyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertSameSuffixIncomplete3(target, result);
+   }
+   
+   protected abstract void assertSameSuffixIncomplete3(KeyPart target,
+         ComparisonResult result);
+
+   public void testSameSuffixIncomplete4()
+   {
+      KeyPart target = new KeyPart("moromore" + expression);
+      target = target.extractPrefixPart(0, 10);
+      ComparisonResult result = keyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertSameSuffixIncomplete4(target, result);
+   }
+   
+   protected abstract void assertSameSuffixIncomplete4(KeyPart target,
+         ComparisonResult result);
+   
+   public void testSameSuffixIncIndex1()
+   {
+      KeyPart target = new KeyPart("moromore" + expression);
+      targetIndex.getElementIndex().increment(4);
+      ComparisonResult result = keyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertSameSuffixIncIndex1(target, result);
+   }
+   
+   protected abstract void assertSameSuffixIncIndex1(KeyPart target,
+         ComparisonResult result);
+
+   public void testSameSuffixIncIndex2()
+   {
+      KeyPart target = new KeyPart("moromore" + expression);
+      comparableIndex.increment(2);
+      targetIndex.increment(2);
+      ComparisonResult result = keyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertSameSuffixIncIndex2(target, result);
+   }
+
+   protected abstract void assertSameSuffixIncIndex2(KeyPart target,
+         ComparisonResult result);
+
+   public void testSameSuffixIncIndex3()
+   {
+      KeyPart target = new KeyPart("moromore" + expression);
+      comparableIndex.increment(3);
+      targetIndex.increment(3);
+      ComparisonResult result = keyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertSameSuffixIncIndex3(target, result);
+   }
+   
+   protected abstract void assertSameSuffixIncIndex3(KeyPart target,
+         ComparisonResult result);
+   
+   public void testMismatch1()
+   {
+      KeyPart target = new KeyPart("same.number.of.elements");
+      ComparisonResult result = keyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertMismatch1(result);
+   }
+   
+   protected abstract void assertMismatch1(ComparisonResult result);
+
+   public void testMismatch2()
+   {
+      KeyPart target = new KeyPart("more.than.one.one.more.than.one.El");
+      ComparisonResult result = keyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertMismatch2(result);
+   }
+
+   protected abstract void assertMismatch2(ComparisonResult result);
+   
+   public void testMismatch3()
+   {
+      KeyPart target = new KeyPart("moreaaa.than.one.one.more.than.one");
+      ComparisonResult result = keyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertMismatch3(result);
+   }
+   
+   protected abstract void assertMismatch3(ComparisonResult result);
+   
+   public void testMismatch4()
+   {
+      KeyPart target = new KeyPart(
+            "more.than.one.elemore.than.one.element.expresion");
+      ComparisonResult result = keyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertMismatch4(result);
+   }
+   
+   protected abstract void assertMismatch4(ComparisonResult result);
+   
+   public void testMismatch5()
+   {
+      KeyPart target = new KeyPart(expression);
+      target.getKeyElements()[2] = target.getKeyElements()[2] + "suffix";
+      ComparisonResult result = keyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertMismatch5(result);
+   }
+   
+   protected abstract void assertMismatch5(ComparisonResult result);
+
+   public void testMismatch6()
+   {
+      KeyPart target = new KeyPart("moromore" + expression);
+      targetIndex.getElementIndex().increment(9);
+      ComparisonResult result = keyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertMismatch6(result);
+   }
+   
+   protected abstract void assertMismatch6(ComparisonResult result);
+   
+   public void testMismatch7()
+   {
+      KeyPart target = new KeyPart("moromore" + expression);
+      comparableIndex.increment(2);
+      comparableIndex.getElementIndex().increment();
+      targetIndex.increment(2);
+      ComparisonResult result = keyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertMismatch7(result);
+   }
+   
+   protected abstract void assertMismatch7(ComparisonResult result);
+   
+   public void testMismatch8()
+   {
+      KeyPart target = new KeyPart(oneElExpression);
+      ComparisonResult result = keyPart.compare(target, targetIndex,
+            comparableIndex, state);
+      assertMismatch8(result);
+   }
+   
+   protected abstract void assertMismatch8(ComparisonResult result);
+}
\ No newline at end of file




More information about the jboss-cvs-commits mailing list