Index: /trunk/autoquest-core-usageprofiles-test/src/test/java/de/ugoe/cs/autoquest/usageprofiles/DefaultSymbolMapTest.java
===================================================================
--- /trunk/autoquest-core-usageprofiles-test/src/test/java/de/ugoe/cs/autoquest/usageprofiles/DefaultSymbolMapTest.java	(revision 1282)
+++ /trunk/autoquest-core-usageprofiles-test/src/test/java/de/ugoe/cs/autoquest/usageprofiles/DefaultSymbolMapTest.java	(revision 1282)
@@ -0,0 +1,962 @@
+//   Copyright 2012 Georg-August-Universität Göttingen, Germany
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+
+package de.ugoe.cs.autoquest.usageprofiles;
+
+import static org.junit.Assert.*;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.junit.Test;
+
+/**
+ * <p>
+ * The class <code>SymbolMapTest</code> contains tests for the class
+ * <code>{@link SymbolMap}</code>.
+ * </p>
+ * 
+ * @author Patrick Harms
+ */
+public class DefaultSymbolMapTest {
+
+    @Test
+    public void testSymbolMap_1() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+        
+        assertNotNull(symbolMap);
+        assertEquals(0, symbolMap.size());
+    }
+
+    @Test
+    public void testSymbolMap_2() {
+        SymbolMap<String, String> symbolMap1 = new DefaultSymbolMap<String, String>();
+        
+        symbolMap1.addSymbol("symbol", "value");
+        
+        SymbolMap<String, String> symbolMap2 = new DefaultSymbolMap<String, String>(symbolMap1);
+        
+        assertNotNull(symbolMap2);
+        assertSymbolMapEntries(symbolMap2, new String[] { "symbol" } , new String[] { "value" });
+    }
+
+    @Test(expected = java.lang.IllegalArgumentException.class)
+    public void testSymbolMap_3() throws Exception {
+        new DefaultSymbolMap<String, String>((SymbolMap<String, String>) null);
+    }
+    
+    @Test
+    public void testAddSymbol_1() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+            
+        symbolMap.addSymbol("symbol1", "value1");
+        
+        assertNotNull(symbolMap);
+        assertSymbolMapEntries(symbolMap, new String[] { "symbol1" } , new String[] { "value1" });
+    }
+    
+    @Test
+    public void testAddSymbol_2() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+        
+        int entryCount = 2000;
+        
+        String[] symbols = new String[entryCount];
+        String[] values = new String[entryCount];
+        
+        for (int i = 0; i < entryCount; i++) {
+            symbolMap.addSymbol("symbol" + i, "value" + i);
+            symbols[i] = "symbol" + i;
+            values[i] = "value" + i;
+        }
+        
+        assertNotNull(symbolMap);
+        assertSymbolMapEntries(symbolMap, symbols, values);
+    }
+    
+    @Test
+    public void testAddSymbol_3() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+        
+        int entryCount = 2000;
+        
+        String[] symbols = new String[entryCount];
+        String[] values = new String[entryCount];
+        
+        for (int i = 0; i < entryCount; i++) {
+            if (i % 7 == 0) {
+                symbolMap.addSymbol("symbol" + i, "value" + i);
+                symbols[i] = "symbol" + i;
+                values[i] = "value" + i;
+            }
+            else {
+                symbolMap.addSymbol("symbol" + i, null);
+                symbols[i] = "symbol" + i;
+                values[i] = null;
+            }
+        }
+        
+        assertNotNull(symbolMap);
+        assertSymbolMapEntries(symbolMap, symbols, values);
+    }
+    
+    @Test(expected = java.lang.IllegalArgumentException.class)
+    public void testAddSymbol_4() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+            
+        symbolMap.addSymbol(null, null);
+    }    
+    
+    @Test
+    public void testSize_1() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+            
+        assertEquals(0, symbolMap.size());
+    }
+    
+    @Test
+    public void testSize_2() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+            
+        symbolMap.addSymbol("symbol1", "value1");
+        
+        assertEquals(1, symbolMap.size());
+    }
+    
+    @Test
+    public void testSize_3() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+        
+        int entryCount = 2000;
+        
+        for (int i = 0; i < entryCount; i++) {
+            symbolMap.addSymbol("symbol" + i, "value" + i);
+        }
+        
+        assertEquals(entryCount, symbolMap.size());
+    }
+    
+    @Test
+    public void testSize_4() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+        
+        int entryCount = 2000;
+        
+        for (int i = 0; i < entryCount; i++) {
+            if (i % 7 == 0) {
+                symbolMap.addSymbol("symbol" + i, "value" + i);
+            }
+            else {
+                symbolMap.addSymbol("symbol" + i, null);
+            }
+        }
+        
+        assertEquals(entryCount, symbolMap.size());
+    }
+    
+    @Test
+    public void testSize_5() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+        
+        int entryCount = 2000;
+        
+        for (int i = 0; i < entryCount; i++) {
+            symbolMap.addSymbol("symbol" + i, "value" + i);
+        }
+        
+        for (int i = 150; i < (entryCount - 150); i++) {
+            symbolMap.removeSymbol("symbol" + i);
+        }
+        
+        assertEquals(2 * 150, symbolMap.size());
+    }
+    
+    @Test
+    public void testIsEmpty_1() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+            
+        assertTrue(symbolMap.isEmpty());
+    }
+    
+    @Test
+    public void testIsEmpty_2() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+            
+        symbolMap.addSymbol("symbol1", "value1");
+        
+        assertFalse(symbolMap.isEmpty());
+    }
+    
+    @Test
+    public void testIsEmpty_3() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+        
+        int entryCount = 2000;
+        
+        for (int i = 0; i < entryCount; i++) {
+            symbolMap.addSymbol("symbol" + i, "value" + i);
+        }
+        
+        assertFalse(symbolMap.isEmpty());
+    }
+    
+    @Test
+    public void testIsEmpty_4() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+        
+        int entryCount = 2000;
+        
+        for (int i = 0; i < entryCount; i++) {
+            if (i % 7 == 0) {
+                symbolMap.addSymbol("symbol" + i, "value" + i);
+            }
+            else {
+                symbolMap.addSymbol("symbol" + i, null);
+            }
+        }
+        
+        assertFalse(symbolMap.isEmpty());
+    }
+    
+    @Test
+    public void testIsEmpty_5() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+        
+        int entryCount = 2000;
+        
+        for (int i = 0; i < entryCount; i++) {
+            symbolMap.addSymbol("symbol" + i, "value" + i);
+        }
+        
+        for (int i = 150; i < (entryCount - 150); i++) {
+            symbolMap.removeSymbol("symbol" + i);
+        }
+        
+        assertFalse(symbolMap.isEmpty());
+    }
+    
+    @Test
+    public void testContainsSymbol_1() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+            
+        assertFalse(symbolMap.containsSymbol("symbol"));
+    }
+    
+    @Test
+    public void testContainsSymbol_2() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+            
+        symbolMap.addSymbol("symbol1", "value1");
+        
+        assertTrue(symbolMap.containsSymbol("symbol1"));
+    }
+    
+    @Test
+    public void testContainsSymbol_3() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+        
+        int entryCount = 2000;
+        
+        for (int i = 0; i < entryCount; i++) {
+            symbolMap.addSymbol("symbol" + i, "value" + i);
+        }
+        
+        for (int i = 0; i < entryCount; i++) {
+            assertTrue(symbolMap.containsSymbol("symbol" + i));
+        }
+    }
+    
+    @Test
+    public void testContainsSymbol_4() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+        
+        int entryCount = 2000;
+        
+        for (int i = 0; i < entryCount; i++) {
+            if (i % 7 == 0) {
+                symbolMap.addSymbol("symbol" + i, "value" + i);
+            }
+            else {
+                symbolMap.addSymbol("symbol" + i, null);
+            }
+        }
+        
+        for (int i = 0; i < entryCount; i++) {
+            assertTrue(symbolMap.containsSymbol("symbol" + i));
+        }
+    }
+    
+    @Test
+    public void testContainsSymbol_5() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+        
+        int entryCount = 2000;
+        
+        for (int i = 0; i < entryCount; i++) {
+            symbolMap.addSymbol("symbol" + i, "value" + i);
+        }
+        
+        for (int i = 150; i < (entryCount - 150); i++) {
+            symbolMap.removeSymbol("symbol" + i);
+        }
+        
+        for (int i = 0; i < 150; i++) {
+            assertTrue(symbolMap.containsSymbol("symbol" + i));
+        }
+        
+        for (int i = 150; i < (entryCount - 150); i++) {
+            assertFalse(symbolMap.containsSymbol("symbol" + i));
+        }
+        
+        for (int i = (entryCount - 150); i < entryCount; i++) {
+            assertTrue(symbolMap.containsSymbol("symbol" + i));
+        }
+    }
+    
+    @Test(expected = java.lang.IllegalArgumentException.class)
+    public void testContainsSymbol_6() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+            
+        symbolMap.containsSymbol(null);
+    }    
+
+    @Test
+    public void testGetValue_1() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+            
+        assertNull(symbolMap.getValue("symbol"));
+    }
+    
+    @Test
+    public void testGetValue_2() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+            
+        symbolMap.addSymbol("symbol1", "value1");
+        
+        assertNotNull(symbolMap.getValue("symbol1"));
+    }
+    
+    @Test
+    public void testGetValue_3() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+            
+        symbolMap.addSymbol("symbol1", null);
+        
+        assertNull(symbolMap.getValue("symbol1"));
+    }
+    
+    @Test
+    public void testGetValue_4() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+        
+        int entryCount = 2000;
+        
+        for (int i = 0; i < entryCount; i++) {
+            symbolMap.addSymbol("symbol" + i, "value" + i);
+        }
+        
+        for (int i = 0; i < entryCount; i++) {
+            assertNotNull(symbolMap.getValue("symbol" + i));
+        }
+    }
+    
+    @Test
+    public void testGetValue_5() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+        
+        int entryCount = 2000;
+        
+        for (int i = 0; i < entryCount; i++) {
+            if (i % 7 == 0) {
+                symbolMap.addSymbol("symbol" + i, "value" + i);
+            }
+            else {
+                symbolMap.addSymbol("symbol" + i, null);
+            }
+        }
+        
+        for (int i = 0; i < entryCount; i++) {
+            if (i % 7 == 0) {
+                assertNotNull(symbolMap.getValue("symbol" + i));
+            }
+            else {
+                assertNull(symbolMap.getValue("symbol" + i));
+            }
+        }
+    }
+    
+    @Test
+    public void testGetValue_6() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+        
+        int entryCount = 2000;
+        
+        for (int i = 0; i < entryCount; i++) {
+            symbolMap.addSymbol("symbol" + i, "value" + i);
+        }
+        
+        for (int i = 150; i < (entryCount - 150); i++) {
+            symbolMap.removeSymbol("symbol" + i);
+        }
+        
+        for (int i = 0; i < 150; i++) {
+            assertNotNull(symbolMap.getValue("symbol" + i));
+        }
+        
+        for (int i = 150; i < (entryCount - 150); i++) {
+            assertNull(symbolMap.getValue("symbol" + i));
+        }
+        
+        for (int i = (entryCount - 150); i < entryCount; i++) {
+            assertNotNull(symbolMap.getValue("symbol" + i));
+        }
+    }
+    
+    @Test(expected = java.lang.IllegalArgumentException.class)
+    public void testGetValue_7() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+            
+        symbolMap.getValue(null);
+    }    
+
+    @Test
+    public void testRemoveSymbol_1() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+            
+        assertNull(symbolMap.removeSymbol("symbol"));
+    }
+    
+    @Test
+    public void testRemoveSymbol_2() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+            
+        symbolMap.addSymbol("symbol1", "value1");
+        
+        assertNotNull(symbolMap.removeSymbol("symbol1"));
+        assertEquals(0, symbolMap.size());
+    }
+    
+    @Test
+    public void testRemoveSymbol_3() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+            
+        symbolMap.addSymbol("symbol1", null);
+        
+        assertNull(symbolMap.removeSymbol("symbol1"));
+        assertEquals(0, symbolMap.size());
+    }
+    
+    @Test
+    public void testRemoveSymbol_4() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+        
+        int entryCount = 2000;
+        
+        for (int i = 0; i < entryCount; i++) {
+            symbolMap.addSymbol("symbol" + i, "value" + i);
+        }
+        
+        for (int i = 0; i < entryCount; i++) {
+            assertNotNull(symbolMap.removeSymbol("symbol" + i));
+        }
+        
+        assertEquals(0, symbolMap.size());
+    }
+    
+    @Test
+    public void testRemoveSymbol_5() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+        
+        int entryCount = 2000;
+        
+        for (int i = 0; i < entryCount; i++) {
+            if (i % 7 == 0) {
+                symbolMap.addSymbol("symbol" + i, "value" + i);
+            }
+            else {
+                symbolMap.addSymbol("symbol" + i, null);
+            }
+        }
+        
+        for (int i = 0; i < entryCount; i++) {
+            if (i % 7 == 0) {
+                assertNotNull(symbolMap.removeSymbol("symbol" + i));
+            }
+            else {
+                assertNull(symbolMap.removeSymbol("symbol" + i));
+            }
+        }
+        
+        assertEquals(0, symbolMap.size());
+    }
+    
+    @Test
+    public void testRemoveSymbol_6() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+        
+        int entryCount = 2000;
+        
+        for (int i = 0; i < entryCount; i++) {
+            symbolMap.addSymbol("symbol" + i, "value" + i);
+        }
+        
+        for (int i = 150; i < (entryCount - 150); i++) {
+            symbolMap.removeSymbol("symbol" + i);
+        }
+        
+        for (int i = 0; i < 150; i++) {
+            assertNotNull(symbolMap.removeSymbol("symbol" + i));
+        }
+        
+        for (int i = 150; i < (entryCount - 150); i++) {
+            assertNull(symbolMap.removeSymbol("symbol" + i));
+        }
+        
+        for (int i = (entryCount - 150); i < entryCount; i++) {
+            assertNotNull(symbolMap.removeSymbol("symbol" + i));
+        }
+        
+        assertEquals(0, symbolMap.size());
+    }
+    
+    @Test(expected = java.lang.IllegalArgumentException.class)
+    public void testRemoveSymbol_7() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+            
+        symbolMap.removeSymbol(null);
+    }    
+   
+    @Test
+    public void testGetSymbols_1() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+            
+        assertNotNull(symbolMap.getSymbols());
+        assertEquals(0, symbolMap.getSymbols().size());
+    }
+    
+    @Test
+    public void testGetSymbols_2() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+            
+        symbolMap.addSymbol("symbol1", "value1");
+        
+        assertNotNull(symbolMap.getSymbols());
+        assertEquals(1, symbolMap.getSymbols().size());
+        assertEquals("symbol1", symbolMap.getSymbols().iterator().next());
+    }
+    
+    @Test
+    public void testGetSymbols_3() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+            
+        symbolMap.addSymbol("symbol1", null);
+        
+        assertNotNull(symbolMap.getSymbols());
+        assertEquals(1, symbolMap.getSymbols().size());
+        assertEquals("symbol1", symbolMap.getSymbols().iterator().next());
+    }
+    
+    @Test
+    public void testGetSymbols_4() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+        Set<String> expectedSymbols = new HashSet<String>();
+        
+        int entryCount = 2000;
+        
+        for (int i = 0; i < entryCount; i++) {
+            symbolMap.addSymbol("symbol" + i, "value" + i);
+            expectedSymbols.add("symbol" + i);
+        }
+        
+        assertNotNull(symbolMap.getSymbols());
+        assertEquals(entryCount, symbolMap.getSymbols().size());
+        
+        Iterator<String> iterator = symbolMap.getSymbols().iterator();
+        for (int i = 0; i < entryCount; i++) {
+            assertTrue(iterator.hasNext());
+            expectedSymbols.remove(iterator.next());
+        }
+        
+        assertTrue(expectedSymbols.isEmpty());
+        assertFalse(iterator.hasNext());
+    }
+    
+    @Test
+    public void testGetSymbols_5() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+        Set<String> expectedSymbols = new HashSet<String>();
+        
+        int entryCount = 2000;
+        
+        for (int i = 0; i < entryCount; i++) {
+            if (i % 7 == 0) {
+                symbolMap.addSymbol("symbol" + i, "value" + i);
+                expectedSymbols.add("symbol" + i);
+            }
+            else {
+                symbolMap.addSymbol("symbol" + i, null);
+                expectedSymbols.add("symbol" + i);
+            }
+        }
+        
+        assertNotNull(symbolMap.getSymbols());
+        assertEquals(entryCount, symbolMap.getSymbols().size());
+        
+        Iterator<String> iterator = symbolMap.getSymbols().iterator();
+        for (int i = 0; i < entryCount; i++) {
+            assertTrue(iterator.hasNext());
+            expectedSymbols.remove(iterator.next());
+        }
+        
+        assertTrue(expectedSymbols.isEmpty());
+        assertFalse(iterator.hasNext());
+    }
+    
+    @Test
+    public void testGetSymbols_6() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+        Set<String> expectedSymbols = new HashSet<String>();
+        
+        int entryCount = 2000;
+        
+        for (int i = 0; i < entryCount; i++) {
+            symbolMap.addSymbol("symbol" + i, "value" + i);
+            expectedSymbols.add("symbol" + i);
+        }
+        
+        for (int i = 150; i < (entryCount - 150); i++) {
+            symbolMap.removeSymbol("symbol" + i);
+            expectedSymbols.remove("symbol" + i);
+        }
+        
+        assertNotNull(symbolMap.getSymbols());
+        assertEquals(2 * 150, symbolMap.getSymbols().size());
+        
+        Iterator<String> iterator = symbolMap.getSymbols().iterator();
+        for (int i = 0; i < 2 * 150; i++) {
+            assertTrue(iterator.hasNext());
+            expectedSymbols.remove(iterator.next());
+        }
+        
+        assertTrue(expectedSymbols.isEmpty());
+        assertFalse(iterator.hasNext());
+    }
+    
+    @Test
+    public void testGetValues_1() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+            
+        assertNotNull(symbolMap.getValues());
+        assertEquals(0, symbolMap.getValues().size());
+    }
+    
+    @Test
+    public void testGetValues_2() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+            
+        symbolMap.addSymbol("symbol1", "value1");
+        
+        assertNotNull(symbolMap.getValues());
+        assertEquals(1, symbolMap.getValues().size());
+        assertEquals("value1", symbolMap.getValues().iterator().next());
+    }
+    
+    @Test
+    public void testGetValues_3() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+            
+        symbolMap.addSymbol("symbol1", null);
+        
+        assertNotNull(symbolMap.getValues());
+        assertEquals(1, symbolMap.getValues().size());
+        assertNull(symbolMap.getValues().iterator().next());
+    }
+    
+    @Test
+    public void testGetValues_4() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+        Set<String> expectedValues = new HashSet<String>();
+        
+        int entryCount = 2000;
+        
+        for (int i = 0; i < entryCount; i++) {
+            symbolMap.addSymbol("symbol" + i, "value" + i);
+            expectedValues.add("value" + i);
+        }
+        
+        assertNotNull(symbolMap.getValues());
+        assertEquals(entryCount, symbolMap.getValues().size());
+        
+        Iterator<String> iterator = symbolMap.getValues().iterator();
+        for (int i = 0; i < entryCount; i++) {
+            assertTrue(iterator.hasNext());
+            expectedValues.remove(iterator.next());
+        }
+        
+        assertTrue(expectedValues.isEmpty());
+        assertFalse(iterator.hasNext());
+    }
+    
+    @Test
+    public void testGetValues_5() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+        Set<String> expectedValues = new HashSet<String>();
+        
+        int entryCount = 2000;
+        
+        for (int i = 0; i < entryCount; i++) {
+            if (i % 7 == 0) {
+                symbolMap.addSymbol("symbol" + i, "value" + i);
+                expectedValues.add("value" + i);
+            }
+            else {
+                symbolMap.addSymbol("symbol" + i, null);
+                expectedValues.add(null);
+            }
+        }
+        
+        assertNotNull(symbolMap.getValues());
+        assertEquals(entryCount, symbolMap.getValues().size());
+        
+        Iterator<String> iterator = symbolMap.getValues().iterator();
+        for (int i = 0; i < entryCount; i++) {
+            assertTrue(iterator.hasNext());
+            expectedValues.remove(iterator.next());
+        }
+        
+        assertTrue(expectedValues.isEmpty());
+        assertFalse(iterator.hasNext());
+    }
+    
+    @Test
+    public void testGetValues_6() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+        Set<String> expectedValues = new HashSet<String>();
+        
+        int entryCount = 2000;
+        
+        for (int i = 0; i < entryCount; i++) {
+            symbolMap.addSymbol("symbol" + i, "value" + i);
+            expectedValues.add("value" + i);
+        }
+        
+        for (int i = 150; i < (entryCount - 150); i++) {
+            symbolMap.removeSymbol("symbol" + i);
+            expectedValues.remove("value" + i);
+        }
+        
+        assertNotNull(symbolMap.getValues());
+        assertEquals(2 * 150, symbolMap.getValues().size());
+        
+        Iterator<String> iterator = symbolMap.getValues().iterator();
+        for (int i = 0; i < 2 * 150; i++) {
+            assertTrue(iterator.hasNext());
+            expectedValues.remove(iterator.next());
+        }
+        
+        assertTrue(expectedValues.isEmpty());
+        assertFalse(iterator.hasNext());
+    }
+    
+    @Test
+    public void testClear_1() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+        
+        symbolMap.clear();
+        assertEquals(0, symbolMap.getValues().size());
+    }
+    
+    @Test
+    public void testClear_2() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+            
+        symbolMap.addSymbol("symbol1", "value1");
+        
+        symbolMap.clear();
+        assertEquals(0, symbolMap.getValues().size());
+    }
+    
+    @Test
+    public void testClear_3() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+            
+        symbolMap.addSymbol("symbol1", null);
+        
+        symbolMap.clear();
+        assertEquals(0, symbolMap.getValues().size());
+    }
+    
+    @Test
+    public void testClear_4() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+        
+        int entryCount = 2000;
+        
+        for (int i = 0; i < entryCount; i++) {
+            symbolMap.addSymbol("symbol" + i, "value" + i);
+        }
+        
+        symbolMap.clear();
+        assertEquals(0, symbolMap.getValues().size());
+    }
+    
+    @Test
+    public void testClear_5() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+        
+        int entryCount = 2000;
+        
+        for (int i = 0; i < entryCount; i++) {
+            if (i % 7 == 0) {
+                symbolMap.addSymbol("symbol" + i, "value" + i);
+            }
+            else {
+                symbolMap.addSymbol("symbol" + i, null);
+            }
+        }
+        
+        symbolMap.clear();
+        assertEquals(0, symbolMap.getValues().size());
+    }
+    
+    @Test
+    public void testClear_6() {
+        SymbolMap<String, String> symbolMap = new DefaultSymbolMap<String, String>();
+        
+        int entryCount = 2000;
+        
+        for (int i = 0; i < entryCount; i++) {
+            symbolMap.addSymbol("symbol" + i, "value" + i);
+        }
+        
+        for (int i = 150; i < (entryCount - 150); i++) {
+            symbolMap.removeSymbol("symbol" + i);
+        }
+        
+        symbolMap.clear();
+        assertEquals(0, symbolMap.getValues().size());
+    }
+    
+    @Test
+    public void testEquals_1() {
+        SymbolMap<String, String> symbolMap1 = new DefaultSymbolMap<String, String>();
+        
+        SymbolMap<String, String> symbolMap2 = new DefaultSymbolMap<String, String>();
+        
+        assertTrue(symbolMap1.equals(symbolMap2));
+    }
+    
+    @Test
+    public void testEquals_2() {
+        SymbolMap<String, String> symbolMap1 = new DefaultSymbolMap<String, String>();
+            
+        SymbolMap<String, String> symbolMap2 = new DefaultSymbolMap<String, String>();
+            
+        symbolMap1.addSymbol("symbol1", "value1");
+        
+        assertFalse(symbolMap1.equals(symbolMap2));
+    }
+    
+    @Test
+    public void testEquals_3() {
+        SymbolMap<String, String> symbolMap1 = new DefaultSymbolMap<String, String>();
+            
+        SymbolMap<String, String> symbolMap2 = new DefaultSymbolMap<String, String>();
+            
+        symbolMap1.addSymbol("symbol1", "value1");
+        symbolMap2.addSymbol("symbol1", "value1");
+        
+        assertTrue(symbolMap1.equals(symbolMap2));
+    }
+
+    @Test
+    public void testEquals_4() {
+        SymbolMap<String, String> symbolMap1 = new DefaultSymbolMap<String, String>();
+                
+        SymbolMap<String, String> symbolMap2 = new DefaultSymbolMap<String, String>();
+        
+        int entryCount = 200;
+        
+        for (int i = 0; i < entryCount; i++) {
+            symbolMap1.addSymbol("symbol" + i, "value" + i);
+            assertFalse(symbolMap1.equals(symbolMap2));
+            symbolMap2.addSymbol("symbol" + i, "value" + i);
+            assertTrue(symbolMap1.equals(symbolMap2));
+        }
+    }
+    
+    @Test
+    public void testEquals_5() {
+        SymbolMap<String, String> symbolMap1 = new DefaultSymbolMap<String, String>();
+               
+        SymbolMap<String, String> symbolMap2 = new DefaultSymbolMap<String, String>();
+        
+        int entryCount = 200;
+        
+        for (int i = 0; i < entryCount; i++) {
+            if (i % 7 == 0) {
+                symbolMap1.addSymbol("symbol" + i, "value" + i);
+                assertFalse(symbolMap1.equals(symbolMap2));
+                symbolMap2.addSymbol("symbol" + i, "value" + i);
+                assertTrue(symbolMap1.equals(symbolMap2));
+            }
+            else {
+                symbolMap1.addSymbol("symbol" + i, null);
+                assertFalse(symbolMap1.equals(symbolMap2));
+                symbolMap2.addSymbol("symbol" + i, null);
+                assertTrue(symbolMap1.equals(symbolMap2));
+            }
+        }
+    }
+    
+    @Test
+    public void testEquals_6() {
+        SymbolMap<String, String> symbolMap1 = new DefaultSymbolMap<String, String>();
+                
+        SymbolMap<String, String> symbolMap2 = new DefaultSymbolMap<String, String>();
+        
+        int entryCount = 200;
+        
+        for (int i = 0; i < entryCount; i++) {
+            symbolMap1.addSymbol("symbol" + i, "value" + i);
+            assertFalse(symbolMap1.equals(symbolMap2));
+            symbolMap2.addSymbol("symbol" + i, "value" + i);
+            assertTrue(symbolMap1.equals(symbolMap2));
+        }
+        
+        for (int i = 150; i < (entryCount - 150); i++) {
+            symbolMap1.removeSymbol("symbol" + i);
+            assertFalse(symbolMap1.equals(symbolMap2));
+            symbolMap2.removeSymbol("symbol" + i);
+            assertTrue(symbolMap1.equals(symbolMap2));
+        }
+    }
+    
+    private void assertSymbolMapEntries(SymbolMap<String, String> symbolMap,
+                                        String[]                  symbols,
+                                        String[]                  values)
+    {
+        assertEquals(symbols.length, symbolMap.size());
+        assertEquals(symbols.length, symbolMap.getSymbols().size());
+        assertEquals(values.length, symbolMap.getValues().size());
+        
+        for (int i = 0; i < symbols.length; i++) {
+            assertTrue(symbolMap.containsSymbol(symbols[i]));
+            assertEquals(values[i], symbolMap.getValue(symbols[i]));
+            assertTrue(symbolMap.getSymbols().contains(symbols[i]));
+            assertTrue(symbolMap.getValues().contains(values[i]));            
+        }
+    }
+}
Index: unk/autoquest-core-usageprofiles-test/src/test/java/de/ugoe/cs/autoquest/usageprofiles/SymbolMapTest.java
===================================================================
--- /trunk/autoquest-core-usageprofiles-test/src/test/java/de/ugoe/cs/autoquest/usageprofiles/SymbolMapTest.java	(revision 1281)
+++ 	(revision )
@@ -1,1026 +1,0 @@
-//   Copyright 2012 Georg-August-Universität Göttingen, Germany
-//
-//   Licensed under the Apache License, Version 2.0 (the "License");
-//   you may not use this file except in compliance with the License.
-//   You may obtain a copy of the License at
-//
-//       http://www.apache.org/licenses/LICENSE-2.0
-//
-//   Unless required by applicable law or agreed to in writing, software
-//   distributed under the License is distributed on an "AS IS" BASIS,
-//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-//   See the License for the specific language governing permissions and
-//   limitations under the License.
-
-package de.ugoe.cs.autoquest.usageprofiles;
-
-import static org.junit.Assert.*;
-
-import java.util.Iterator;
-
-import org.junit.Test;
-
-/**
- * <p>
- * The class <code>SymbolMapTest</code> contains tests for the class
- * <code>{@link SymbolMap}</code>.
- * </p>
- * 
- * @author Patrick Harms
- */
-public class SymbolMapTest {
-
-    @Test
-    public void testSymbolMap_1() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-        
-        assertNotNull(symbolMap);
-        assertEquals(0, symbolMap.size());
-    }
-
-    @Test
-    public void testSymbolMap_2() {
-        SymbolMap<String, String> symbolMap1 =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-        
-        symbolMap1.addSymbol("symbol", "value");
-        
-        SymbolMap<String, String> symbolMap2 = new SymbolMap<String, String>(symbolMap1);
-        
-        assertNotNull(symbolMap2);
-        assertSymbolMapEntries(symbolMap2, new String[] { "symbol" } , new String[] { "value" });
-    }
-
-    @Test(expected = java.lang.IllegalArgumentException.class)
-    public void testSymbolMap_3() throws Exception {
-        new SymbolMap<String, String>((DefaultSymbolComparator<String>) null);
-    }
-
-    @Test(expected = java.lang.IllegalArgumentException.class)
-    public void testSymbolMap_4() throws Exception {
-        new SymbolMap<String, String>((SymbolMap<String, String>) null);
-    }
-    
-    @Test
-    public void testAddSymbol_1() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-            
-        symbolMap.addSymbol("symbol1", "value1");
-        
-        assertNotNull(symbolMap);
-        assertSymbolMapEntries(symbolMap, new String[] { "symbol1" } , new String[] { "value1" });
-    }
-    
-    @Test
-    public void testAddSymbol_2() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-        
-        int entryCount = 2000;
-        
-        String[] symbols = new String[entryCount];
-        String[] values = new String[entryCount];
-        
-        for (int i = 0; i < entryCount; i++) {
-            symbolMap.addSymbol("symbol" + i, "value" + i);
-            symbols[i] = "symbol" + i;
-            values[i] = "value" + i;
-        }
-        
-        assertNotNull(symbolMap);
-        assertSymbolMapEntries(symbolMap, symbols, values);
-    }
-    
-    @Test
-    public void testAddSymbol_3() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-        
-        int entryCount = 2000;
-        
-        String[] symbols = new String[entryCount];
-        String[] values = new String[entryCount];
-        
-        for (int i = 0; i < entryCount; i++) {
-            if (i % 7 == 0) {
-                symbolMap.addSymbol("symbol" + i, "value" + i);
-                symbols[i] = "symbol" + i;
-                values[i] = "value" + i;
-            }
-            else {
-                symbolMap.addSymbol("symbol" + i, null);
-                symbols[i] = "symbol" + i;
-                values[i] = null;
-            }
-        }
-        
-        assertNotNull(symbolMap);
-        assertSymbolMapEntries(symbolMap, symbols, values);
-    }
-    
-    @Test(expected = java.lang.IllegalArgumentException.class)
-    public void testAddSymbol_4() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-            
-        symbolMap.addSymbol(null, null);
-    }    
-    
-    @Test
-    public void testSize_1() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-            
-        assertEquals(0, symbolMap.size());
-    }
-    
-    @Test
-    public void testSize_2() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-            
-        symbolMap.addSymbol("symbol1", "value1");
-        
-        assertEquals(1, symbolMap.size());
-    }
-    
-    @Test
-    public void testSize_3() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-        
-        int entryCount = 2000;
-        
-        for (int i = 0; i < entryCount; i++) {
-            symbolMap.addSymbol("symbol" + i, "value" + i);
-        }
-        
-        assertEquals(entryCount, symbolMap.size());
-    }
-    
-    @Test
-    public void testSize_4() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-        
-        int entryCount = 2000;
-        
-        for (int i = 0; i < entryCount; i++) {
-            if (i % 7 == 0) {
-                symbolMap.addSymbol("symbol" + i, "value" + i);
-            }
-            else {
-                symbolMap.addSymbol("symbol" + i, null);
-            }
-        }
-        
-        assertEquals(entryCount, symbolMap.size());
-    }
-    
-    @Test
-    public void testSize_5() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-        
-        int entryCount = 2000;
-        
-        for (int i = 0; i < entryCount; i++) {
-            symbolMap.addSymbol("symbol" + i, "value" + i);
-        }
-        
-        for (int i = 150; i < (entryCount - 150); i++) {
-            symbolMap.removeSymbol("symbol" + i);
-        }
-        
-        assertEquals(2 * 150, symbolMap.size());
-    }
-    
-    @Test
-    public void testIsEmpty_1() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-            
-        assertTrue(symbolMap.isEmpty());
-    }
-    
-    @Test
-    public void testIsEmpty_2() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-            
-        symbolMap.addSymbol("symbol1", "value1");
-        
-        assertFalse(symbolMap.isEmpty());
-    }
-    
-    @Test
-    public void testIsEmpty_3() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-        
-        int entryCount = 2000;
-        
-        for (int i = 0; i < entryCount; i++) {
-            symbolMap.addSymbol("symbol" + i, "value" + i);
-        }
-        
-        assertFalse(symbolMap.isEmpty());
-    }
-    
-    @Test
-    public void testIsEmpty_4() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-        
-        int entryCount = 2000;
-        
-        for (int i = 0; i < entryCount; i++) {
-            if (i % 7 == 0) {
-                symbolMap.addSymbol("symbol" + i, "value" + i);
-            }
-            else {
-                symbolMap.addSymbol("symbol" + i, null);
-            }
-        }
-        
-        assertFalse(symbolMap.isEmpty());
-    }
-    
-    @Test
-    public void testIsEmpty_5() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-        
-        int entryCount = 2000;
-        
-        for (int i = 0; i < entryCount; i++) {
-            symbolMap.addSymbol("symbol" + i, "value" + i);
-        }
-        
-        for (int i = 150; i < (entryCount - 150); i++) {
-            symbolMap.removeSymbol("symbol" + i);
-        }
-        
-        assertFalse(symbolMap.isEmpty());
-    }
-    
-    @Test
-    public void testContainsSymbol_1() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-            
-        assertFalse(symbolMap.containsSymbol("symbol"));
-    }
-    
-    @Test
-    public void testContainsSymbol_2() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-            
-        symbolMap.addSymbol("symbol1", "value1");
-        
-        assertTrue(symbolMap.containsSymbol("symbol1"));
-    }
-    
-    @Test
-    public void testContainsSymbol_3() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-        
-        int entryCount = 2000;
-        
-        for (int i = 0; i < entryCount; i++) {
-            symbolMap.addSymbol("symbol" + i, "value" + i);
-        }
-        
-        for (int i = 0; i < entryCount; i++) {
-            assertTrue(symbolMap.containsSymbol("symbol" + i));
-        }
-    }
-    
-    @Test
-    public void testContainsSymbol_4() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-        
-        int entryCount = 2000;
-        
-        for (int i = 0; i < entryCount; i++) {
-            if (i % 7 == 0) {
-                symbolMap.addSymbol("symbol" + i, "value" + i);
-            }
-            else {
-                symbolMap.addSymbol("symbol" + i, null);
-            }
-        }
-        
-        for (int i = 0; i < entryCount; i++) {
-            assertTrue(symbolMap.containsSymbol("symbol" + i));
-        }
-    }
-    
-    @Test
-    public void testContainsSymbol_5() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-        
-        int entryCount = 2000;
-        
-        for (int i = 0; i < entryCount; i++) {
-            symbolMap.addSymbol("symbol" + i, "value" + i);
-        }
-        
-        for (int i = 150; i < (entryCount - 150); i++) {
-            symbolMap.removeSymbol("symbol" + i);
-        }
-        
-        for (int i = 0; i < 150; i++) {
-            assertTrue(symbolMap.containsSymbol("symbol" + i));
-        }
-        
-        for (int i = 150; i < (entryCount - 150); i++) {
-            assertFalse(symbolMap.containsSymbol("symbol" + i));
-        }
-        
-        for (int i = (entryCount - 150); i < entryCount; i++) {
-            assertTrue(symbolMap.containsSymbol("symbol" + i));
-        }
-    }
-    
-    @Test(expected = java.lang.IllegalArgumentException.class)
-    public void testContainsSymbol_6() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-            
-        symbolMap.containsSymbol(null);
-    }    
-
-    @Test
-    public void testGetValue_1() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-            
-        assertNull(symbolMap.getValue("symbol"));
-    }
-    
-    @Test
-    public void testGetValue_2() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-            
-        symbolMap.addSymbol("symbol1", "value1");
-        
-        assertNotNull(symbolMap.getValue("symbol1"));
-    }
-    
-    @Test
-    public void testGetValue_3() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-            
-        symbolMap.addSymbol("symbol1", null);
-        
-        assertNull(symbolMap.getValue("symbol1"));
-    }
-    
-    @Test
-    public void testGetValue_4() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-        
-        int entryCount = 2000;
-        
-        for (int i = 0; i < entryCount; i++) {
-            symbolMap.addSymbol("symbol" + i, "value" + i);
-        }
-        
-        for (int i = 0; i < entryCount; i++) {
-            assertNotNull(symbolMap.getValue("symbol" + i));
-        }
-    }
-    
-    @Test
-    public void testGetValue_5() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-        
-        int entryCount = 2000;
-        
-        for (int i = 0; i < entryCount; i++) {
-            if (i % 7 == 0) {
-                symbolMap.addSymbol("symbol" + i, "value" + i);
-            }
-            else {
-                symbolMap.addSymbol("symbol" + i, null);
-            }
-        }
-        
-        for (int i = 0; i < entryCount; i++) {
-            if (i % 7 == 0) {
-                assertNotNull(symbolMap.getValue("symbol" + i));
-            }
-            else {
-                assertNull(symbolMap.getValue("symbol" + i));
-            }
-        }
-    }
-    
-    @Test
-    public void testGetValue_6() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-        
-        int entryCount = 2000;
-        
-        for (int i = 0; i < entryCount; i++) {
-            symbolMap.addSymbol("symbol" + i, "value" + i);
-        }
-        
-        for (int i = 150; i < (entryCount - 150); i++) {
-            symbolMap.removeSymbol("symbol" + i);
-        }
-        
-        for (int i = 0; i < 150; i++) {
-            assertNotNull(symbolMap.getValue("symbol" + i));
-        }
-        
-        for (int i = 150; i < (entryCount - 150); i++) {
-            assertNull(symbolMap.getValue("symbol" + i));
-        }
-        
-        for (int i = (entryCount - 150); i < entryCount; i++) {
-            assertNotNull(symbolMap.getValue("symbol" + i));
-        }
-    }
-    
-    @Test(expected = java.lang.IllegalArgumentException.class)
-    public void testGetValue_7() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-            
-        symbolMap.getValue(null);
-    }    
-
-    @Test
-    public void testRemoveSymbol_1() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-            
-        assertNull(symbolMap.removeSymbol("symbol"));
-    }
-    
-    @Test
-    public void testRemoveSymbol_2() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-            
-        symbolMap.addSymbol("symbol1", "value1");
-        
-        assertNotNull(symbolMap.removeSymbol("symbol1"));
-        assertEquals(0, symbolMap.size());
-    }
-    
-    @Test
-    public void testRemoveSymbol_3() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-            
-        symbolMap.addSymbol("symbol1", null);
-        
-        assertNull(symbolMap.removeSymbol("symbol1"));
-        assertEquals(0, symbolMap.size());
-    }
-    
-    @Test
-    public void testRemoveSymbol_4() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-        
-        int entryCount = 2000;
-        
-        for (int i = 0; i < entryCount; i++) {
-            symbolMap.addSymbol("symbol" + i, "value" + i);
-        }
-        
-        for (int i = 0; i < entryCount; i++) {
-            assertNotNull(symbolMap.removeSymbol("symbol" + i));
-        }
-        
-        assertEquals(0, symbolMap.size());
-    }
-    
-    @Test
-    public void testRemoveSymbol_5() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-        
-        int entryCount = 2000;
-        
-        for (int i = 0; i < entryCount; i++) {
-            if (i % 7 == 0) {
-                symbolMap.addSymbol("symbol" + i, "value" + i);
-            }
-            else {
-                symbolMap.addSymbol("symbol" + i, null);
-            }
-        }
-        
-        for (int i = 0; i < entryCount; i++) {
-            if (i % 7 == 0) {
-                assertNotNull(symbolMap.removeSymbol("symbol" + i));
-            }
-            else {
-                assertNull(symbolMap.removeSymbol("symbol" + i));
-            }
-        }
-        
-        assertEquals(0, symbolMap.size());
-    }
-    
-    @Test
-    public void testRemoveSymbol_6() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-        
-        int entryCount = 2000;
-        
-        for (int i = 0; i < entryCount; i++) {
-            symbolMap.addSymbol("symbol" + i, "value" + i);
-        }
-        
-        for (int i = 150; i < (entryCount - 150); i++) {
-            symbolMap.removeSymbol("symbol" + i);
-        }
-        
-        for (int i = 0; i < 150; i++) {
-            assertNotNull(symbolMap.removeSymbol("symbol" + i));
-        }
-        
-        for (int i = 150; i < (entryCount - 150); i++) {
-            assertNull(symbolMap.removeSymbol("symbol" + i));
-        }
-        
-        for (int i = (entryCount - 150); i < entryCount; i++) {
-            assertNotNull(symbolMap.removeSymbol("symbol" + i));
-        }
-        
-        assertEquals(0, symbolMap.size());
-    }
-    
-    @Test(expected = java.lang.IllegalArgumentException.class)
-    public void testRemoveSymbol_7() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-            
-        symbolMap.removeSymbol(null);
-    }    
-   
-    @Test
-    public void testGetSymbols_1() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-            
-        assertNotNull(symbolMap.getSymbols());
-        assertEquals(0, symbolMap.getSymbols().size());
-    }
-    
-    @Test
-    public void testGetSymbols_2() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-            
-        symbolMap.addSymbol("symbol1", "value1");
-        
-        assertNotNull(symbolMap.getSymbols());
-        assertEquals(1, symbolMap.getSymbols().size());
-        assertEquals("symbol1", symbolMap.getSymbols().iterator().next());
-    }
-    
-    @Test
-    public void testGetSymbols_3() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-            
-        symbolMap.addSymbol("symbol1", null);
-        
-        assertNotNull(symbolMap.getSymbols());
-        assertEquals(1, symbolMap.getSymbols().size());
-        assertEquals("symbol1", symbolMap.getSymbols().iterator().next());
-    }
-    
-    @Test
-    public void testGetSymbols_4() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-        
-        int entryCount = 2000;
-        
-        for (int i = 0; i < entryCount; i++) {
-            symbolMap.addSymbol("symbol" + i, "value" + i);
-        }
-        
-        assertNotNull(symbolMap.getSymbols());
-        assertEquals(entryCount, symbolMap.getSymbols().size());
-        
-        Iterator<String> iterator = symbolMap.getSymbols().iterator();
-        for (int i = 0; i < entryCount; i++) {
-            assertTrue(iterator.hasNext());
-            assertEquals("symbol" + i, iterator.next());
-        }
-        
-        assertFalse(iterator.hasNext());
-    }
-    
-    @Test
-    public void testGetSymbols_5() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-        
-        int entryCount = 2000;
-        
-        for (int i = 0; i < entryCount; i++) {
-            if (i % 7 == 0) {
-                symbolMap.addSymbol("symbol" + i, "value" + i);
-            }
-            else {
-                symbolMap.addSymbol("symbol" + i, null);
-            }
-        }
-        
-        assertNotNull(symbolMap.getSymbols());
-        assertEquals(entryCount, symbolMap.getSymbols().size());
-        
-        Iterator<String> iterator = symbolMap.getSymbols().iterator();
-        for (int i = 0; i < entryCount; i++) {
-            assertTrue(iterator.hasNext());
-            assertEquals("symbol" + i, iterator.next());
-        }
-        
-        assertFalse(iterator.hasNext());
-    }
-    
-    @Test
-    public void testGetSymbols_6() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-        
-        int entryCount = 2000;
-        
-        for (int i = 0; i < entryCount; i++) {
-            symbolMap.addSymbol("symbol" + i, "value" + i);
-        }
-        
-        for (int i = 150; i < (entryCount - 150); i++) {
-            symbolMap.removeSymbol("symbol" + i);
-        }
-        
-        assertNotNull(symbolMap.getSymbols());
-        assertEquals(2 * 150, symbolMap.getSymbols().size());
-        
-        Iterator<String> iterator = symbolMap.getSymbols().iterator();
-        for (int i = 0; i < 2 * 150; i++) {
-            assertTrue(iterator.hasNext());
-            
-            if (i < 150) {
-                assertEquals("symbol" + i, iterator.next());
-            }
-            else if (i >= 150){
-                assertEquals("symbol" + (entryCount - 300 + i), iterator.next());
-            }
-        }
-        
-        assertFalse(iterator.hasNext());
-    }
-    
-    @Test
-    public void testGetValues_1() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-            
-        assertNotNull(symbolMap.getValues());
-        assertEquals(0, symbolMap.getValues().size());
-    }
-    
-    @Test
-    public void testGetValues_2() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-            
-        symbolMap.addSymbol("symbol1", "value1");
-        
-        assertNotNull(symbolMap.getValues());
-        assertEquals(1, symbolMap.getValues().size());
-        assertEquals("value1", symbolMap.getValues().iterator().next());
-    }
-    
-    @Test
-    public void testGetValues_3() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-            
-        symbolMap.addSymbol("symbol1", null);
-        
-        assertNotNull(symbolMap.getValues());
-        assertEquals(1, symbolMap.getValues().size());
-        assertNull(symbolMap.getValues().iterator().next());
-    }
-    
-    @Test
-    public void testGetValues_4() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-        
-        int entryCount = 2000;
-        
-        for (int i = 0; i < entryCount; i++) {
-            symbolMap.addSymbol("symbol" + i, "value" + i);
-        }
-        
-        assertNotNull(symbolMap.getValues());
-        assertEquals(entryCount, symbolMap.getValues().size());
-        
-        Iterator<String> iterator = symbolMap.getValues().iterator();
-        for (int i = 0; i < entryCount; i++) {
-            assertTrue(iterator.hasNext());
-            assertEquals("value" + i, iterator.next());
-        }
-        
-        assertFalse(iterator.hasNext());
-    }
-    
-    @Test
-    public void testGetValues_5() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-        
-        int entryCount = 2000;
-        
-        for (int i = 0; i < entryCount; i++) {
-            if (i % 7 == 0) {
-                symbolMap.addSymbol("symbol" + i, "value" + i);
-            }
-            else {
-                symbolMap.addSymbol("symbol" + i, null);
-            }
-        }
-        
-        assertNotNull(symbolMap.getValues());
-        assertEquals(entryCount, symbolMap.getValues().size());
-        
-        Iterator<String> iterator = symbolMap.getValues().iterator();
-        for (int i = 0; i < entryCount; i++) {
-            assertTrue(iterator.hasNext());
-            if (i % 7 == 0) {
-                assertEquals("value" + i, iterator.next());
-            }
-            else {
-                assertNull(iterator.next());
-            }
-        }
-        
-        assertFalse(iterator.hasNext());
-    }
-    
-    @Test
-    public void testGetValues_6() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-        
-        int entryCount = 2000;
-        
-        for (int i = 0; i < entryCount; i++) {
-            symbolMap.addSymbol("symbol" + i, "value" + i);
-        }
-        
-        for (int i = 150; i < (entryCount - 150); i++) {
-            symbolMap.removeSymbol("symbol" + i);
-        }
-        
-        assertNotNull(symbolMap.getValues());
-        assertEquals(2 * 150, symbolMap.getValues().size());
-        
-        Iterator<String> iterator = symbolMap.getValues().iterator();
-        for (int i = 0; i < 2 * 150; i++) {
-            assertTrue(iterator.hasNext());
-            
-            if (i < 150) {
-                assertEquals("value" + i, iterator.next());
-            }
-            else if (i >= 150){
-                assertEquals("value" + (entryCount - 300 + i), iterator.next());
-            }
-        }
-        
-        assertFalse(iterator.hasNext());
-    }
-    
-    @Test
-    public void testClear_1() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-        
-        symbolMap.clear();
-        assertEquals(0, symbolMap.getValues().size());
-    }
-    
-    @Test
-    public void testClear_2() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-            
-        symbolMap.addSymbol("symbol1", "value1");
-        
-        symbolMap.clear();
-        assertEquals(0, symbolMap.getValues().size());
-    }
-    
-    @Test
-    public void testClear_3() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-            
-        symbolMap.addSymbol("symbol1", null);
-        
-        symbolMap.clear();
-        assertEquals(0, symbolMap.getValues().size());
-    }
-    
-    @Test
-    public void testClear_4() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-        
-        int entryCount = 2000;
-        
-        for (int i = 0; i < entryCount; i++) {
-            symbolMap.addSymbol("symbol" + i, "value" + i);
-        }
-        
-        symbolMap.clear();
-        assertEquals(0, symbolMap.getValues().size());
-    }
-    
-    @Test
-    public void testClear_5() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-        
-        int entryCount = 2000;
-        
-        for (int i = 0; i < entryCount; i++) {
-            if (i % 7 == 0) {
-                symbolMap.addSymbol("symbol" + i, "value" + i);
-            }
-            else {
-                symbolMap.addSymbol("symbol" + i, null);
-            }
-        }
-        
-        symbolMap.clear();
-        assertEquals(0, symbolMap.getValues().size());
-    }
-    
-    @Test
-    public void testClear_6() {
-        SymbolMap<String, String> symbolMap =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-        
-        int entryCount = 2000;
-        
-        for (int i = 0; i < entryCount; i++) {
-            symbolMap.addSymbol("symbol" + i, "value" + i);
-        }
-        
-        for (int i = 150; i < (entryCount - 150); i++) {
-            symbolMap.removeSymbol("symbol" + i);
-        }
-        
-        symbolMap.clear();
-        assertEquals(0, symbolMap.getValues().size());
-    }
-    
-    @Test
-    public void testEquals_1() {
-        SymbolMap<String, String> symbolMap1 =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-        
-        SymbolMap<String, String> symbolMap2 =
-                new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-        
-        assertTrue(symbolMap1.equals(symbolMap2));
-    }
-    
-    @Test
-    public void testEquals_2() {
-        SymbolMap<String, String> symbolMap1 =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-            
-        SymbolMap<String, String> symbolMap2 =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-            
-        symbolMap1.addSymbol("symbol1", "value1");
-        
-        assertFalse(symbolMap1.equals(symbolMap2));
-    }
-    
-    @Test
-    public void testEquals_3() {
-        SymbolMap<String, String> symbolMap1 =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-            
-        SymbolMap<String, String> symbolMap2 =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-            
-        symbolMap1.addSymbol("symbol1", "value1");
-        symbolMap2.addSymbol("symbol1", "value1");
-        
-        assertTrue(symbolMap1.equals(symbolMap2));
-    }
-
-    @Test
-    public void testEquals_4() {
-        SymbolMap<String, String> symbolMap1 =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-                
-        SymbolMap<String, String> symbolMap2 =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-        
-        int entryCount = 200;
-        
-        for (int i = 0; i < entryCount; i++) {
-            symbolMap1.addSymbol("symbol" + i, "value" + i);
-            assertFalse(symbolMap1.equals(symbolMap2));
-            symbolMap2.addSymbol("symbol" + i, "value" + i);
-            assertTrue(symbolMap1.equals(symbolMap2));
-        }
-    }
-    
-    @Test
-    public void testEquals_5() {
-        SymbolMap<String, String> symbolMap1 =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-               
-        SymbolMap<String, String> symbolMap2 =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-        
-        int entryCount = 200;
-        
-        for (int i = 0; i < entryCount; i++) {
-            if (i % 7 == 0) {
-                symbolMap1.addSymbol("symbol" + i, "value" + i);
-                assertFalse(symbolMap1.equals(symbolMap2));
-                symbolMap2.addSymbol("symbol" + i, "value" + i);
-                assertTrue(symbolMap1.equals(symbolMap2));
-            }
-            else {
-                symbolMap1.addSymbol("symbol" + i, null);
-                assertFalse(symbolMap1.equals(symbolMap2));
-                symbolMap2.addSymbol("symbol" + i, null);
-                assertTrue(symbolMap1.equals(symbolMap2));
-            }
-        }
-    }
-    
-    @Test
-    public void testEquals_6() {
-        SymbolMap<String, String> symbolMap1 =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-                
-        SymbolMap<String, String> symbolMap2 =
-            new SymbolMap<String, String>(new DefaultSymbolComparator<String>());
-        
-        int entryCount = 200;
-        
-        for (int i = 0; i < entryCount; i++) {
-            symbolMap1.addSymbol("symbol" + i, "value" + i);
-            assertFalse(symbolMap1.equals(symbolMap2));
-            symbolMap2.addSymbol("symbol" + i, "value" + i);
-            assertTrue(symbolMap1.equals(symbolMap2));
-        }
-        
-        for (int i = 150; i < (entryCount - 150); i++) {
-            symbolMap1.removeSymbol("symbol" + i);
-            assertFalse(symbolMap1.equals(symbolMap2));
-            symbolMap2.removeSymbol("symbol" + i);
-            assertTrue(symbolMap1.equals(symbolMap2));
-        }
-    }
-    
-    private void assertSymbolMapEntries(SymbolMap<String, String> symbolMap,
-                                        String[]                  symbols,
-                                        String[]                  values)
-    {
-        assertEquals(symbols.length, symbolMap.size());
-        assertEquals(symbols.length, symbolMap.getSymbols().size());
-        assertEquals(values.length, symbolMap.getValues().size());
-        
-        for (int i = 0; i < symbols.length; i++) {
-            assertTrue(symbolMap.containsSymbol(symbols[i]));
-            assertEquals(values[i], symbolMap.getValue(symbols[i]));
-            assertTrue(symbolMap.getSymbols().contains(symbols[i]));
-            assertTrue(symbolMap.getValues().contains(values[i]));            
-        }
-    }
-}
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 1281)
+++ /trunk/autoquest-core-usageprofiles-test/src/test/java/de/ugoe/cs/autoquest/usageprofiles/TrieTest.java	(revision 1282)
@@ -75,5 +75,5 @@
     @Test(expected = java.lang.IllegalArgumentException.class)
     public void testTrie_3() throws Exception {
-        new Trie<String>((SymbolComparator<String>) null);
+        new Trie<String>((SymbolStrategy<String>) null);
     }
 
Index: /trunk/autoquest-core-usageprofiles/src/main/java/de/ugoe/cs/autoquest/usageprofiles/DefaultSymbolComparator.java
===================================================================
--- /trunk/autoquest-core-usageprofiles/src/main/java/de/ugoe/cs/autoquest/usageprofiles/DefaultSymbolComparator.java	(revision 1281)
+++ /trunk/autoquest-core-usageprofiles/src/main/java/de/ugoe/cs/autoquest/usageprofiles/DefaultSymbolComparator.java	(revision 1282)
@@ -26,5 +26,7 @@
 public class DefaultSymbolComparator<T> implements SymbolComparator<T> {
 
-    /**  */
+    /**
+     * default serial version UID
+     */
     private static final long serialVersionUID = 1L;
 
@@ -42,16 +44,3 @@
     }
 
-    /* (non-Javadoc)
-     * @see de.ugoe.cs.autoquest.usageprofiles.SymbolComparator#getBucketSearchOrder(Object)
-     */
-    @Override
-    public int[] getBucketSearchOrder(T symbol) {
-        if (symbol != null) {
-            return new int[] { symbol.hashCode() };
-        }
-        else {
-            return null;
-        }
-    }
-
 }
Index: /trunk/autoquest-core-usageprofiles/src/main/java/de/ugoe/cs/autoquest/usageprofiles/DefaultSymbolMap.java
===================================================================
--- /trunk/autoquest-core-usageprofiles/src/main/java/de/ugoe/cs/autoquest/usageprofiles/DefaultSymbolMap.java	(revision 1282)
+++ /trunk/autoquest-core-usageprofiles/src/main/java/de/ugoe/cs/autoquest/usageprofiles/DefaultSymbolMap.java	(revision 1282)
@@ -0,0 +1,182 @@
+//   Copyright 2012 Georg-August-Universität Göttingen, Germany
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+
+package de.ugoe.cs.autoquest.usageprofiles;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * <p>
+ * Default implementation of the {@link SymbolMap}. Uses internally a {@link HashMap} for
+ * implementing the interface by delegating the calls to this class to the internal map.
+ * </p>
+ * 
+ * @author Patrick Harms
+ */
+public class DefaultSymbolMap<K, V> implements SymbolMap<K, V> {
+
+    /**
+     * default serial version id
+     */
+    private static final long serialVersionUID = 1L;
+    
+    /**
+     * the internally used map for implementing this interface
+     */
+    private Map<K, V> delegate;
+
+    /**
+     * <p>
+     * creates a new symbol map
+     * </p>
+     */
+    public DefaultSymbolMap() {
+        delegate = new HashMap<K, V>();
+    }
+
+    /**
+     * <p>
+     * creates a copy of an existing symbol map. The other map must not be null.
+     * </p>
+     *
+     * @param other the map to be copied
+     */
+    public DefaultSymbolMap(SymbolMap<K, V> other) {
+        if (other == null) {
+            throw new IllegalArgumentException("other map must not be null");
+        }
+        
+        delegate = new HashMap<K, V>();
+        
+        for (K symbol : other.getSymbols()) {
+            delegate.put(symbol, other.getValue(symbol));
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.usageprofiles.SymbolMap#size()
+     */
+    @Override
+    public int size() {
+        return delegate.size();
+    }
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.usageprofiles.SymbolMap#isEmpty()
+     */
+    @Override
+    public boolean isEmpty() {
+        return delegate.isEmpty();
+    }
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.usageprofiles.SymbolMap#containsSymbol(java.lang.Object)
+     */
+    @Override
+    public boolean containsSymbol(K symbol) {
+        if (symbol == null) {
+            throw new IllegalArgumentException("symbol must not be null");
+        }
+        
+        return delegate.containsKey(symbol);
+    }
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.usageprofiles.SymbolMap#getValue(java.lang.Object)
+     */
+    @Override
+    public V getValue(K symbol) {
+        if (symbol == null) {
+            throw new IllegalArgumentException("symbol must not be null");
+        }
+        
+        return delegate.get(symbol);
+    }
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.usageprofiles.SymbolMap#addSymbol(java.lang.Object, java.lang.Object)
+     */
+    @Override
+    public void addSymbol(K symbol, V value) {
+        if (symbol == null) {
+            throw new IllegalArgumentException("symbol must not be null");
+        }
+        
+        delegate.put(symbol, value);
+    }
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.usageprofiles.SymbolMap#removeSymbol(java.lang.Object)
+     */
+    @Override
+    public V removeSymbol(K symbol) {
+        if (symbol == null) {
+            throw new IllegalArgumentException("symbol must not be null");
+        }
+        
+        return delegate.remove(symbol);
+    }
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.usageprofiles.SymbolMap#getSymbols()
+     */
+    @Override
+    public Collection<K> getSymbols() {
+        return delegate.keySet();
+    }
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.usageprofiles.SymbolMap#getValues()
+     */
+    @Override
+    public Collection<V> getValues() {
+        return delegate.values();
+    }
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.usageprofiles.SymbolMap#clear()
+     */
+    @Override
+    public void clear() {
+        delegate.clear();
+    }
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public int hashCode() {
+        return delegate.hashCode();
+    }
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    @SuppressWarnings("unchecked")
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        else if (this.getClass().isInstance(obj)) {
+            return delegate.equals(((DefaultSymbolMap<K, V>) obj).delegate);
+        }
+        else {
+            return false;
+        }
+    }
+
+}
Index: /trunk/autoquest-core-usageprofiles/src/main/java/de/ugoe/cs/autoquest/usageprofiles/DefaultSymbolStrategy.java
===================================================================
--- /trunk/autoquest-core-usageprofiles/src/main/java/de/ugoe/cs/autoquest/usageprofiles/DefaultSymbolStrategy.java	(revision 1282)
+++ /trunk/autoquest-core-usageprofiles/src/main/java/de/ugoe/cs/autoquest/usageprofiles/DefaultSymbolStrategy.java	(revision 1282)
@@ -0,0 +1,63 @@
+//   Copyright 2012 Georg-August-Universität Göttingen, Germany
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+
+package de.ugoe.cs.autoquest.usageprofiles;
+
+/**
+ * <p>
+ * Default implementation of a {@link SymbolStrategy}. Uses a {@link DefaultSymbolComparator} and
+ * a {@link DefaultSymbolMap} for managing symbols.
+ * </p>
+ * 
+ * @author Patrick Harms
+ * 
+ * @see SymbolStrategy
+ */
+public class DefaultSymbolStrategy<T> implements SymbolStrategy<T> {
+    
+    /**
+     * default serial version id
+     */
+    private static final long serialVersionUID = 1L;
+    
+    /**
+     * the comparator used in this strategy
+     */
+    private SymbolComparator<T> comparator = new DefaultSymbolComparator<T>();
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.usageprofiles.SymbolStrategy#getSymbolComparator()
+     */
+    @Override
+    public SymbolComparator<T> getSymbolComparator() {
+        return comparator;
+    }
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.usageprofiles.SymbolStrategy#createSymbolMap()
+     */
+    @Override
+    public <V> SymbolMap<T, V> createSymbolMap() {
+        return new DefaultSymbolMap<T, V>();
+    }
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.usageprofiles.SymbolStrategy#copySymbolMap(de.ugoe.cs.autoquest.usageprofiles.SymbolMap)
+     */
+    @Override
+    public <V> SymbolMap<T, V> copySymbolMap(SymbolMap<T, V> other) {
+        return new DefaultSymbolMap<T, V>(other);
+    }
+
+}
Index: /trunk/autoquest-core-usageprofiles/src/main/java/de/ugoe/cs/autoquest/usageprofiles/SymbolComparator.java
===================================================================
--- /trunk/autoquest-core-usageprofiles/src/main/java/de/ugoe/cs/autoquest/usageprofiles/SymbolComparator.java	(revision 1281)
+++ /trunk/autoquest-core-usageprofiles/src/main/java/de/ugoe/cs/autoquest/usageprofiles/SymbolComparator.java	(revision 1282)
@@ -29,6 +29,8 @@
      * <p>
      * compares two symbols and returns true, if the concrete comparison strategy sees both
-     * symbols as equal. The method must be commutative, i.e.,
-     * <code>equals(symbol1, symbol2) == equals(symbol2, symbol1)</code>.
+     * symbols as equal. The method must be commutative and transitive, i.e.,
+     * <code>equals(symbol1, symbol2) == equals(symbol2, symbol1)</code> and
+     * <code>if (equals(symbol1, symbol2) && equals(symbol2, symbol3)) then
+     * equals(symbol1, symbol3)</code>.
      * </p>
      *
@@ -39,33 +41,4 @@
      */
     public boolean equals(T symbol1, T symbol2);
-    
-    /**
-     * <p>
-     * returns a search order for buckets. This method can be used for optimizing a search for
-     * equal symbols. The client of this class can store symbols in buckets of similar symbols.
-     * Those buckets get an id denoted by an integer. The most appropriate bucket for a symbol is
-     * the first element in the array returned by this method. The symbol should therefore be put
-     * into that bucket.
-     * </p>
-     * <p>
-     * In case a search for an equal symbol shall be performed at the client side, the client
-     * checks the available buckets in the order given as return value of this method. All other
-     * buckets are searched afterwards. In this scenario it is ensured, that the equal symbol is
-     * found as soon as possible as the search always starts in the most appropriate bucket.
-     * However, the other buckets are searched, as well, if no equal symbol is found. Therefore,
-     * in the worst case, all buckets are searched. In the optimal case, the equal symbol is found
-     * in the first bucket.
-     * </p>
-     * <p>
-     * The returned array should contain different integers in each field. This allows a most
-     * efficient search. If an integer is repeated, it is up to the clien, if this is ignored.
-     * </p>
-     *
-     * @param symbol the symbol for which the bucket order is to be returned
-     * 
-     * @return a search order for buckets as described
-     * 
-     * @see SymbolMap
-     */
-    public int[] getBucketSearchOrder(T symbol);
+
 }
Index: /trunk/autoquest-core-usageprofiles/src/main/java/de/ugoe/cs/autoquest/usageprofiles/SymbolMap.java
===================================================================
--- /trunk/autoquest-core-usageprofiles/src/main/java/de/ugoe/cs/autoquest/usageprofiles/SymbolMap.java	(revision 1281)
+++ /trunk/autoquest-core-usageprofiles/src/main/java/de/ugoe/cs/autoquest/usageprofiles/SymbolMap.java	(revision 1282)
@@ -16,124 +16,33 @@
 
 import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
 
 /**
  * <p>
- * This class is a data structure for holding symbols which is more efficient than a simple list.
- * This data structure can be used with a comparator to adapt the effective list behavior and to
- * define the equals strategy for comparing objects. After a certain size ({@link #MAX_LIST_SIZE}),
- * the symbol map creates a symbol index consisting of buckets. This allows searching for symbols
- * in a more efficient order as the search can start in the most appropriate of the internal
- * buckets.
+ * This interface defines a data structure for holding symbols. Its implementations can be used to
+ * improve the performance of a trie by tuning its internal symbol storage management.
  * </p>
  * <p>
- * The class is called a map, although it is not. It may contain the same element as separate keys.
- * This implementation is done for performance improvements. If it is required to really assure,
- * that a key exists only once, then each call to the {@link #addSymbol(Object, Object)} method
- * should be done only, if the {@link #containsSymbol(Object)} method for the same symbol returns
- * false.
+ * The interface is called a map, although it is not necessarily. It may contain the same element
+ * as separate keys. This is allowed for performance improvements. If it is required to really
+ * assure, that a key exists only once, then each call to the {@link #addSymbol(Object, Object)}
+ * method should be done only, if the {@link #containsSymbol(Object)} method for the same symbol
+ * returns false.
+ * </p>
+ * <p>
+ * Mapping a symbol to the value null is possible. In this case {@link #getValue(Object)} returns
+ * null for the symbol. But {@link #containsSymbol(Object)} returns true.
  * </p>
  * 
- * @see SymbolComparator
+ * @author Patrick Harms
  * 
- * @author Patrick Harms
+ * @param <T>
+ *            Type of the symbols that are stored
+ * @param <V>
+ *            Type of the values associated with the symbols
+ *            
+ * @see SymbolStrategy
  */
-public class SymbolMap<K, V> implements Serializable {
-
-    /**
-     * <p>
-     * default serial version UID
-     * </p>
-     */
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * <p>
-     * the maximum number of symbols in this map which is still only treated as list instead of
-     * using buckets.
-     * </p>
-     */
-    private static final int MAX_LIST_SIZE = 15;
-    
-    /**
-     * <p>
-     * Comparator to be used for comparing the symbols with each other and to determine a bucket
-     * search order
-     * </p>
-     */
-    private SymbolComparator<K> comparator;
-
-    /**
-     * <p>
-     * Internally maintained plain list of symbols and associated values
-     * </p>
-     */
-    private List<Map.Entry<K, V>> symbolList;
-
-    /**
-     * <p>
-     * If the size of the map exceeds {@link #MAX_LIST_SIZE}, this is the symbol index using buckets
-     * for optimizing the search order.
-     * </p>
-     */
-    private Map<Integer, List<Map.Entry<K, V>>> symbolBuckets;
-    
-    /**
-     * <p>
-     * When using buckets, not any symbol may be associated a correct bucket by the used
-     * comparator. Therefore, we set a default bucket for all such symbols. This may change
-     * if the comparator defines the same bucket for a specific symbol.
-     * </p>
-     */
-    private int defaultBucket = 0;
-    
-    /**
-     * <p>
-     * Instantiates a symbol map with a comparator
-     * </p>
-     *
-     * @param comparator the comparator to use for comparing symbols and for determining bucket
-     *                   search orders
-     * 
-     * @throws IllegalArgumentException if the provided comparator is null
-     */
-    public SymbolMap(SymbolComparator<K> comparator) {
-        if (comparator == null) {
-            throw new IllegalArgumentException("comparator must not be null");
-        }
-        
-        this.comparator = comparator;
-        this.symbolList = new ArrayList<Map.Entry<K, V>>();
-    }
-
-    /**
-     * <p>
-     * Copy constructure
-     * </p>
-     * 
-     * @param otherMap the other map to be copied including its comparator
-     * 
-     * @throws IllegalArgumentException if the provided other map is null
-     */
-    public SymbolMap(SymbolMap<K, V> otherMap) {
-        if (otherMap == null) {
-            throw new IllegalArgumentException("otherMap must not be null");
-        }
-
-        this.comparator = otherMap.comparator;
-        this.symbolList = new ArrayList<Map.Entry<K, V>>(otherMap.symbolList);
-        
-        if (this.symbolList.size() > MAX_LIST_SIZE) {
-            createSymbolBuckets();
-        }
-    }
+public interface SymbolMap<K, V> extends Serializable {
 
     /**
@@ -144,7 +53,5 @@
      * @return as described
      */
-    public int size() {
-        return symbolList.size();
-    }
+    public int size();
 
     /**
@@ -155,7 +62,5 @@
      * @return as described
      */
-    public boolean isEmpty() {
-        return symbolList.isEmpty();
-    }
+    public boolean isEmpty();
 
     /**
@@ -170,11 +75,5 @@
      * @throws IllegalArgumentException if the provided symbol is null
      */
-    public boolean containsSymbol(K symbol) {
-        if (symbol == null) {
-            throw new IllegalArgumentException("symbol must not be null");
-        }
-        
-        return getEntry(symbol) != null;
-    }
+    public boolean containsSymbol(K symbol);
 
     /**
@@ -191,18 +90,5 @@
      * @throws IllegalArgumentException if the provided symbol is null
      */
-    public V getValue(K symbol) {
-        if (symbol == null) {
-            throw new IllegalArgumentException("symbol must not be null");
-        }
-        
-        Map.Entry<K, V> entry = getEntry(symbol);
-        
-        if (entry != null) {
-            return entry.getValue();
-        }
-        else {
-            return null;
-        }
-    }
+    public V getValue(K symbol);
 
     /**
@@ -210,5 +96,5 @@
      * Adds a symbol and an associated value to the map. If the value is null, the symbol is added,
      * anyway and {@link #containsSymbol(Object)} will return true for that symbol. Adding the
-     * same symbol twice will produce two entries. This is contradictory to typical map
+     * same symbol twice may produce two entries. This is contradictory to typical map
      * implementations. To prevent this, the {@link #containsSymbol(Object)} and
      * {@link #removeSymbol(Object)} methods should be used to ensure map behavior.
@@ -222,22 +108,5 @@
      * @throws IllegalArgumentException if the provided symbol is null
      */
-    public void addSymbol(K symbol, V value) {
-        if (symbol == null) {
-            throw new IllegalArgumentException("symbol must not be null");
-        }
-        
-        Map.Entry<K, V> entry = new SymbolMapEntry(symbol, value);
-        
-        symbolList.add(entry);
-            
-        if (symbolList.size() > MAX_LIST_SIZE) {
-            if (symbolBuckets == null) {
-                createSymbolBuckets();
-            }
-            else {
-                addToSymbolBucket(entry);
-            }
-        }
-    }
+    public void addSymbol(K symbol, V value);
 
     /**
@@ -253,24 +122,5 @@
      * @throws IllegalArgumentException if the provided symbol is null
      */
-    public V removeSymbol(K symbol) {
-        if (symbol == null) {
-            throw new IllegalArgumentException("symbol must not be null");
-        }
-        
-        for (int i = 0; i < symbolList.size(); i++) {
-            if (comparator.equals(symbolList.get(i).getKey(), symbol)) {
-                // found the symbol. Remove it from the list, and if required, also from the map.
-                V value = symbolList.remove(i).getValue();
-                
-                if (symbolList.size() > MAX_LIST_SIZE) {
-                    removeFromSymbolBuckets(symbol);
-                }
-                
-                return value;
-            }
-        }
-        
-        return null;
-    }
+    public V removeSymbol(K symbol);
 
     /**
@@ -281,7 +131,5 @@
      * @return as described
      */
-    public Collection<K> getSymbols() {
-        return new ReadOnlyCollectionFacade<K>(symbolList, new SymbolFacade());
-    }
+    public Collection<K> getSymbols();
     
     /**
@@ -294,7 +142,5 @@
      * @return as described
      */
-    public Collection<V> getValues() {
-        return new ReadOnlyCollectionFacade<V>(symbolList, new ValueFacade());
-    }
+    public Collection<V> getValues();
     
     /**
@@ -303,8 +149,5 @@
      * </p>
      */
-    public void clear() {
-        symbolList.clear();
-        symbolBuckets = null;
-    }
+    public void clear();
 
     /* (non-Javadoc)
@@ -312,564 +155,11 @@
      */
     @Override
-    public int hashCode() {
-        return symbolList.size();
-    }
+    public int hashCode();
 
     /* (non-Javadoc)
      * @see java.lang.Object#equals(java.lang.Object)
      */
-    @SuppressWarnings("unchecked")
     @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        else if (this.getClass().isInstance(obj)) {
-            SymbolMap<K, V> other = (SymbolMap<K, V>) obj;
-            
-            return (symbolList.size() == other.symbolList.size()) &&
-                   (symbolList.containsAll(other.symbolList));
-        }
-        else {
-            return false;
-        }
-    }
-
-    /**
-     * <p>
-     * Internally used to create symbol buckets in case the number of stored symbols increased
-     * above {@link #MAX_LIST_SIZE}.
-     * </p>
-     */
-    private void createSymbolBuckets() {
-        //System.out.println("creating symbol buckets");
-        symbolBuckets = new HashMap<Integer, List<Map.Entry<K, V>>>();
-        
-        for (Map.Entry<K, V> symbol : symbolList) {
-            addToSymbolBucket(symbol);
-        }
-    }
-
-    /**
-     * <p>
-     * Adds a symbol and its value to its corresponding bucket. The corresponding bucket is
-     * retrieved from the symbol comparator. It is the first element of the search order returned
-     * by the symbol comparator. If the comparator does not define a search order for the symbol
-     * the entry is added to the default bucket. If the comparator defines a bucket id
-     * identical to the default bucket id, the default bucket id is shifted to another value.
-     * </p>
-     */
-    private void addToSymbolBucket(Map.Entry<K, V> symbolEntry) {
-        int bucketId = defaultBucket;
-        int[] bucketSearchOrder = comparator.getBucketSearchOrder(symbolEntry.getKey());
-        
-        if ((bucketSearchOrder != null) && (bucketSearchOrder.length > 0)) {
-            bucketId = bucketSearchOrder[0];
-            
-            if (bucketId == defaultBucket) {
-                setNewDefaultBucketId();
-            }
-        }
-        
-        List<Map.Entry<K, V>> list = symbolBuckets.get(bucketId);
-        
-        if (list == null) {
-            list = new LinkedList<Map.Entry<K, V>>();
-            symbolBuckets.put(bucketId, list);
-        }
-        
-        list.add(symbolEntry);
-    }
-    
-    /**
-     * <p>
-     * Removes the entry for a given symbol from the buckets. It uses the bucket search order
-     * defined by the symbol comparator to find the symbol as fast as possible.
-     * </p>
-     */
-    private Map.Entry<K, V> removeFromSymbolBuckets(K symbol) {
-        int bucketId = defaultBucket;
-        int[] bucketSearchOrder = comparator.getBucketSearchOrder(symbol);
-        
-        if ((bucketSearchOrder != null) && (bucketSearchOrder.length > 0)) {
-            bucketId = bucketSearchOrder[0];
-        }
-        
-        List<Map.Entry<K, V>> list = symbolBuckets.get(bucketId);
-        Map.Entry<K, V> result = null;
-        
-        if (list != null) {
-            for (int i = 0; i < list.size(); i++) {
-                if (comparator.equals(list.get(i).getKey(), symbol)) {
-                    result = list.remove(i);
-                    break;
-                }
-            }
-            
-            if (list.isEmpty()) {
-                symbolBuckets.remove(bucketId);
-            }
-        }
-        
-        return result;
-    }
-
-    /**
-     * <p>
-     * Updates the default bucket id to a new one
-     * </p>
-     */
-    private void setNewDefaultBucketId() {
-        int oldDefaultBucket = defaultBucket;
-        do {
-            defaultBucket += 1;
-        }
-        while (symbolBuckets.containsKey(defaultBucket));
-        
-        symbolBuckets.put(defaultBucket, symbolBuckets.get(oldDefaultBucket));
-    }
-
-    /**
-     * <p>
-     * searches for the entry belonging to the given symbol. The method either uses the list if
-     * buckets are not used yet, or it uses the buckets and searches them in the order defined
-     * by the comparator. If the symbol isn't found and the comparator does not refer all buckets,
-     * then also the other buckets are searched for the symbol.
-     * </p>
-     */
-    private Map.Entry<K, V> getEntry(K symbol) {
-        Map.Entry<K, V> entry = null;
-        if (symbolBuckets == null) {
-            entry = lookup(symbol, symbolList);
-        }
-        else {
-            int[] bucketSearchOrder = comparator.getBucketSearchOrder(symbol);
-            for (int bucketId : bucketSearchOrder) {
-                List<Map.Entry<K, V>> list = symbolBuckets.get(bucketId);
-                if (list != null) {
-                    entry = lookup(symbol, list);
-                    if (entry != null) {
-                        break;
-                    }
-                }
-            }
-            
-            // try to search the other buckets
-            if (entry == null) {
-                Arrays.sort(bucketSearchOrder);
-                for (Map.Entry<Integer, List<Map.Entry<K, V>>> bucket : symbolBuckets.entrySet()) {
-                    if (Arrays.binarySearch(bucketSearchOrder, bucket.getKey()) < 0) {
-                        List<Map.Entry<K, V>> list = bucket.getValue();
-                        if (list != null) {
-                            entry = lookup(symbol, list);
-                            if (entry != null) {
-                                break;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        
-        return entry;
-    }
-
-    /**
-     * <p>
-     * Convenience method to look up a symbol in a list of entries using the comparator.
-     * </p>
-     */
-    private Map.Entry<K, V> lookup(K symbol, List<Map.Entry<K, V>> list) {
-        for (Map.Entry<K, V> candidate : list) {
-            if (comparator.equals(candidate.getKey(), symbol)) {
-                return candidate;
-            }
-        }
-        
-        return null;
-    }
-
-    /**
-     * <p>
-     * Internally used data structure for storing symbol value pairs
-     * </p>
-     * 
-     * @author Patrick Harms
-     */
-    private class SymbolMapEntry implements Map.Entry<K, V> {
-        
-        /**
-         * the symbol to map to a value
-         */
-        private K symbol;
-        
-        /**
-         * the value associated with the symbol
-         */
-        private V value;
-
-        /**
-         * <p>
-         * Simple constructor for initializing the entry with a symbol and its associated value.
-         * </p>
-         */
-        private SymbolMapEntry(K symbol, V value) {
-            super();
-            this.symbol = symbol;
-            this.value = value;
-        }
-
-        /* (non-Javadoc)
-         * @see java.util.Map.Entry#getKey()
-         */
-        @Override
-        public K getKey() {
-            return symbol;
-        }
-
-        /* (non-Javadoc)
-         * @see java.util.Map.Entry#getValue()
-         */
-        @Override
-        public V getValue() {
-            return value;
-        }
-
-        /* (non-Javadoc)
-         * @see java.util.Map.Entry#setValue(java.lang.Object)
-         */
-        @Override
-        public V setValue(V value) {
-            V oldValue = this.value;
-            this.value = value;
-            return oldValue;
-        }
-
-        /* (non-Javadoc)
-         * @see java.lang.Object#hashCode()
-         */
-        @Override
-        public int hashCode() {
-            return symbol.hashCode();
-        }
-
-        /* (non-Javadoc)
-         * @see java.lang.Object#equals(java.lang.Object)
-         */
-        @SuppressWarnings("unchecked")
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            else if (this.getClass().isInstance(obj)) {
-                SymbolMapEntry other = (SymbolMapEntry) obj;
-                return (symbol.equals(other.symbol) &&
-                        (value == null ? other.value == null : value.equals(other.value)));
-            }
-            else {
-                return false;
-            }
-        }
-
-        /* (non-Javadoc)
-         * @see java.lang.Object#toString()
-         */
-        @Override
-        public String toString() {
-            return symbol + "=" + value;
-        }
-
-    }
-
-    /**
-     * <p>
-     * Used to create an efficient facade for accessing the internal list of entries either only
-     * for the symbols or only for the values. It is a default implementation of the collection
-     * interface. The entry facade provided to the constructor decides, if either the list
-     * accesses only the symbols or only the values. 
-     * </p>
-     * 
-     * @author Patrick Harms
-     */
-    private class ReadOnlyCollectionFacade<TYPE> implements Collection<TYPE> {
-        
-        /**
-         * the list facaded by this facade
-         */
-        private List<Map.Entry<K, V>> list;
-        
-        /**
-         * the facade to be used for the entries
-         */
-        private EntryFacade<TYPE> entryFacade;
-        
-        /**
-         * <p>
-         * Initializes the facade with the facaded list and the facade to be used for the entries
-         * </p>
-         */
-        private ReadOnlyCollectionFacade(List<Map.Entry<K, V>> list, EntryFacade<TYPE> entryFacade)
-        {
-            this.list = list;
-            this.entryFacade = entryFacade;
-        }
-
-        /* (non-Javadoc)
-         * @see java.util.Collection#size()
-         */
-        @Override
-        public int size() {
-            return list.size();
-        }
-
-        /* (non-Javadoc)
-         * @see java.util.Collection#isEmpty()
-         */
-        @Override
-        public boolean isEmpty() {
-            return list.isEmpty();
-        }
-
-        /* (non-Javadoc)
-         * @see java.util.Collection#contains(java.lang.Object)
-         */
-        @Override
-        public boolean contains(Object o) {
-            if (o == null) {
-                for (Map.Entry<K, V> entry : list) {
-                    if (entryFacade.getFacadedElement(entry) == null) {
-                        return true;
-                    }
-                }
-            }
-            else {
-                for (Map.Entry<K, V> entry : list) {
-                    if (o.equals(entryFacade.getFacadedElement(entry))) {
-                        return true;
-                    }
-                }
-            }
-            
-            return false;
-        }
-
-        /* (non-Javadoc)
-         * @see java.util.Collection#toArray()
-         */
-        @Override
-        public Object[] toArray() {
-            Object[] result = new Object[list.size()];
-            
-            for (int i = 0; i < list.size(); i++) {
-                result[i] = entryFacade.getFacadedElement(list.get(i));
-            }
-            
-            return result;
-        }
-
-        /* (non-Javadoc)
-         * @see java.util.Collection#toArray(T[])
-         */
-        @SuppressWarnings("unchecked")
-        @Override
-        public <T> T[] toArray(T[] a) {
-            T[] result = a;
-            
-            for (int i = 0; i < list.size(); i++) {
-                result[i] = (T) entryFacade.getFacadedElement(list.get(i));
-            }
-            
-            return result;
-        }
-
-        /* (non-Javadoc)
-         * @see java.util.Collection#add(java.lang.Object)
-         */
-        @Override
-        public boolean add(TYPE e) {
-            throw new UnsupportedOperationException("this collection is read only");
-        }
-
-        /* (non-Javadoc)
-         * @see java.util.Collection#remove(java.lang.Object)
-         */
-        @Override
-        public boolean remove(Object o) {
-            throw new UnsupportedOperationException("this collection is read only");
-        }
-
-        /* (non-Javadoc)
-         * @see java.util.Collection#containsAll(java.util.Collection)
-         */
-        @Override
-        public boolean containsAll(Collection<?> c) {
-            for (Object candidate : c) {
-                if (!contains(candidate)) {
-                    return false;
-                }
-            }
-            
-            return true;
-        }
-
-        /* (non-Javadoc)
-         * @see java.util.Collection#addAll(java.util.Collection)
-         */
-        @Override
-        public boolean addAll(Collection<? extends TYPE> c) {
-            throw new UnsupportedOperationException("this collection is read only");
-        }
-
-        /* (non-Javadoc)
-         * @see java.util.Collection#removeAll(java.util.Collection)
-         */
-        @Override
-        public boolean removeAll(Collection<?> c) {
-            throw new UnsupportedOperationException("this collection is read only");
-        }
-
-        /* (non-Javadoc)
-         * @see java.util.Collection#retainAll(java.util.Collection)
-         */
-        @Override
-        public boolean retainAll(Collection<?> c) {
-            throw new UnsupportedOperationException("this collection is read only");
-        }
-
-        /* (non-Javadoc)
-         * @see java.util.Collection#clear()
-         */
-        @Override
-        public void clear() {
-            throw new UnsupportedOperationException("this collection is read only");
-        }
-
-        /* (non-Javadoc)
-         * @see java.util.Collection#iterator()
-         */
-        @Override
-        public Iterator<TYPE> iterator() {
-            return new ReadOnlyCollectionIteratorFacade<TYPE>(list.iterator(), entryFacade);
-        }
-        
-    }
-
-    /**
-     * <p>
-     * Implementation of an iterator to facade an iterator on the internal list of symbol entries.
-     * </p>
-     * 
-     * @author Patrick Harms
-     */
-    private class ReadOnlyCollectionIteratorFacade<TYPE> implements Iterator<TYPE> {
-        
-        /**
-         * the facaded iterator
-         */
-        private Iterator<Map.Entry<K, V>> iterator;
-        
-        /**
-         * the facade for the entries provided by the facaded iterator
-         */
-        private EntryFacade<TYPE> entryFacade;
-        
-        /**
-         * <p>
-         * initialized this facade with the facaded iterator and the entry facade to be used for
-         * the entries.
-         * </p>
-         */
-        private ReadOnlyCollectionIteratorFacade(Iterator<Map.Entry<K, V>> iterator,
-                                                 EntryFacade<TYPE>         entryFacade)
-        {
-            this.iterator = iterator;
-            this.entryFacade = entryFacade;
-        }
-
-        /* (non-Javadoc)
-         * @see java.util.Iterator#hasNext()
-         */
-        @Override
-        public boolean hasNext() {
-            return iterator.hasNext();
-        }
-
-        /* (non-Javadoc)
-         * @see java.util.Iterator#next()
-         */
-        @Override
-        public TYPE next() {
-            return entryFacade.getFacadedElement(iterator.next());
-        }
-
-        /* (non-Javadoc)
-         * @see java.util.Iterator#remove()
-         */
-        @Override
-        public void remove() {
-            throw new UnsupportedOperationException("this iterator is read only");
-        }
-        
-    }
-        
-    /**
-     * <p>
-     * Used to facade symbol entries and to return only this part of an entry, that is relevant.
-     * </p>
-     * 
-     * @author Patrick Harms
-     */
-    private abstract class EntryFacade<T> {
-        
-        /**
-         * <p>
-         * Returns only the part of an entry that is relevant or required.
-         * </p>
-         *
-         * @param entry of which the part shall be returned
-         * 
-         * @return the part of the entry to be returned
-         */
-        protected abstract T getFacadedElement(Entry<K, V> entry);
-        
-    }
-    
-    /**
-     * <p>
-     * Implementation of the entry facade returning the entries key, i.e. the symbol.
-     * </p>
-     * 
-     * @author Patrick Harms
-     */
-    private class SymbolFacade extends EntryFacade<K> {
-
-        /* (non-Javadoc)
-         * @see ReadOnlyCollectionIteratorFacade#getFacadedElement(Entry)
-         */
-        @Override
-        protected K getFacadedElement(Entry<K, V> entry) {
-            return entry.getKey();
-        }
-    }
-    
-    /**
-     * <p>
-     * Implementation of the entry facade returning the entries value, i.e. the value associated to
-     * the symbol.
-     * </p>
-     * 
-     * @author Patrick Harms
-     */
-    private class ValueFacade extends EntryFacade<V> {
-
-        /* (non-Javadoc)
-         * @see ReadOnlyCollectionIteratorFacade#getFacadedElement(Entry)
-         */
-        @Override
-        protected V getFacadedElement(Entry<K, V> entry) {
-            return entry.getValue();
-        }
-    }
+    public boolean equals(Object obj);
 
 }
Index: /trunk/autoquest-core-usageprofiles/src/main/java/de/ugoe/cs/autoquest/usageprofiles/SymbolStrategy.java
===================================================================
--- /trunk/autoquest-core-usageprofiles/src/main/java/de/ugoe/cs/autoquest/usageprofiles/SymbolStrategy.java	(revision 1282)
+++ /trunk/autoquest-core-usageprofiles/src/main/java/de/ugoe/cs/autoquest/usageprofiles/SymbolStrategy.java	(revision 1282)
@@ -0,0 +1,68 @@
+//   Copyright 2012 Georg-August-Universität Göttingen, Germany
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+
+package de.ugoe.cs.autoquest.usageprofiles;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ * The symbol strategy is used in a trie for comparing symbols and for storing symbols in maps.
+ * The symbol strategy can be changed to improve the performance of the trie depending on the type
+ * of symbols.
+ * </p>
+ * 
+ * @author Patrick Harms
+ * 
+ * @param <T>
+ *            Type of the symbols that are compared and stored
+ * @see Trie
+ */
+public interface SymbolStrategy<T> extends Serializable {
+
+    /**
+     * <p>
+     * Returns a comparator for symbols that can be used to compare two symbols
+     * </p>
+     *
+     * @return a comparator for symbols
+     * 
+     * @see SymbolComparator
+     */
+    public SymbolComparator<T> getSymbolComparator();
+
+    /**
+     * <p>
+     * returns a new empty map for storing symbols and associated values. The symbols are the
+     * keys of the map.
+     * </p>
+     *
+     * @return as described
+     * 
+     * @see SymbolMap
+     */
+    public <V> SymbolMap<T, V> createSymbolMap();
+
+    /**
+     * <p>
+     * returns a copy of the provided map for storing symbols and associated values.
+     * </p>
+     *
+     * @return as described
+     * 
+     * @see SymbolMap
+     */
+    public <V> SymbolMap<T, V> copySymbolMap(SymbolMap<T, V> other);
+
+}
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 1281)
+++ /trunk/autoquest-core-usageprofiles/src/main/java/de/ugoe/cs/autoquest/usageprofiles/Trie.java	(revision 1282)
@@ -29,6 +29,6 @@
 /**
  * <p>
- * This class implements a <it>trie</it>, i.e., a tree of sequences that the occurence of
- * subsequences up to a predefined length. This length is the trie order.
+ * This class implements a <it>trie</it>, i.e., a tree of sequences that represents the occurrence
+ * of subsequences up to a predefined length. This length is the trie order.
  * </p>
  * 
@@ -51,5 +51,5 @@
     /**
      * <p>
-     * Collection of all symbols occuring in the trie.
+     * Collection of all symbols occurring in the trie.
      * </p>
      */
@@ -65,36 +65,48 @@
     /**
      * <p>
-     * Comparator to be used for comparing the symbols with each other
-     * </p>
-     */
-    private SymbolComparator<T> comparator;
-
-    /**
-     * <p>
-     * Contructor. Creates a new Trie with a {@link DefaultSymbolComparator}.
+     * Strategy for handling symbols, i.e., for comparing and storing them
+     * </p>
+     */
+    private SymbolStrategy<T> strategy;
+
+    /**
+     * <p>
+     * Constructor. Creates a new trie with a {@link DefaultSymbolStrategy}.
      * </p>
      */
     public Trie() {
-        this(new DefaultSymbolComparator<T>());
-    }
-
-    /**
-     * <p>
-     * Contructor. Creates a new Trie with that uses a specific {@link SymbolComparator}.
-     * </p>
-     */
-    public Trie(SymbolComparator<T> comparator) {
-        this.comparator = comparator;
-        rootNode = new TrieNode<T>(comparator);
-        knownSymbols = new SymbolMap<T, T>(this.comparator);
-    }
-
-    /**
-     * <p>
-     * Copy-Constructor. Creates a new Trie as the copy of other. The other trie must not be null.
+        this(new DefaultSymbolStrategy<T>());
+    }
+
+    /**
+     * <p>
+     * Constructor. Creates a new trie that uses a specific {@link SymbolStrategy}.
+     * </p>
+     * 
+     * @param strategy
+     *            strategy to be used for managing symbols
+     * 
+     * @throws IllegalArgumentException
+     *            if the strategy is null
+     */
+    public Trie(SymbolStrategy<T> strategy) {
+        if (strategy == null) {
+            throw new IllegalArgumentException("strategy must not be null");
+        }
+        this.strategy = strategy;
+        rootNode = new TrieNode<T>(strategy);
+        knownSymbols = strategy.createSymbolMap();
+    }
+
+    /**
+     * <p>
+     * Copy-Constructor. Creates a new trie as the copy of other. The other trie must not be null.
      * </p>
      * 
      * @param other
-     *            Trie that is copied
+     *            trie that is copied
+     * 
+     * @throws IllegalArgumentException
+     *            if the other trie is null
      */
     public Trie(Trie<T> other) {
@@ -103,14 +115,14 @@
         }
         rootNode = new TrieNode<T>(other.rootNode);
-        knownSymbols = new SymbolMap<T, T>(other.knownSymbols);
-        comparator = other.comparator;
-    }
-
-    /**
-     * <p>
-     * Returns a collection of all symbols occuring in the trie.
-     * </p>
-     * 
-     * @return symbols occuring in the trie
+        strategy = other.strategy;
+        knownSymbols = strategy.copySymbolMap(other.knownSymbols);
+    }
+
+    /**
+     * <p>
+     * Returns a collection of all symbols occurring in the trie.
+     * </p>
+     * 
+     * @return symbols occurring in the trie
      */
     public Collection<T> getKnownSymbols() {
@@ -202,10 +214,10 @@
     /**
      * <p>
-     * Returns the number of occurences of the given sequence.
+     * Returns the number of occurrences of the given sequence.
      * </p>
      * 
      * @param sequence
-     *            sequence whose number of occurences is required
-     * @return number of occurences of the sequence
+     *            sequence whose number of occurrences is required
+     * @return number of occurrences of the sequence
      */
     public int getCount(List<T> sequence) {
@@ -220,5 +232,5 @@
     /**
      * <p>
-     * Returns the number of occurences of the given prefix and a symbol that follows it.<br>
+     * Returns the number of occurrences of the given prefix and a symbol that follows it.<br>
      * Convenience function to simplify usage of {@link #getCount(List)}.
      * </p>
@@ -228,5 +240,5 @@
      * @param follower
      *            suffix of the sequence
-     * @return number of occurences of the sequence
+     * @return number of occurrences of the sequence
      * @see #getCount(List)
      */
@@ -326,5 +338,5 @@
      * <p>
      * used to recursively process the trie. The provided processor will be called for any path
-     * through the tree. The processor may abort the processing through returns values of its
+     * through the trie. The processor may abort the processing through return values of its
      * {@link TrieProcessor#process(List, int)} method.
      * </p>
@@ -348,5 +360,5 @@
      * </p>
      * 
-     * @param context   the context of the currently processed trie node, i.e. the preceeding
+     * @param context   the context of the currently processed trie node, i.e. the preceding
      *                  symbols
      * @param child     the processed trie node
@@ -489,5 +501,5 @@
      * <p>
      * adds a new symbol to the collection of known symbols if this symbol is not already
-     * contained. The symbols are compared using the comparator.
+     * contained.
      * </p>
      *
@@ -496,5 +508,5 @@
     private void addToKnownSymbols(T symbol) {
         if (!knownSymbols.containsSymbol(symbol)) {
-            knownSymbols.addSymbol(symbol, symbol);
+            knownSymbols.addSymbol(symbol, null);
         }
     }
@@ -529,5 +541,5 @@
         /**
          * <p>
-         * Contructor. Creates a new TrieVertex.
+         * Constructor. Creates a new TrieVertex.
          * </p>
          * 
@@ -635,5 +647,5 @@
      */
     public void updateKnownSymbols() {
-        knownSymbols = new SymbolMap<T, T>(this.comparator);
+        knownSymbols = strategy.createSymbolMap();
         for (TrieNode<T> node : rootNode.getChildren()) {
             addToKnownSymbols(node.getSymbol());
@@ -643,5 +655,5 @@
     /**
      * <p>
-     * Two Tries are defined as equal, if their {@link #rootNode} are equal.
+     * Two tries are defined as equal, if their {@link #rootNode}s are equal.
      * </p>
      * 
Index: /trunk/autoquest-core-usageprofiles/src/main/java/de/ugoe/cs/autoquest/usageprofiles/TrieNode.java
===================================================================
--- /trunk/autoquest-core-usageprofiles/src/main/java/de/ugoe/cs/autoquest/usageprofiles/TrieNode.java	(revision 1281)
+++ /trunk/autoquest-core-usageprofiles/src/main/java/de/ugoe/cs/autoquest/usageprofiles/TrieNode.java	(revision 1282)
@@ -29,5 +29,5 @@
  * <p>
  * This class implements a node of a trie. Each node is associated with a symbol and has a counter.
- * The counter marks the number of occurences of the sequence defined by the path from the root of
+ * The counter marks the number of occurrences of the sequence defined by the path from the root of
  * the trie to this node.
  * </p>
@@ -50,5 +50,5 @@
     /**
      * <p>
-     * Counter for the number of occurences of the sequence.
+     * Counter for the number of occurrences of the sequence.
      * </p>
      */
@@ -71,8 +71,8 @@
     /**
      * <p>
-     * Comparator to be used for comparing the symbols with each other
-     * </p>
-     */
-    private SymbolComparator<T> comparator;
+     * Strategy for handling symbols, i.e., for comparing and storing them
+     * </p>
+     */
+    private SymbolStrategy<T> strategy;
 
     /**
@@ -80,9 +80,9 @@
      * Constructor. Creates a new TrieNode without a symbol associated.<br>
      * <b>This constructor should only be used to create the root node of the trie!</b>
-     * The comparator used by the tree node will be a {@link DefaultSymbolComparator}.
+     * The strategy used by the trie node will be a {@link DefaultSymbolStrategy}.
      * </p>
      */
     TrieNode() {
-        this(new DefaultSymbolComparator<T>());
+        this(new DefaultSymbolStrategy<T>());
     }
 
@@ -90,12 +90,15 @@
      * <p>
      * Constructor. Creates a new TrieNode. The symbol must not be null.
-     * The comparator used by the tree node will be a {@link DefaultSymbolComparator}.
+     * The strategy used by the trie node will be a {@link DefaultSymbolStrategy}.
      * </p>
      * 
      * @param symbol
      *            symbol associated with the trie node
+     * 
+     * @throws IllegalArgumentException
+     *            if the provided symbol is null
      */
     TrieNode(T symbol) {
-        this(symbol, new DefaultSymbolComparator<T>());
+        this(symbol, new DefaultSymbolStrategy<T>());
     }
 
@@ -103,29 +106,40 @@
      * <p>
      * Constructor. Creates a new TrieNode without a symbol associated using the provided
-     * comparator.<br>
+     * strategy.<br>
      * <b>This constructor should only be used to create the root node of the trie!</b>
-     * <br>The comparator must not be null.
-     * </p>
-     */
-    TrieNode(SymbolComparator<T> comparator) {
-        if (comparator == null) {
-            throw new IllegalArgumentException("comparator must not be null!");
-        }
-        this.comparator = comparator;
+     * <br>The strategy must not be null.
+     * </p>
+     * 
+     * @param strategy
+     *            the strategy used for comparing and storing symbols
+     * 
+     * @throws IllegalArgumentException
+     *            if the provided strategy is null
+     */
+    TrieNode(SymbolStrategy<T> strategy) {
+        if (strategy == null) {
+            throw new IllegalArgumentException("strategy must not be null!");
+        }
+        this.strategy = strategy;
         this.symbol = null;
         count = 0;
-        children = new SymbolMap<T, TrieNode<T>>(this.comparator);
-    }
-
-    /**
-     * <p>
-     * Constructor. Creates a new TrieNode using the provided comparator. The symbol and the
-     * comparator must not be null.
+        children = strategy.createSymbolMap();
+    }
+
+    /**
+     * <p>
+     * Constructor. Creates a new TrieNode using the provided strategy. The symbol and the
+     * strategy must not be null.
      * </p>
      * 
      * @param symbol
      *            symbol associated with the trie node
-     */
-    TrieNode(T symbol, SymbolComparator<T> comparator) {
+     * @param strategy
+     *            the strategy used for comparing and storing symbols
+     * 
+     * @throws IllegalArgumentException
+     *            if the provided symbol or strategy is null
+     */
+    TrieNode(T symbol, SymbolStrategy<T> strategy) {
         if (symbol == null) {
             throw new IllegalArgumentException
@@ -134,11 +148,11 @@
         this.symbol = symbol;
         
-        if (comparator == null) {
-            throw new IllegalArgumentException("comparator must not be null!");
-        }
-        this.comparator = comparator;
+        if (strategy == null) {
+            throw new IllegalArgumentException("strategy must not be null!");
+        }
+        this.strategy = strategy;
 
         count = 0;
-        children = new SymbolMap<T, TrieNode<T>>(this.comparator);
+        children = strategy.createSymbolMap();
     }
 
@@ -148,5 +162,8 @@
      * </p>
      * 
-     * @param other
+     * @param other the trie node to create the copy of
+     * 
+     * @throws IllegalArgumentException
+     *            if the provided node is null
      */
     TrieNode(TrieNode<T> other) {
@@ -156,6 +173,6 @@
         symbol = other.symbol;
         count = other.count;
-        comparator = other.comparator;
-        children = new SymbolMap<T, TrieNode<T>>(this.comparator);
+        strategy = other.strategy;
+        children = strategy.createSymbolMap();
         
         for (TrieNode<T> child : other.children.getValues()) {
@@ -175,6 +192,6 @@
     public void add(List<T> subsequence) {
         if (!subsequence.isEmpty()) {
-            if (!comparator.equals(symbol, subsequence.get(0))) { // should be guaranteed by
-                                                                  // the recursion/TrieRoot!
+            if (!strategy.getSymbolComparator().equals(symbol, subsequence.get(0))) {
+                // should be guaranteed by the recursion/TrieRoot!
                 throw new AssertionError("Invalid trie operation!");
             }
@@ -201,8 +218,8 @@
     /**
      * <p>
-     * Returns the number of occurences of the sequence represented by the node.
-     * </p>
-     * 
-     * @return number of occurences of the sequence represented by the node
+     * Returns the number of occurrences of the sequence represented by the node.
+     * </p>
+     * 
+     * @return number of occurrences of the sequence represented by the node
      */
     public int getCount() {
@@ -224,5 +241,5 @@
         TrieNode<T> node = getChild(symbol);
         if (node == null) {
-            node = new TrieNode<T>(symbol, comparator);
+            node = new TrieNode<T>(symbol, strategy);
             children.addSymbol(symbol, node);
         }
@@ -283,5 +300,5 @@
     /**
      * <p>
-     * Returns a collection of all symbols that follow a this node, i.e., the symbols associated
+     * Returns a collection of all symbols that follow this node, i.e., the symbols associated
      * with the children of this node.
      * </p>
@@ -399,5 +416,5 @@
     /**
      * <p>
-     * Recursive methods that collects all nodes that are ancestors of leafs and stores them in the
+     * Recursive method that collects all nodes that are ancestors of leafs and stores them in the
      * set.
      * </p>
@@ -457,5 +474,6 @@
      * <p>
      * Two TrieNodes are defined as equal, if their {@link #count}, {@link #symbol}, and
-     * {@link #children} are equal. For the comparison of their symbols the comparator is used.
+     * {@link #children} are equal. For the comparison of their symbols the comparator provided
+     * by the symbol management strategy is used.
      * </p>
      * 
@@ -477,5 +495,5 @@
                 return count == otherNode.count &&
                     symbol.getClass().isInstance(((TrieNode) other).symbol) &&
-                    comparator.equals(symbol, ((TrieNode<T>) other).symbol) &&
+                    strategy.getSymbolComparator().equals(symbol, ((TrieNode<T>) other).symbol) &&
                     children.equals(((TrieNode) other).children);
             }
