//   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.tasktrees.temporalrelation;

import static org.junit.Assert.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.junit.Before;
import org.junit.Test;

import de.ugoe.cs.autoquest.eventcore.Event;
import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask;
import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTaskInstance;
import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskFactory;
import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;
import de.ugoe.cs.autoquest.tasktrees.treeimpl.TaskFactory;
import de.ugoe.cs.autoquest.test.DummyGUIElement;
import de.ugoe.cs.autoquest.test.DummyInteraction;
import de.ugoe.cs.autoquest.usageprofiles.SymbolMap;

/**
 * <p>
 * The class <code>SymbolMapTest</code> contains tests for the class
 * <code>{@link SymbolMap}</code>.
 * </p>
 * 
 * @author Patrick Harms
 */
public class TaskSymbolIdentityMapTest {

    /** */
    private ITaskFactory taskFactory = new TaskFactory();
    
    /** */
    Map<String, ITask> tasks = new HashMap<String, ITask>();
    
    @Before
    public void setUp() {
        tasks = new HashMap<String, ITask>();
    }
    
    @Test
    public void testSymbolMap_1() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
        
        assertNotNull(symbolMap);
        assertEquals(0, symbolMap.size());
    }

    @Test
    public void testSymbolMap_2() {
        TaskSymbolIdentityMap<String> symbolMap1 = new TaskSymbolIdentityMap<String>();
        
        ITaskInstance taskInstance = createTaskInstance("symbol");
        symbolMap1.addSymbol(taskInstance, "value");
        
        SymbolMap<ITaskInstance, String> symbolMap2 = new TaskSymbolIdentityMap<String>(symbolMap1);
        
        assertNotNull(symbolMap2);
        assertSymbolMapEntries(symbolMap2, new ITaskInstance[] { taskInstance },
                               new String[] { "value" });
    }

    @Test(expected = java.lang.IllegalArgumentException.class)
    public void testSymbolMap_3() throws Exception {
        new TaskSymbolBucketedMap<String>((TaskSymbolBucketedMap<String>) null);
    }
    
    @Test
    public void testAddSymbol_1() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
            
        ITaskInstance taskInstance = createTaskInstance("symbol");
        symbolMap.addSymbol(taskInstance, "value1");
        
        assertNotNull(symbolMap);
        assertSymbolMapEntries(symbolMap, new ITaskInstance[] { taskInstance },
                               new String[] { "value1" });
    }
    
    @Test
    public void testAddSymbol_2() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
        
        int entryCount = 2000;
        
        ITaskInstance[] symbols = new ITaskInstance[entryCount];
        String[] values = new String[entryCount];
        
        for (int i = 0; i < entryCount; i++) {
            symbols[i] = createTaskInstance("symbol" + i);
            symbolMap.addSymbol(symbols[i], "value" + i);
            values[i] = "value" + i;
        }
        
        assertNotNull(symbolMap);
        assertSymbolMapEntries(symbolMap, symbols, values);
    }
    
    @Test
    public void testAddSymbol_3() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
        
        int entryCount = 2000;
        
        ITaskInstance[] symbols = new ITaskInstance[entryCount];
        String[] values = new String[entryCount];
        
        for (int i = 0; i < entryCount; i++) {
            symbols[i] = createTaskInstance("symbol" + i);
            if (i % 7 == 0) {
                values[i] = "value" + i;
            }
            else {
                values[i] = null;
            }
            
            symbolMap.addSymbol(symbols[i], values[i]);
        }
        
        assertNotNull(symbolMap);
        assertSymbolMapEntries(symbolMap, symbols, values);
    }
    
    @Test(expected = java.lang.IllegalArgumentException.class)
    public void testAddSymbol_4() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
            
        symbolMap.addSymbol(null, null);
    }    
    
    @Test
    public void testSize_1() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
            
        assertEquals(0, symbolMap.size());
    }
    
    @Test
    public void testSize_2() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
            
        symbolMap.addSymbol(createTaskInstance("symbol1"), "value1");
        
        assertEquals(1, symbolMap.size());
    }
    
    @Test
    public void testSize_3() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
        
        int entryCount = 2000;
        
        for (int i = 0; i < entryCount; i++) {
            symbolMap.addSymbol(createTaskInstance("symbol" + i), "value" + i);
        }
        
        assertEquals(entryCount, symbolMap.size());
    }
    
    @Test
    public void testSize_4() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
        
        int entryCount = 2000;
        
        for (int i = 0; i < entryCount; i++) {
            if (i % 7 == 0) {
                symbolMap.addSymbol(createTaskInstance("symbol" + i), "value" + i);
            }
            else {
                symbolMap.addSymbol(createTaskInstance("symbol" + i), null);
            }
        }
        
        assertEquals(entryCount, symbolMap.size());
    }
    
    @Test
    public void testSize_5() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
        
        int entryCount = 2000;
        
        for (int i = 0; i < entryCount; i++) {
            symbolMap.addSymbol(createTaskInstance("symbol" + i), "value" + i);
        }
        
        for (int i = 150; i < (entryCount - 150); i++) {
            symbolMap.removeSymbol(createTaskInstance("symbol" + i));
        }
        
        assertEquals(2 * 150, symbolMap.size());
    }
    
    @Test
    public void testIsEmpty_1() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
            
        assertTrue(symbolMap.isEmpty());
    }
    
    @Test
    public void testIsEmpty_2() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
            
        symbolMap.addSymbol(createTaskInstance("symbol1"), "value1");
        
        assertFalse(symbolMap.isEmpty());
    }
    
    @Test
    public void testIsEmpty_3() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
        
        int entryCount = 2000;
        
        for (int i = 0; i < entryCount; i++) {
            symbolMap.addSymbol(createTaskInstance("symbol" + i), "value" + i);
        }
        
        assertFalse(symbolMap.isEmpty());
    }
    
    @Test
    public void testIsEmpty_4() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
        
        int entryCount = 2000;
        
        for (int i = 0; i < entryCount; i++) {
            if (i % 7 == 0) {
                symbolMap.addSymbol(createTaskInstance("symbol" + i), "value" + i);
            }
            else {
                symbolMap.addSymbol(createTaskInstance("symbol" + i), null);
            }
        }
        
        assertFalse(symbolMap.isEmpty());
    }
    
    @Test
    public void testIsEmpty_5() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
        
        int entryCount = 2000;
        
        for (int i = 0; i < entryCount; i++) {
            symbolMap.addSymbol(createTaskInstance("symbol" + i), "value" + i);
        }
        
        for (int i = 150; i < (entryCount - 150); i++) {
            symbolMap.removeSymbol(createTaskInstance("symbol" + i));
        }
        
        assertFalse(symbolMap.isEmpty());
    }
    
    @Test
    public void testContainsSymbol_1() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
            
        assertFalse(symbolMap.containsSymbol(createTaskInstance("symbol")));
    }
    
    @Test
    public void testContainsSymbol_2() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
            
        symbolMap.addSymbol(createTaskInstance("symbol1"), "value1");
        
        assertTrue(symbolMap.containsSymbol(createTaskInstance("symbol1")));
    }
    
    @Test
    public void testContainsSymbol_3() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
        
        int entryCount = 2000;
        
        for (int i = 0; i < entryCount; i++) {
            symbolMap.addSymbol(createTaskInstance("symbol" + i), "value" + i);
        }
        
        for (int i = 0; i < entryCount; i++) {
            assertTrue(symbolMap.containsSymbol(createTaskInstance("symbol" + i)));
        }
    }
    
    @Test
    public void testContainsSymbol_4() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
        
        int entryCount = 2000;
        
        for (int i = 0; i < entryCount; i++) {
            if (i % 7 == 0) {
                symbolMap.addSymbol(createTaskInstance("symbol" + i), "value" + i);
            }
            else {
                symbolMap.addSymbol(createTaskInstance("symbol" + i), null);
            }
        }
        
        for (int i = 0; i < entryCount; i++) {
            assertTrue(symbolMap.containsSymbol(createTaskInstance("symbol" + i)));
        }
    }
    
    @Test
    public void testContainsSymbol_5() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
        
        int entryCount = 2000;
        
        for (int i = 0; i < entryCount; i++) {
            symbolMap.addSymbol(createTaskInstance("symbol" + i), "value" + i);
        }
        
        for (int i = 150; i < (entryCount - 150); i++) {
            symbolMap.removeSymbol(createTaskInstance("symbol" + i));
        }
        
        for (int i = 0; i < 150; i++) {
            assertTrue(symbolMap.containsSymbol(createTaskInstance("symbol" + i)));
        }
        
        for (int i = 150; i < (entryCount - 150); i++) {
            assertFalse(symbolMap.containsSymbol(createTaskInstance("symbol" + i)));
        }
        
        for (int i = (entryCount - 150); i < entryCount; i++) {
            assertTrue(symbolMap.containsSymbol(createTaskInstance("symbol" + i)));
        }
    }
    
    @Test(expected = java.lang.IllegalArgumentException.class)
    public void testContainsSymbol_6() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
            
        symbolMap.containsSymbol(null);
    }    

    @Test
    public void testGetValue_1() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
            
        assertNull(symbolMap.getValue(createTaskInstance("symbol")));
    }
    
    @Test
    public void testGetValue_2() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
            
        symbolMap.addSymbol(createTaskInstance("symbol1"), "value1");
        
        assertNotNull(symbolMap.getValue(createTaskInstance("symbol1")));
    }
    
    @Test
    public void testGetValue_3() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
            
        symbolMap.addSymbol(createTaskInstance("symbol1"), null);
        
        assertNull(symbolMap.getValue(createTaskInstance("symbol1")));
    }
    
    @Test
    public void testGetValue_4() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
        
        int entryCount = 2000;
        
        for (int i = 0; i < entryCount; i++) {
            symbolMap.addSymbol(createTaskInstance("symbol" + i), "value" + i);
        }
        
        for (int i = 0; i < entryCount; i++) {
            assertNotNull(symbolMap.getValue(createTaskInstance("symbol" + i)));
        }
    }
    
    @Test
    public void testGetValue_5() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
        
        int entryCount = 2000;
        
        for (int i = 0; i < entryCount; i++) {
            if (i % 7 == 0) {
                symbolMap.addSymbol(createTaskInstance("symbol" + i), "value" + i);
            }
            else {
                symbolMap.addSymbol(createTaskInstance("symbol" + i), null);
            }
        }
        
        for (int i = 0; i < entryCount; i++) {
            if (i % 7 == 0) {
                assertNotNull(symbolMap.getValue(createTaskInstance("symbol" + i)));
            }
            else {
                assertNull(symbolMap.getValue(createTaskInstance("symbol" + i)));
            }
        }
    }
    
    @Test
    public void testGetValue_6() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
        
        int entryCount = 2000;
        
        for (int i = 0; i < entryCount; i++) {
            symbolMap.addSymbol(createTaskInstance("symbol" + i), "value" + i);
        }
        
        for (int i = 150; i < (entryCount - 150); i++) {
            symbolMap.removeSymbol(createTaskInstance("symbol" + i));
        }
        
        for (int i = 0; i < 150; i++) {
            assertNotNull(symbolMap.getValue(createTaskInstance("symbol" + i)));
        }
        
        for (int i = 150; i < (entryCount - 150); i++) {
            assertNull(symbolMap.getValue(createTaskInstance("symbol" + i)));
        }
        
        for (int i = (entryCount - 150); i < entryCount; i++) {
            assertNotNull(symbolMap.getValue(createTaskInstance("symbol" + i)));
        }
    }
    
    @Test(expected = java.lang.IllegalArgumentException.class)
    public void testGetValue_7() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
            
        symbolMap.getValue(null);
    }    

    @Test
    public void testRemoveSymbol_1() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
            
        assertNull(symbolMap.removeSymbol(createTaskInstance("symbol")));
    }
    
    @Test
    public void testRemoveSymbol_2() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
            
        symbolMap.addSymbol(createTaskInstance("symbol1"), "value1");
        
        assertNotNull(symbolMap.removeSymbol(createTaskInstance("symbol1")));
        assertEquals(0, symbolMap.size());
    }
    
    @Test
    public void testRemoveSymbol_3() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
            
        symbolMap.addSymbol(createTaskInstance("symbol1"), null);
        
        assertNull(symbolMap.removeSymbol(createTaskInstance("symbol1")));
        assertEquals(0, symbolMap.size());
    }
    
    @Test
    public void testRemoveSymbol_4() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
        
        int entryCount = 2000;
        
        for (int i = 0; i < entryCount; i++) {
            symbolMap.addSymbol(createTaskInstance("symbol" + i), "value" + i);
        }
        
        for (int i = 0; i < entryCount; i++) {
            assertNotNull(symbolMap.removeSymbol(createTaskInstance("symbol" + i)));
        }
        
        assertEquals(0, symbolMap.size());
    }
    
    @Test
    public void testRemoveSymbol_5() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
        
        int entryCount = 2000;
        
        for (int i = 0; i < entryCount; i++) {
            if (i % 7 == 0) {
                symbolMap.addSymbol(createTaskInstance("symbol" + i), "value" + i);
            }
            else {
                symbolMap.addSymbol(createTaskInstance("symbol" + i), null);
            }
        }
        
        for (int i = 0; i < entryCount; i++) {
            if (i % 7 == 0) {
                assertNotNull(symbolMap.removeSymbol(createTaskInstance("symbol" + i)));
            }
            else {
                assertNull(symbolMap.removeSymbol(createTaskInstance("symbol" + i)));
            }
        }
        
        assertEquals(0, symbolMap.size());
    }
    
    @Test
    public void testRemoveSymbol_6() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
        
        int entryCount = 2000;
        
        for (int i = 0; i < entryCount; i++) {
            symbolMap.addSymbol(createTaskInstance("symbol" + i), "value" + i);
        }
        
        for (int i = 150; i < (entryCount - 150); i++) {
            symbolMap.removeSymbol(createTaskInstance("symbol" + i));
        }
        
        for (int i = 0; i < 150; i++) {
            assertNotNull(symbolMap.removeSymbol(createTaskInstance("symbol" + i)));
        }
        
        for (int i = 150; i < (entryCount - 150); i++) {
            assertNull(symbolMap.removeSymbol(createTaskInstance("symbol" + i)));
        }
        
        for (int i = (entryCount - 150); i < entryCount; i++) {
            assertNotNull(symbolMap.removeSymbol(createTaskInstance("symbol" + i)));
        }
        
        assertEquals(0, symbolMap.size());
    }
    
    @Test(expected = java.lang.IllegalArgumentException.class)
    public void testRemoveSymbol_7() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
            
        symbolMap.removeSymbol(null);
    }    
   
    @Test
    public void testGetSymbols_1() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
            
        assertNotNull(symbolMap.getSymbols());
        assertEquals(0, symbolMap.getSymbols().size());
    }
    
    @Test
    public void testGetSymbols_2() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
         
        ITaskInstance task = createTaskInstance("symbol1");
        symbolMap.addSymbol(task, "value1");
        
        assertNotNull(symbolMap.getSymbols());
        assertEquals(1, symbolMap.getSymbols().size());
        assertEquals(task, symbolMap.getSymbols().iterator().next());
    }
    
    @Test
    public void testGetSymbols_3() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
            
        ITaskInstance task = createTaskInstance("symbol1");
        symbolMap.addSymbol(task, null);
        
        assertNotNull(symbolMap.getSymbols());
        assertEquals(1, symbolMap.getSymbols().size());
        assertEquals(task, symbolMap.getSymbols().iterator().next());
    }
    
    @Test
    public void testGetSymbols_4() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
        Set<ITaskInstance> expectedSymbols = new HashSet<ITaskInstance>();
        
        int entryCount = 2000;
        
        for (int i = 0; i < entryCount; i++) {
            ITaskInstance task = createTaskInstance("symbol" + i);
            symbolMap.addSymbol(task, "value" + i);
            expectedSymbols.add(task);
        }
        
        assertNotNull(symbolMap.getSymbols());
        assertEquals(entryCount, symbolMap.getSymbols().size());
        
        Iterator<ITaskInstance> 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<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
        Set<ITaskInstance> expectedSymbols = new HashSet<ITaskInstance>();
        
        int entryCount = 2000;
        
        for (int i = 0; i < entryCount; i++) {
            ITaskInstance task = createTaskInstance("symbol" + i);
            
            if (i % 7 == 0) {
                symbolMap.addSymbol(task, "value" + i);
            }
            else {
                symbolMap.addSymbol(task, null);
            }
            
            expectedSymbols.add(task);
        }
        
        assertNotNull(symbolMap.getSymbols());
        assertEquals(entryCount, symbolMap.getSymbols().size());
        
        Iterator<ITaskInstance> 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<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
        List<ITaskInstance> expectedSymbols = new ArrayList<ITaskInstance>();
        
        int entryCount = 2000;
        
        for (int i = 0; i < entryCount; i++) {
            ITaskInstance task = createTaskInstance("symbol" + i);
            symbolMap.addSymbol(task, "value" + i);
            expectedSymbols.add(task);
        }
        
        for (int i = 150; i < (entryCount - 150); i++) {
            symbolMap.removeSymbol(expectedSymbols.remove(150));
        }
        
        assertNotNull(symbolMap.getSymbols());
        assertEquals(2 * 150, symbolMap.getSymbols().size());
        
        Iterator<ITaskInstance> 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<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
            
        assertNotNull(symbolMap.getValues());
        assertEquals(0, symbolMap.getValues().size());
    }
    
    @Test
    public void testGetValues_2() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
            
        symbolMap.addSymbol(createTaskInstance("symbol1"), "value1");
        
        assertNotNull(symbolMap.getValues());
        assertEquals(1, symbolMap.getValues().size());
        assertEquals("value1", symbolMap.getValues().iterator().next());
    }
    
    @Test
    public void testGetValues_3() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
            
        symbolMap.addSymbol(createTaskInstance("symbol1"), null);
        
        assertNotNull(symbolMap.getValues());
        assertEquals(1, symbolMap.getValues().size());
        assertNull(symbolMap.getValues().iterator().next());
    }
    
    @Test
    public void testGetValues_4() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
        Set<String> expectedValues = new HashSet<String>();
        
        int entryCount = 2000;
        
        for (int i = 0; i < entryCount; i++) {
            symbolMap.addSymbol(createTaskInstance("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<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
        Set<String> expectedValues = new HashSet<String>();
        
        int entryCount = 2000;
        
        for (int i = 0; i < entryCount; i++) {
            if (i % 7 == 0) {
                symbolMap.addSymbol(createTaskInstance("symbol" + i), "value" + i);
                expectedValues.add("value" + i);
            }
            else {
                symbolMap.addSymbol(createTaskInstance("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<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
        Set<String> expectedValues = new HashSet<String>();
        
        int entryCount = 2000;
        
        for (int i = 0; i < entryCount; i++) {
            symbolMap.addSymbol(createTaskInstance("symbol" + i), "value" + i);
            expectedValues.add("value" + i);
        }
        
        for (int i = 150; i < (entryCount - 150); i++) {
            symbolMap.removeSymbol(createTaskInstance("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<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
        
        symbolMap.clear();
        assertEquals(0, symbolMap.getValues().size());
    }
    
    @Test
    public void testClear_2() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
            
        symbolMap.addSymbol(createTaskInstance("symbol1"), "value1");
        
        symbolMap.clear();
        assertEquals(0, symbolMap.getValues().size());
    }
    
    @Test
    public void testClear_3() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
            
        symbolMap.addSymbol(createTaskInstance("symbol1"), null);
        
        symbolMap.clear();
        assertEquals(0, symbolMap.getValues().size());
    }
    
    @Test
    public void testClear_4() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
        
        int entryCount = 2000;
        
        for (int i = 0; i < entryCount; i++) {
            symbolMap.addSymbol(createTaskInstance("symbol" + i), "value" + i);
        }
        
        symbolMap.clear();
        assertEquals(0, symbolMap.getValues().size());
    }
    
    @Test
    public void testClear_5() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
        
        int entryCount = 2000;
        
        for (int i = 0; i < entryCount; i++) {
            if (i % 7 == 0) {
                symbolMap.addSymbol(createTaskInstance("symbol" + i), "value" + i);
            }
            else {
                symbolMap.addSymbol(createTaskInstance("symbol" + i), null);
            }
        }
        
        symbolMap.clear();
        assertEquals(0, symbolMap.getValues().size());
    }
    
    @Test
    public void testClear_6() {
        SymbolMap<ITaskInstance, String> symbolMap = new TaskSymbolIdentityMap<String>();
        
        int entryCount = 2000;
        
        for (int i = 0; i < entryCount; i++) {
            symbolMap.addSymbol(createTaskInstance("symbol" + i), "value" + i);
        }
        
        for (int i = 150; i < (entryCount - 150); i++) {
            symbolMap.removeSymbol(createTaskInstance("symbol" + i));
        }
        
        symbolMap.clear();
        assertEquals(0, symbolMap.getValues().size());
    }
    
    @Test
    public void testEquals_1() {
        SymbolMap<ITaskInstance, String> symbolMap1 = new TaskSymbolIdentityMap<String>();
        
        SymbolMap<ITaskInstance, String> symbolMap2 = new TaskSymbolIdentityMap<String>();
        
        assertTrue(symbolMap1.equals(symbolMap2));
    }
    
    @Test
    public void testEquals_2() {
        SymbolMap<ITaskInstance, String> symbolMap1 = new TaskSymbolIdentityMap<String>();
            
        SymbolMap<ITaskInstance, String> symbolMap2 = new TaskSymbolIdentityMap<String>();
            
        symbolMap1.addSymbol(createTaskInstance("symbol1"), "value1");
        
        assertFalse(symbolMap1.equals(symbolMap2));
    }
    
    @Test
    public void testEquals_3() {
        SymbolMap<ITaskInstance, String> symbolMap1 = new TaskSymbolIdentityMap<String>();
            
        SymbolMap<ITaskInstance, String> symbolMap2 = new TaskSymbolIdentityMap<String>();
        
        ITaskInstance task = createTaskInstance("symbol1");
        symbolMap1.addSymbol(task, "value1");
        symbolMap2.addSymbol(task, "value1");
        
        assertTrue(symbolMap1.equals(symbolMap2));
    }

    @Test
    public void testEquals_4() {
        SymbolMap<ITaskInstance, String> symbolMap1 = new TaskSymbolIdentityMap<String>();
                
        SymbolMap<ITaskInstance, String> symbolMap2 = new TaskSymbolIdentityMap<String>();
        
        int entryCount = 1000;
        
        for (int i = 0; i < entryCount; i++) {
            ITaskInstance task = createTaskInstance("symbol1");
            symbolMap1.addSymbol(task, "value" + i);
            assertFalse(symbolMap1.equals(symbolMap2));
            symbolMap2.addSymbol(task, "value" + i);
            assertTrue(symbolMap1.equals(symbolMap2));
        }
    }
    
    @Test
    public void testEquals_5() {
        SymbolMap<ITaskInstance, String> symbolMap1 = new TaskSymbolIdentityMap<String>();
               
        SymbolMap<ITaskInstance, String> symbolMap2 = new TaskSymbolIdentityMap<String>();
        
        int entryCount = 1000;
        
        for (int i = 0; i < entryCount; i++) {
            ITaskInstance task = createTaskInstance("symbol" + i);
            if (i % 7 == 0) {
                symbolMap1.addSymbol(task, "value" + i);
                assertFalse(symbolMap1.equals(symbolMap2));
                symbolMap2.addSymbol(task, "value" + i);
                assertTrue(symbolMap1.equals(symbolMap2));
            }
            else {
                symbolMap1.addSymbol(task, null);
                assertFalse(symbolMap1.equals(symbolMap2));
                symbolMap2.addSymbol(task, null);
                assertTrue(symbolMap1.equals(symbolMap2));
            }
        }
    }
    
    @Test
    public void testEquals_6() {
        SymbolMap<ITaskInstance, String> symbolMap1 = new TaskSymbolIdentityMap<String>();
                
        SymbolMap<ITaskInstance, String> symbolMap2 = new TaskSymbolIdentityMap<String>();
        
        int entryCount = 1000;
        
        ITaskInstance[] taskInstances = new ITaskInstance[entryCount];
        
        for (int i = 0; i < entryCount; i++) {
            ITaskInstance task = createTaskInstance("symbol" + i);
            taskInstances[i] = task;
            symbolMap1.addSymbol(task, "value" + i);
            assertFalse(symbolMap1.equals(symbolMap2));
            symbolMap2.addSymbol(task, "value" + i);
            assertTrue(symbolMap1.equals(symbolMap2));
        }
        
        for (int i = 150; i < (entryCount - 150); i++) {
            symbolMap1.removeSymbol(taskInstances[i]);
            assertFalse(symbolMap1.equals(symbolMap2));
            symbolMap2.removeSymbol(taskInstances[i]);
            assertTrue(symbolMap1.equals(symbolMap2));
        }
    }
    
    @Test
    public void testPerformance_Contains_1() {
        SymbolMap<ITaskInstance, String> symbolMap1 = new TaskSymbolIdentityMap<String>();
        int mapSize = 100000;
        int noOfLookups = 1000000;
        
        ITaskInstance[] taskInstances = new ITaskInstance[mapSize];
        
        for (int i = 0; i < mapSize; i++) {
            ITaskInstance task = createTaskInstance("symbol" + i);
            taskInstances[i] = task;
            symbolMap1.addSymbol(task, "value" + i);
        }
        
        long start = System.currentTimeMillis();
        for (int i = 0; i < noOfLookups; i++) {
            symbolMap1.containsSymbol(taskInstances[noOfLookups % mapSize]);
        }
        
        System.out.println(noOfLookups + " look ups in a map of size " + mapSize + " took " +
                           (System.currentTimeMillis() - start));
    }
    
    @Test
    public void testPerformance_GetValue_1() {
        SymbolMap<ITaskInstance, String> symbolMap1 = new TaskSymbolIdentityMap<String>();
        int mapSize = 100000;
        int noOfLookups = 1000000;
        
        ITaskInstance[] taskInstances = new ITaskInstance[mapSize];
        
        for (int i = 0; i < mapSize; i++) {
            ITaskInstance task = createTaskInstance("symbol" + i);
            taskInstances[i] = task;
            symbolMap1.addSymbol(task, "value" + i);
        }
        
        long start = System.currentTimeMillis();
        for (int i = 0; i < noOfLookups; i++) {
            symbolMap1.getValue(taskInstances[noOfLookups % mapSize]);
        }
        
        System.out.println(noOfLookups + " value retrievals in a map of size " + mapSize +
                           " took " + (System.currentTimeMillis() - start));
    }
    
    
    @Test
    public void testPerformance_AddRemove_1() {
        SymbolMap<ITaskInstance, String> symbolMap1 = new TaskSymbolIdentityMap<String>();
        int mapSize = 100000;
        int noOfLookups = 1000000;
        
        ITaskInstance[] taskInstances = new ITaskInstance[mapSize];
        
        for (int i = 0; i < mapSize; i++) {
            ITaskInstance task = createTaskInstance("symbol" + i);
            taskInstances[i] = task;
            symbolMap1.addSymbol(task, "value" + i);
        }
        
        long start = System.currentTimeMillis();
        for (int i = 0; i < noOfLookups; i++) {
            ITaskInstance task = taskInstances[noOfLookups % mapSize];
            symbolMap1.addSymbol(task, symbolMap1.removeSymbol(task));
        }
        
        System.out.println(noOfLookups + " adds and removes in a map of size " + mapSize +
                           " took " + (System.currentTimeMillis() - start));
    }
    
    /**
     *
     */
    private ITaskInstance createTaskInstance(String id) {
        ITask task = tasks.get(id);
        Event event = null;
        
        if (task == null) {
            event = new Event(new DummyInteraction(id, 0), new DummyGUIElement("default"));
            task = taskFactory.createNewEventTask(event.toString());
            
            tasks.put(id, task);
        }
        else {
            event = ((IEventTaskInstance) task.getInstances().iterator().next()).getEvent();
        }
        
        return taskFactory.createNewTaskInstance((IEventTask) task, event);
    }

    private void assertSymbolMapEntries(SymbolMap<ITaskInstance, String> symbolMap,
                                        ITaskInstance[]                  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]));            
        }
    }
}
