Index: /trunk/autoquest-core-usageprofiles-test/src/test/java/de/ugoe/cs/autoquest/usageprofiles/TrieTest.java
===================================================================
--- /trunk/autoquest-core-usageprofiles-test/src/test/java/de/ugoe/cs/autoquest/usageprofiles/TrieTest.java	(revision 1109)
+++ /trunk/autoquest-core-usageprofiles-test/src/test/java/de/ugoe/cs/autoquest/usageprofiles/TrieTest.java	(revision 1110)
@@ -247,23 +247,187 @@
 
         @Test
+        public void testGetContextSuffix_5() throws Exception {
+                Trie<String> fixture = new Trie<String>();
+                fixture.train(sequence, 3);
+                List<String> context = new ArrayList<String>();
+                context.add("a");
+                context.add("a");
+                context.add("b");
+                List<String> expected = new ArrayList<String>();
+                expected.add("a");
+                expected.add("b");
+
+                List<String> result = fixture.getContextSuffix(context);
+
+                ListAssert.assertEquals(expected, result);
+        }
+
+        @Test
         public void testGetSequencesWithMostOccurrences_1() throws Exception {
                 Trie<String> fixture = new Trie<String>();
                 fixture.train(sequence, 3);
                 
+                // get all sequences with a minimal length of one that occur most often
+                Collection<List<String>> result = fixture.getSequencesWithOccurrenceCount(1, 0);
+
+                assertEquals(1, result.size());
+                
                 List<String> expected = new ArrayList<String>();
                 expected.add("a");
 
-                Collection<List<String>> result = fixture.getSequencesWithMostOccurrences(1);
+                ListAssert.assertEquals(expected, result.iterator().next());
+        }
+
+        @Test
+        public void testGetSequencesWithMostOccurrences_2() throws Exception {
+                Trie<String> fixture = new Trie<String>();
+                fixture.train(sequence, 3);
+                
+                // get all sequences with a minimal length of one that occur exactly once
+                Collection<List<String>> result = fixture.getSequencesWithOccurrenceCount(1, 1);
+
+                assertEquals(11, result.size());
+                
+                List<String> expected = new ArrayList<String>();
+                expected.add("r");
+                expected.add("a");
+                expected.add("c");
+                // rac
+                ListAssert.assertContains((List<List<String>>) result, expected);
+                
+                expected.clear();
+                expected.add("a");
+                expected.add("c");
+                // ac
+                ListAssert.assertContains((List<List<String>>) result, expected);
+                
+                expected.add("a");
+                // aca
+                ListAssert.assertContains((List<List<String>>) result, expected);
+                
+                expected.clear();
+                expected.add("c");
+                // c
+                ListAssert.assertContains((List<List<String>>) result, expected);
+                
+                expected.add("a");
+                // ca
+                ListAssert.assertContains((List<List<String>>) result, expected);
+                
+                expected.add("d");
+                // cad
+                ListAssert.assertContains((List<List<String>>) result, expected);
+                
+                expected.clear();
+                expected.add("a");
+                expected.add("d");
+                // ad
+                ListAssert.assertContains((List<List<String>>) result, expected);
+                
+                expected.add("a");
+                // ada
+                ListAssert.assertContains((List<List<String>>) result, expected);
+                
+                expected.clear();
+                expected.add("d");
+                // d
+                ListAssert.assertContains((List<List<String>>) result, expected);
+                
+                expected.add("a");
+                // da
+                ListAssert.assertContains((List<List<String>>) result, expected);
+                
+                expected.add("b");
+                // dab
+                ListAssert.assertContains((List<List<String>>) result, expected);
+        }
+
+        @Test
+        public void testGetSequencesWithMostOccurrences_3() throws Exception {
+                Trie<String> fixture = new Trie<String>();
+                fixture.train(sequence, 3);
+                
+                // get all sequences with a minimal length of one that occur exactly twice
+                Collection<List<String>> result = fixture.getSequencesWithOccurrenceCount(1, 2);
+
+                assertEquals(7, result.size());
+                
+                List<String> expected = new ArrayList<String>();
+                expected.add("a");
+                expected.add("b");
+                // ab
+                ListAssert.assertContains((List<List<String>>) result, expected);
+                
+                expected.add("r");
+                // abr
+                ListAssert.assertContains((List<List<String>>) result, expected);
+
+                expected.clear();
+                expected.add("b");
+                // b
+                ListAssert.assertContains((List<List<String>>) result, expected);
+                
+                expected.add("r");
+                // br
+                ListAssert.assertContains((List<List<String>>) result, expected);
+                
+                expected.add("a");
+                // bra
+                ListAssert.assertContains((List<List<String>>) result, expected);
+
+                expected.clear();
+                expected.add("r");
+                // r
+                ListAssert.assertContains((List<List<String>>) result, expected);
+                
+                expected.add("a");
+                // ra
+                ListAssert.assertContains((List<List<String>>) result, expected);
+        }
+
+        @Test
+        public void testGetSequencesWithMostOccurrences_4() throws Exception {
+                Trie<String> fixture = new Trie<String>();
+                fixture.train(sequence, 3);
+                
+                // get all sequences with a minimal length of one that occur exactly three times
+                Collection<List<String>> result = fixture.getSequencesWithOccurrenceCount(1, 3);
+
+                assertEquals(0, result.size());
+        }
+
+        @Test
+        public void testGetSequencesWithMostOccurrences_5() throws Exception {
+                Trie<String> fixture = new Trie<String>();
+                fixture.train(sequence, 3);
+                
+                // get all sequences with a minimal length of one that occur exactly four times
+                Collection<List<String>> result = fixture.getSequencesWithOccurrenceCount(1, 4);
+
+                assertEquals(0, result.size());
+        }
+
+        @Test
+        public void testGetSequencesWithMostOccurrences_6() throws Exception {
+                Trie<String> fixture = new Trie<String>();
+                fixture.train(sequence, 3);
+                
+                // get all sequences with a minimal length of one that occur exactly five times
+                Collection<List<String>> result = fixture.getSequencesWithOccurrenceCount(1, 5);
 
                 assertEquals(1, result.size());
-                ListAssert.assertEquals(expected, result.iterator().next());
-        }
-
-        @Test
-        public void testGetSequencesWithMostOccurrences_2() throws Exception {
-                Trie<String> fixture = new Trie<String>();
-                fixture.train(sequence, 3);
-                
-                Collection<List<String>> result = fixture.getSequencesWithMostOccurrences(2);
+                
+                List<String> expected = new ArrayList<String>();
+                expected.add("a");
+                ListAssert.assertContains((List<List<String>>) result, expected);
+        }
+
+        @Test
+        public void testGetSequencesWithMostOccurrences_7() throws Exception {
+                Trie<String> fixture = new Trie<String>();
+                fixture.train(sequence, 3);
+                
+                // get all sequences with a minimal length of two that occur most often
+                Collection<List<String>> result = fixture.getSequencesWithOccurrenceCount(2, 0);
 
                 assertEquals(5, result.size());
@@ -292,9 +456,116 @@
 
         @Test
-        public void testGetSequencesWithMostOccurrences_3() throws Exception {
-                Trie<String> fixture = new Trie<String>();
-                fixture.train(sequence, 3);
-                
-                Collection<List<String>> result = fixture.getSequencesWithMostOccurrences(3);
+        public void testGetSequencesWithMostOccurrences_8() throws Exception {
+                Trie<String> fixture = new Trie<String>();
+                fixture.train(sequence, 3);
+                
+                // get all sequences with a minimal length of two that occur exactly once
+                Collection<List<String>> result = fixture.getSequencesWithOccurrenceCount(2, 1);
+
+                assertEquals(9, result.size());
+                
+                List<String> expected = new ArrayList<String>();
+                expected.add("r");
+                expected.add("a");
+                expected.add("c");
+                // rac
+                ListAssert.assertContains((List<List<String>>) result, expected);
+                
+                expected.clear();
+                expected.add("a");
+                expected.add("c");
+                // ac
+                ListAssert.assertContains((List<List<String>>) result, expected);
+                
+                expected.add("a");
+                // aca
+                ListAssert.assertContains((List<List<String>>) result, expected);
+                
+                expected.clear();
+                expected.add("c");
+                expected.add("a");
+                // ca
+                ListAssert.assertContains((List<List<String>>) result, expected);
+                
+                expected.add("d");
+                // cad
+                ListAssert.assertContains((List<List<String>>) result, expected);
+                
+                expected.clear();
+                expected.add("a");
+                expected.add("d");
+                // ad
+                ListAssert.assertContains((List<List<String>>) result, expected);
+                
+                expected.add("a");
+                // ada
+                ListAssert.assertContains((List<List<String>>) result, expected);
+                
+                expected.clear();
+                expected.add("d");
+                expected.add("a");
+                // da
+                ListAssert.assertContains((List<List<String>>) result, expected);
+                
+                expected.add("b");
+                // dab
+                ListAssert.assertContains((List<List<String>>) result, expected);
+        }
+
+        @Test
+        public void testGetSequencesWithMostOccurrences_9() throws Exception {
+                Trie<String> fixture = new Trie<String>();
+                fixture.train(sequence, 3);
+                
+                // get all sequences with a minimal length of two that occur exactly twice
+                Collection<List<String>> result = fixture.getSequencesWithOccurrenceCount(2, 2);
+
+                assertEquals(5, result.size());
+                
+                List<String> expected = new ArrayList<String>();
+                expected.add("a");
+                expected.add("b");
+                // ab
+                ListAssert.assertContains((List<List<String>>) result, expected);
+                
+                expected.add("r");
+                // abr
+                ListAssert.assertContains((List<List<String>>) result, expected);
+
+                expected.clear();
+                expected.add("b");
+                expected.add("r");
+                // br
+                ListAssert.assertContains((List<List<String>>) result, expected);
+                
+                expected.add("a");
+                // bra
+                ListAssert.assertContains((List<List<String>>) result, expected);
+
+                expected.clear();
+                expected.add("r");
+                expected.add("a");
+                // ra
+                ListAssert.assertContains((List<List<String>>) result, expected);
+        }
+
+        @Test
+        public void testGetSequencesWithMostOccurrences_10() throws Exception {
+                Trie<String> fixture = new Trie<String>();
+                fixture.train(sequence, 3);
+                
+                // get all sequences with a minimal length of two that occur exactly three times
+                Collection<List<String>> result = fixture.getSequencesWithOccurrenceCount(2, 3);
+
+                assertEquals(0, result.size());
+        }
+        
+        @Test
+        public void testGetSequencesWithMostOccurrences_11() throws Exception {
+                Trie<String> fixture = new Trie<String>();
+                fixture.train(sequence, 3);
+                
+                // get all sequences with a minimal length of three that occur most often
+                Collection<List<String>> result = fixture.getSequencesWithOccurrenceCount(3, 0);
 
                 assertEquals(2, result.size());
@@ -314,29 +585,72 @@
 
         @Test
-        public void testGetSequencesWithMostOccurrences_4() throws Exception {
-                Trie<String> fixture = new Trie<String>();
-                fixture.train(sequence, 3);
-                
-                Collection<List<String>> result = fixture.getSequencesWithMostOccurrences(4);
-
+        public void testGetSequencesWithMostOccurrences_12() throws Exception {
+                Trie<String> fixture = new Trie<String>();
+                fixture.train(sequence, 3);
+                
+                // get all sequences with a minimal length of three that occur exactly once
+                Collection<List<String>> result = fixture.getSequencesWithOccurrenceCount(3, 1);
+
+                assertEquals(5, result.size());
+                
+                List<String> expected = new ArrayList<String>();
+                expected.add("r");
+                expected.add("a");
+                expected.add("c");
+                // rac
+                ListAssert.assertContains((List<List<String>>) result, expected);
+                
+                expected.clear();
+                expected.add("a");
+                expected.add("c");
+                expected.add("a");
+                // aca
+                ListAssert.assertContains((List<List<String>>) result, expected);
+                
+                expected.clear();
+                expected.add("c");
+                expected.add("a");
+                expected.add("d");
+                // cad
+                ListAssert.assertContains((List<List<String>>) result, expected);
+                
+                expected.clear();
+                expected.add("a");
+                expected.add("d");
+                expected.add("a");
+                // ada
+                ListAssert.assertContains((List<List<String>>) result, expected);
+                
+                expected.clear();
+                expected.add("d");
+                expected.add("a");
+                expected.add("b");
+                // dab
+                ListAssert.assertContains((List<List<String>>) result, expected);
+        }
+
+        @Test
+        public void testGetSequencesWithMostOccurrences_13() throws Exception {
+                Trie<String> fixture = new Trie<String>();
+                fixture.train(sequence, 3);
+                
+                // get all sequences with a minimal length of four that occur most often
+                Collection<List<String>> result = fixture.getSequencesWithOccurrenceCount(4, 0);
+
+                // none of these exist, as the tree is only trained with sequences of length 3
                 assertEquals(0, result.size());
         }
 
-	@Test
-	public void testGetContextSuffix_5() throws Exception {
-		Trie<String> fixture = new Trie<String>();
-		fixture.train(sequence, 3);
-		List<String> context = new ArrayList<String>();
-		context.add("a");
-		context.add("a");
-		context.add("b");
-		List<String> expected = new ArrayList<String>();
-		expected.add("a");
-		expected.add("b");
-
-		List<String> result = fixture.getContextSuffix(context);
-
-		ListAssert.assertEquals(expected, result);
-	}
+        @Test
+        public void testGetSequencesWithMostOccurrences_14() throws Exception {
+                Trie<String> fixture = new Trie<String>();
+                fixture.train(sequence, 3);
+                
+                // get all sequences with a minimal length of four that occur exactly once
+                Collection<List<String>> result = fixture.getSequencesWithOccurrenceCount(4, 1);
+
+                // none of these exist, as the tree is only trained with sequences of length 3
+                assertEquals(0, result.size());
+        }
 
 	@Test
Index: /trunk/autoquest-core-usageprofiles/src/main/java/de/ugoe/cs/autoquest/usageprofiles/Trie.java
===================================================================
--- /trunk/autoquest-core-usageprofiles/src/main/java/de/ugoe/cs/autoquest/usageprofiles/Trie.java	(revision 1109)
+++ /trunk/autoquest-core-usageprofiles/src/main/java/de/ugoe/cs/autoquest/usageprofiles/Trie.java	(revision 1110)
@@ -324,14 +324,18 @@
     /**
      * <p>
-     * returns a list of symbol sequences which have a minimal length and that occurred most often
-     * with the same number of occurrences. The resulting list is empty, if there is no symbol
-     * sequence with the minimal length.
+     * returns a list of symbol sequences which have a minimal length and that occurred as often
+     * as defined by the given occurrence count. If the given occurrence count is smaller 1 then
+     * those sequences are returned, that occur most often. The resulting list is empty, if there
+     * is no symbol sequence with the minimal length or the provided number of occurrences.
      * </p>
      *
-     * @param minimalLength the minimal length of the returned sequences
+     * @param minimalLength   the minimal length of the returned sequences
+     * @param occurrenceCount the number of occurrences of the returned sequences
      * 
      * @return as described
      */
-    public Collection<List<T>> getSequencesWithMostOccurrences(int minimalLength) {
+    public Collection<List<T>> getSequencesWithOccurrenceCount(int minimalLength,
+                                                               int occurrenceCount)
+    {
         LinkedList<TrieNode<T>> context = new LinkedList<TrieNode<T>>();
         Collection<List<TrieNode<T>>> paths = new LinkedList<List<TrieNode<T>>>();
@@ -339,9 +343,9 @@
         context.push(rootNode);
         
-        // traverse the trie and determine all sequences, which have the maximum number of
+        // traverse the trie and determine all sequences, which have the provided number of
         // occurrences and a minimal length.
         
         // minimalLength + 1 because we denote the depth including the root node
-        determineLongPathsWithMostOccurrences(minimalLength + 1, paths, context);
+        determineLongPathsWithMostOccurrences(minimalLength + 1, occurrenceCount, paths, context);
         
         Collection<List<T>> resultingPaths = new LinkedList<List<T>>();
@@ -368,41 +372,49 @@
     /**
      * <p>
-     * Traverses the trie to collect all sequences with a maximum number of occurrences and with
-     * a minimal length. The length is encoded in the provided recursion depth.
+     * Traverses the trie to collect all sequences with a defined number of occurrences and with
+     * a minimal length. If the given occurrence count is smaller 1 then those sequences are
+     * searched that occur most often. The length of the sequences is encoded in the provided
+     * recursion depth.
      * </p>
      *
-     * @param minimalDepth the minimal recursion depth to be done
-     * @param paths        the paths through the trie that all occurred with the same amount and
-     *                     that have the so far found maximum of occurrences (is updated each
-     *                     time a further path with the same number of occurrences is found; is
-     *                     replaced if a path with more occurrences is found)
-     * @param context      the path through the trie, that is analyzed by the recursive call
+     * @param minimalDepth    the minimal recursion depth to be done
+     * @param occurrenceCount the number of occurrences of the returned sequences
+     * @param paths           the paths through the trie that all occurred with the same amount
+     *                        (if occurrence count is smaller 1, the paths which occurred most
+     *                        often) and that have the so far found matching number of occurrences
+     *                        (is updated each time a further path with the same number of
+     *                        occurrences is found; if occurrence count is smaller 1
+     *                        it is replaced if a path with more occurrences is found)
+     * @param context         the path through the trie, that is analyzed by the recursive call
      */
     private void determineLongPathsWithMostOccurrences(int                           minimalDepth,
+                                                       int                           occurrenceCount,
                                                        Collection<List<TrieNode<T>>> paths,
                                                        LinkedList<TrieNode<T>>       context)
     {
-        int maxCount = 0;
+        int envisagedCount = occurrenceCount;
 
         // only if we already reached the depth to be achieved, we check if the paths have the
-        // maximum number of occurrences
+        // required number of occurrences
         if (context.size() >= minimalDepth) {
             
-            // try to determine the maximum number of occurrences so far, if any
-            if (paths.size() > 0) {
-                List<TrieNode<T>> path = paths.iterator().next();
-                maxCount = path.get(path.size() - 1).getCount();
-            }
-
-            // if the current path has a higher number of occurrences than all so far, clear
-            // the paths collected so far and set the new number of occurrences as new maximum
-            if (context.getLast().getCount() > maxCount) {
-                paths.clear();
-                maxCount = context.getLast().getCount();
+            if (envisagedCount < 1) {
+                // try to determine the maximum number of occurrences so far, if any
+                if (paths.size() > 0) {
+                    List<TrieNode<T>> path = paths.iterator().next();
+                    envisagedCount = path.get(path.size() - 1).getCount();
+                }
+
+                // if the current path has a higher number of occurrences than all so far, clear
+                // the paths collected so far and set the new number of occurrences as new maximum
+                if (context.getLast().getCount() > envisagedCount) {
+                    paths.clear();
+                    envisagedCount = context.getLast().getCount();
+                }
             }
             
             // if the path matches the current maximal number of occurrences, add it to the list
             // of collected paths with these number of occurrences
-            if (context.getLast().getCount() == maxCount) {
+            if (context.getLast().getCount() == envisagedCount) {
                 paths.add(new LinkedList<TrieNode<T>>(context));
             }
@@ -411,7 +423,8 @@
         // perform the trie traversal
         for (TrieNode<T> child : context.getLast().getChildren()) {
-            if (child.getCount() >= maxCount) {
+            if (child.getCount() >= envisagedCount) {
                 context.add(child);
-                determineLongPathsWithMostOccurrences(minimalDepth, paths, context);
+                determineLongPathsWithMostOccurrences
+                    (minimalDepth, occurrenceCount, paths, context);
                 context.removeLast();
             }
