Index: trunk/autoquest-test-utils/src/main/java/de/ugoe/cs/autoquest/tasktrees/TaskTreeDecoder.java
===================================================================
--- trunk/autoquest-test-utils/src/main/java/de/ugoe/cs/autoquest/tasktrees/TaskTreeDecoder.java	(revision 1294)
+++ trunk/autoquest-test-utils/src/main/java/de/ugoe/cs/autoquest/tasktrees/TaskTreeDecoder.java	(revision 1325)
@@ -17,4 +17,6 @@
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
 import java.util.Map;
 import java.util.regex.Matcher;
@@ -163,4 +165,86 @@
         String id = matcher.group(2);
         
+        // determine the children before creating this instance
+        List<ITaskInstance> children = new LinkedList<ITaskInstance>();
+        while (taskMatcher.find() && !"}".equals(taskMatcher.group(0))) {
+            children.add(parseTaskInstance(taskMatcher));
+        }
+        
+        // get the model
+        ITask task = getCreateTask(id, type, children);
+        
+        // create the respective instance
+        ITaskInstance instance;
+        
+        if (task instanceof ISequence) {
+            instance = taskFactory.createNewTaskInstance((ISequence) task);
+        }
+        else if (task instanceof ISelection) {
+            instance = taskFactory.createNewTaskInstance((ISelection) task);
+        }
+        else if (task instanceof IIteration) {
+            instance = taskFactory.createNewTaskInstance((IIteration) task);
+        }
+        else if (task instanceof IOptional) {
+            instance = taskFactory.createNewTaskInstance((IOptional) task);
+        }
+        else {
+            Event event = !task.getInstances().isEmpty() ?
+                ((IEventTaskInstance) task.getInstances().iterator().next()).getEvent() :
+                createUserInteractionEvent(type, id, matcher.group(4));
+                
+            instance = taskFactory.createNewTaskInstance((IEventTask) task, event);
+        }  
+        
+        // add the children to the instance
+        for (ITaskInstance childInstance : children) {
+            if (instance instanceof ISequenceInstance) {
+                taskBuilder.addChild((ISequenceInstance) instance, childInstance);
+            }
+            else if (instance instanceof ISelectionInstance) {
+                if (((ISelectionInstance) instance).getChild() == null) {
+                    taskBuilder.setChild((ISelectionInstance) instance, childInstance);
+                }
+                else {
+                    throw new IllegalArgumentException("can not add several children to one " +
+                                                       "selection instance");
+                }
+            }
+            else if (instance instanceof IIterationInstance) {
+                taskBuilder.addChild((IIterationInstance) instance, childInstance);
+            }
+            else if (instance instanceof IOptionalInstance) {
+                if (((IOptionalInstance) instance).getChild() == null) {
+                    taskBuilder.setChild((IOptionalInstance) instance, childInstance);
+                }
+                else {
+                    throw new IllegalArgumentException("can not add several children to one " +
+                                                       "optional instance");
+                }
+            }
+        }
+
+        // validate the instance
+        try {
+            new TaskTreeValidator().validate(instance);
+        }
+        catch (java.lang.AssertionError e) {
+            throw new IllegalArgumentException(e.getMessage(), e);
+        }
+        
+        return instance;
+    }
+
+    /**
+     * <p>
+     * TODO: comment
+     * </p>
+     *
+     * @param id
+     * @param type
+     * @param children
+     * @return
+     */
+    private ITask getCreateTask(String id, String type, List<ITaskInstance> children) {
         ITask task = tasks.get(id);
         
@@ -179,76 +263,61 @@
             }
             else {
-            	task = createUserInteractionTaskInstance(matcher).getTask();
+                task = taskFactory.createNewEventTask(type + " --> " + id);
             }  
             tasks.put(id, task);
-        }
-        
-        ITaskInstance instance;
-        
-        if (task instanceof ISequence) {
-            instance = taskFactory.createNewTaskInstance((ISequence) task);
-        }
-        else if (task instanceof ISelection) {
-            instance = taskFactory.createNewTaskInstance((ISelection) task);
-        }
-        else if (task instanceof IIteration) {
-            instance = taskFactory.createNewTaskInstance((IIteration) task);
-        }
-        else if (task instanceof IOptional) {
-            instance = taskFactory.createNewTaskInstance((IOptional) task);
-        }
-        else {
-            instance = taskFactory.createNewTaskInstance
-                 ((IEventTask) task,
-                  ((IEventTaskInstance) task.getInstances().iterator().next()).getEvent());
-        }  
-        
-        while (taskMatcher.find() && !"}".equals(taskMatcher.group(0))) {
-            ITaskInstance childInstance = parseTaskInstance(taskMatcher);
-            
-            if (task instanceof ISequence) {
-                taskBuilder.addChild((ISequence) task, childInstance.getTask());
-            }
-            else if (task instanceof ISelection) {
-                taskBuilder.addChild((ISelection) task, childInstance.getTask());
-            }
-            else if (task instanceof IIteration) {
-                if (((IIteration) task).getMarkedTask() == null) {
-                    taskBuilder.setMarkedTask((IIteration) task, childInstance.getTask());
-                }
-                else if (!((IIteration) task).getMarkedTask().equals(childInstance.getTask())) {
-                    throw new IllegalArgumentException
-                        ("can not add more than one child to an iteration");
-                }
-            }
-            else if (task instanceof IOptional) {
-                if (((IOptional) task).getMarkedTask() == null) {
-                    taskBuilder.setMarkedTask((IOptional) task, childInstance.getTask());
-                }
-                else if (!((IOptional) task).getMarkedTask().equals(childInstance.getTask())) {
-                    throw new IllegalArgumentException
-                        ("can not add more than one child to an optional");
-                }
-            }
-            else {
-                throw new IllegalArgumentException("can not add children to something that is no " +
-                                                   "sequence, selection, iteration, or optional");
-            }
-            
-            if (instance instanceof ISequenceInstance) {
-                taskBuilder.addChild((ISequenceInstance) instance, childInstance);
-            }
-            else if (instance instanceof ISelectionInstance) {
-                taskBuilder.setChild((ISelectionInstance) instance, childInstance);
-            }
-            else if (instance instanceof IIterationInstance) {
-                taskBuilder.addChild((IIterationInstance) instance, childInstance);
-            }
-            else if (instance instanceof IOptionalInstance) {
-                taskBuilder.setChild((IOptionalInstance) instance, childInstance);
-            }
-        }
-
-        return instance;
+
+            for (ITaskInstance childInstance : children) {
+                if (task instanceof ISequence) {
+                    taskBuilder.addChild((ISequence) task, childInstance.getTask());
+                }
+                else if (task instanceof ISelection) {
+                    taskBuilder.addChild((ISelection) task, childInstance.getTask());
+                }
+                else if (task instanceof IIteration) {
+                    if (((IIteration) task).getMarkedTask() == null) {
+                        taskBuilder.setMarkedTask((IIteration) task, childInstance.getTask());
+                    }
+                    else if (!((IIteration) task).getMarkedTask().equals(childInstance.getTask())) {
+                        throw new IllegalArgumentException
+                            ("can not add more than one child to an iteration");
+                    }
+                }
+                else if (task instanceof IOptional) {
+                    if (((IOptional) task).getMarkedTask() == null) {
+                        taskBuilder.setMarkedTask((IOptional) task, childInstance.getTask());
+                    }
+                    else if (!((IOptional) task).getMarkedTask().equals(childInstance.getTask())) {
+                        throw new IllegalArgumentException
+                            ("can not add more than one child to an optional");
+                    }
+                }
+                else {
+                    throw new IllegalArgumentException("can not add children to something that " +
+                                                       "is no sequence, selection, iteration, or " +
+                                                       "optional");
+                }
+            }
+        }
+        else if ("Selection".equals(type)) {
+            // update the selection with further alternatives, if specified by the current
+            // child instance
+            if (children.size() == 1) {
+                ITask newChildTask = children.get(0).getTask();
+                
+                boolean found = false;
+                for (ITask childTask : ((ISelection) task).getChildren()) {
+                    if (childTask.equals(newChildTask)) {
+                        found = true;
+                        break;
+                    }
+                }
+                
+                if (!found) {
+                    taskBuilder.addChild((ISelection) task, newChildTask);
+                }
+            }
+        }
+
+        return task;
     }
 
@@ -260,16 +329,13 @@
      * @return
      */
-    private ITaskInstance createUserInteractionTaskInstance(Matcher matcher) {
-        String evenType = matcher.group(1);
-        String id = matcher.group(2);
-        IEventTarget eventTarget = targets.get(id);
+    private Event createUserInteractionEvent(String type, String targetId, String furtherInfo) {
+        IEventTarget eventTarget = targets.get(targetId);
         if (eventTarget == null) {
-            eventTarget = determineTarget(evenType, id, matcher.group(4));
-            targets.put(id, eventTarget);
-        }
-        IEventType eventType = determineType(evenType, matcher.group(4));
-        IEventTask task = taskFactory.createNewEventTask(eventType + " --> " + eventTarget);
-        
-        return taskFactory.createNewTaskInstance(task, new Event(eventType, eventTarget));
+            eventTarget = determineTarget(type, targetId, furtherInfo);
+            targets.put(targetId, eventTarget);
+        }
+        IEventType eventType = determineType(type, furtherInfo);
+        
+        return new Event(eventType, eventTarget);
     }
 
Index: trunk/autoquest-test-utils/src/test/java/de/ugoe/cs/autoquest/tasktrees/TaskTreeDecoderTest.java
===================================================================
--- trunk/autoquest-test-utils/src/test/java/de/ugoe/cs/autoquest/tasktrees/TaskTreeDecoderTest.java	(revision 1325)
+++ trunk/autoquest-test-utils/src/test/java/de/ugoe/cs/autoquest/tasktrees/TaskTreeDecoderTest.java	(revision 1325)
@@ -0,0 +1,911 @@
+//   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;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTaskInstance;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IIteration;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IIterationInstance;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IOptional;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IOptionalInstance;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelection;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelectionInstance;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequenceInstance;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceList;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IUserSession;
+import de.ugoe.cs.autoquest.tasktrees.treeimpl.TaskBuilder;
+import de.ugoe.cs.autoquest.tasktrees.treeimpl.TaskFactory;
+
+/**
+ * @author Patrick Harms
+ */
+public class TaskTreeDecoderTest {
+
+    /**
+     *
+     */
+    @Test
+    public void test_UserSession_01() {
+        String blub =
+            "UserSession {" +
+            "}";
+
+        TaskTreeDecoder decoder = new TaskTreeDecoder(new TaskFactory(), new TaskBuilder());
+        
+        ITaskInstanceList list = decoder.decode(blub);
+        
+        assertTrue(list instanceof IUserSession);
+        assertEquals(0, list.size());
+            
+        new TaskTreeValidator().validate(list);
+    }
+
+    /**
+     *
+     */
+    @Test
+    public void test_UserSession_02() {
+        String blub =
+            "UserSession {" +
+            "  MouseClick c1 { }" +
+            "}";
+
+        TaskTreeDecoder decoder = new TaskTreeDecoder(new TaskFactory(), new TaskBuilder());
+        
+        ITaskInstanceList list = decoder.decode(blub);
+        
+        assertTrue(list instanceof IUserSession);
+        assertEquals(1, list.size());
+        
+        new TaskTreeValidator().validate(list);
+    }
+
+    /**
+     *
+     */
+    @Test
+    public void test_UserSession_03() {
+        String blub =
+            "UserSession {" +
+            "  MouseClick c1 { }" +
+            "  MouseClick c2 { }" +
+            "  MouseClick c3 { }" +
+            "  MouseClick c4 { }" +
+            "  MouseClick c5 { }" +
+            "  MouseClick c6 { }" +
+            "  MouseClick c7 { }" +
+            "}";
+
+        TaskTreeDecoder decoder = new TaskTreeDecoder(new TaskFactory(), new TaskBuilder());
+        
+        ITaskInstanceList list = decoder.decode(blub);
+        
+        assertTrue(list instanceof IUserSession);
+        assertEquals(7, list.size());
+            
+        new TaskTreeValidator().validate(list);
+    }
+
+    /**
+     *
+     */
+    @Test
+    public void test_TaskInstances_01() {
+        String blub =
+            "TaskInstances {" +
+            "}";
+
+        TaskTreeDecoder decoder = new TaskTreeDecoder(new TaskFactory(), new TaskBuilder());
+        
+        ITaskInstanceList list = decoder.decode(blub);
+        
+        assertFalse(list instanceof IUserSession);
+        assertEquals(0, list.size());
+            
+        new TaskTreeValidator().validate(list);
+    }
+
+    /**
+     *
+     */
+    @Test
+    public void test_TaskInstances_02() {
+        String blub =
+            "TaskInstances {" +
+            "  MouseClick c1 { }" +
+            "}";
+
+        TaskTreeDecoder decoder = new TaskTreeDecoder(new TaskFactory(), new TaskBuilder());
+        
+        ITaskInstanceList list = decoder.decode(blub);
+        
+        assertFalse(list instanceof IUserSession);
+        assertEquals(1, list.size());
+        
+        new TaskTreeValidator().validate(list);
+    }
+
+    /**
+     *
+     */
+    @Test
+    public void test_TaskInstances_03() {
+        String blub =
+            "TaskInstances {" +
+            "  MouseClick c1 { }" +
+            "  MouseClick c2 { }" +
+            "  MouseClick c3 { }" +
+            "  MouseClick c4 { }" +
+            "  MouseClick c5 { }" +
+            "  MouseClick c6 { }" +
+            "  MouseClick c7 { }" +
+            "}";
+
+        TaskTreeDecoder decoder = new TaskTreeDecoder(new TaskFactory(), new TaskBuilder());
+        
+        ITaskInstanceList list = decoder.decode(blub);
+        
+        assertFalse(list instanceof IUserSession);
+        assertEquals(7, list.size());
+            
+        new TaskTreeValidator().validate(list);
+    }
+
+    /**
+     *
+     */
+    @Test
+    public void test_MouseClick_01() {
+        String blub =
+            "UserSession {" +
+            "  MouseClick c1 { }" +
+            "}";
+
+        TaskTreeDecoder decoder = new TaskTreeDecoder(new TaskFactory(), new TaskBuilder());
+        
+        ITaskInstanceList list = decoder.decode(blub);
+        
+        assertTrue(list.get(0) instanceof IEventTaskInstance);
+        assertTrue(list.get(0).getTask() instanceof IEventTask);
+        
+        new TaskTreeValidator().validate(list);
+    }
+
+    /**
+     *
+     */
+    @Test
+    public void test_MouseClick_02() {
+        String blub =
+            "UserSession {" +
+            "  MouseClick c1 { }" +
+            "  MouseClick c2 { }" +
+            "}";
+
+        TaskTreeDecoder decoder = new TaskTreeDecoder(new TaskFactory(), new TaskBuilder());
+        
+        ITaskInstanceList list = decoder.decode(blub);
+        
+        assertTrue(list.get(0) instanceof IEventTaskInstance);
+        assertTrue(list.get(0).getTask() instanceof IEventTask);
+        assertTrue(list.get(1) instanceof IEventTaskInstance);
+        assertTrue(list.get(1).getTask() instanceof IEventTask);
+        
+        assertFalse(list.get(0).equals(list.get(1)));
+        assertFalse(list.get(0).getTask().equals(list.get(1).getTask()));
+        
+        new TaskTreeValidator().validate(list);
+    }
+
+    /**
+     *
+     */
+    @Test
+    public void test_MouseClick_03() {
+        String blub =
+            "UserSession {" +
+            "  MouseClick c1 { }" +
+            "  MouseClick c1 { }" +
+            "}";
+
+        TaskTreeDecoder decoder = new TaskTreeDecoder(new TaskFactory(), new TaskBuilder());
+        
+        ITaskInstanceList list = decoder.decode(blub);
+        
+        assertTrue(list.get(0) instanceof IEventTaskInstance);
+        assertTrue(list.get(0).getTask() instanceof IEventTask);
+        assertTrue(list.get(1) instanceof IEventTaskInstance);
+        assertTrue(list.get(1).getTask() instanceof IEventTask);
+        
+        assertFalse(list.get(0).equals(list.get(1)));
+        assertTrue(list.get(0).getTask().equals(list.get(1).getTask()));
+        
+        new TaskTreeValidator().validate(list);
+    }
+
+    /**
+     *
+     */
+    @Test
+    public void test_Sequence_01() {
+        String blub =
+            "UserSession {" +
+            "  Sequence s1 { }" +
+            "}";
+
+        TaskTreeDecoder decoder = new TaskTreeDecoder(new TaskFactory(), new TaskBuilder());
+        
+        ITaskInstanceList list = decoder.decode(blub);
+        
+        assertTrue(list.get(0) instanceof ISequenceInstance);
+        assertEquals(0, ((ISequenceInstance) list.get(0)).size());
+        
+        assertTrue(list.get(0).getTask() instanceof ISequence);
+        assertEquals(0, ((ISequence) list.get(0).getTask()).getChildren().size());
+
+        new TaskTreeValidator().validate(list);
+    }
+
+    /**
+     *
+     */
+    @Test
+    public void test_Sequence_02() {
+        String blub =
+            "UserSession {" +
+            "  Sequence seq1 {" +
+            "    MouseClick c1 { }" +
+            "  }" +
+            "}";
+
+        TaskTreeDecoder decoder = new TaskTreeDecoder(new TaskFactory(), new TaskBuilder());
+            
+        ITaskInstanceList list = decoder.decode(blub);
+            
+        assertTrue(list.get(0) instanceof ISequenceInstance);
+        assertEquals(1, ((ISequenceInstance) list.get(0)).size());
+        assertTrue(((ISequenceInstance) list.get(0)).get(0) instanceof IEventTaskInstance);
+            
+        assertTrue(list.get(0).getTask() instanceof ISequence);
+        assertEquals(1, ((ISequence) list.get(0).getTask()).getChildren().size());
+        assertTrue(((ISequence) list.get(0).getTask()).getChildren().get(0) instanceof IEventTask);
+        
+        assertEquals(((ISequenceInstance) list.get(0)).get(0).getTask(),
+                     ((ISequence) list.get(0).getTask()).getChildren().get(0));
+
+        new TaskTreeValidator().validate(list);
+    }
+
+    /**
+     *
+     */
+    @Test
+    public void test_Sequence_03() {
+        String blub =
+            "UserSession {" +
+            "  Sequence seq1 {" +
+            "    MouseClick c1 { }" +
+            "    MouseClick c2 { }" +
+            "  }" +
+            "}";
+
+        TaskTreeDecoder decoder = new TaskTreeDecoder(new TaskFactory(), new TaskBuilder());
+
+        ITaskInstanceList list = decoder.decode(blub);
+
+        assertTrue(list.get(0) instanceof ISequenceInstance);
+        assertEquals(2, ((ISequenceInstance) list.get(0)).size());
+        assertTrue(((ISequenceInstance) list.get(0)).get(0) instanceof IEventTaskInstance);
+        assertTrue(((ISequenceInstance) list.get(0)).get(1) instanceof IEventTaskInstance);
+
+        assertTrue(list.get(0).getTask() instanceof ISequence);
+        assertEquals(2, ((ISequence) list.get(0).getTask()).getChildren().size());
+        assertTrue(((ISequence) list.get(0).getTask()).getChildren().get(0) instanceof IEventTask);
+        assertTrue(((ISequence) list.get(0).getTask()).getChildren().get(1) instanceof IEventTask);
+
+        assertEquals(((ISequenceInstance) list.get(0)).get(0).getTask(),
+                     ((ISequence) list.get(0).getTask()).getChildren().get(0));
+        assertEquals(((ISequenceInstance) list.get(0)).get(1).getTask(),
+                     ((ISequence) list.get(0).getTask()).getChildren().get(1));
+
+        assertFalse(((ISequence) list.get(0).getTask()).getChildren().get(0).equals
+                         (((ISequence) list.get(0).getTask()).getChildren().get(1)));
+        
+        new TaskTreeValidator().validate(list);
+    }
+
+    /**
+     *
+     */
+    @Test
+    public void test_Sequence_04() {
+        String blub =
+            "UserSession {" +
+            "  Sequence seq1 {" +
+            "    MouseClick c1 { }" +
+            "    MouseClick c2 { }" +
+            "  }" +
+            "  Sequence seq1 {" +
+            "    MouseClick c1 { }" +
+            "    MouseClick c2 { }" +
+            "  }" +
+            "}";
+
+        TaskTreeDecoder decoder = new TaskTreeDecoder(new TaskFactory(), new TaskBuilder());
+
+        ITaskInstanceList list = decoder.decode(blub);
+
+        // ensure, sequences are identical
+        assertTrue(list.get(0) instanceof ISequenceInstance);
+        assertTrue(list.get(1) instanceof ISequenceInstance);
+        
+        assertFalse(list.get(0).equals(list.get(1)));
+
+        assertTrue(list.get(0).getTask() instanceof ISequence);
+        assertTrue(list.get(1).getTask() instanceof ISequence);
+        
+        assertTrue(list.get(0).getTask().equals(list.get(1).getTask()));
+
+        // ensure that sequence itself is correct
+        assertEquals(2, ((ISequenceInstance) list.get(0)).size());
+        assertTrue(((ISequenceInstance) list.get(0)).get(0) instanceof IEventTaskInstance);
+        assertTrue(((ISequenceInstance) list.get(0)).get(1) instanceof IEventTaskInstance);
+
+        assertEquals(2, ((ISequenceInstance) list.get(1)).size());
+        assertTrue(((ISequenceInstance) list.get(1)).get(0) instanceof IEventTaskInstance);
+        assertTrue(((ISequenceInstance) list.get(1)).get(1) instanceof IEventTaskInstance);
+
+        assertEquals(2, ((ISequence) list.get(0).getTask()).getChildren().size());
+        assertTrue(((ISequence) list.get(0).getTask()).getChildren().get(0) instanceof IEventTask);
+        assertTrue(((ISequence) list.get(0).getTask()).getChildren().get(1) instanceof IEventTask);
+
+        assertEquals(((ISequenceInstance) list.get(0)).get(0).getTask(),
+                     ((ISequence) list.get(0).getTask()).getChildren().get(0));
+        assertEquals(((ISequenceInstance) list.get(0)).get(1).getTask(),
+                     ((ISequence) list.get(0).getTask()).getChildren().get(1));
+
+        assertEquals(((ISequenceInstance) list.get(1)).get(0).getTask(),
+                     ((ISequence) list.get(0).getTask()).getChildren().get(0));
+        assertEquals(((ISequenceInstance) list.get(1)).get(1).getTask(),
+                     ((ISequence) list.get(0).getTask()).getChildren().get(1));
+
+        assertFalse(((ISequence) list.get(0).getTask()).getChildren().get(0).equals
+                         (((ISequence) list.get(0).getTask()).getChildren().get(1)));
+        
+        
+        new TaskTreeValidator().validate(list);
+    }
+
+    /**
+     *
+     */
+    @Test(expected=java.lang.IllegalArgumentException.class)
+    public void test_Sequence_05() {
+        String blub =
+            "UserSession {" +
+            "  Sequence seq1 {" +
+            "    MouseClick c1 { }" +
+            "  }" +
+            "  Sequence seq1 {" +
+            "    MouseClick c2 { }" +
+            "  }" +
+            "}";
+
+        TaskTreeDecoder decoder = new TaskTreeDecoder(new TaskFactory(), new TaskBuilder());
+
+        decoder.decode(blub);
+    }
+
+    /**
+     *
+     */
+    @Test(expected=java.lang.IllegalArgumentException.class)
+    public void test_Selection_01() {
+        String blub =
+            "UserSession {" +
+            "  Selection sel1 { }" +
+            "}";
+
+        TaskTreeDecoder decoder = new TaskTreeDecoder(new TaskFactory(), new TaskBuilder());
+        
+        decoder.decode(blub);
+    }
+
+    /**
+     *
+     */
+    @Test
+    public void test_Selection_02() {
+        String blub =
+            "UserSession {" +
+            "  Selection sel1 {" +
+            "    MouseClick c1 { }" +
+            "  }" +
+            "}";
+
+        TaskTreeDecoder decoder = new TaskTreeDecoder(new TaskFactory(), new TaskBuilder());
+            
+        ITaskInstanceList list = decoder.decode(blub);
+            
+        assertTrue(list.get(0) instanceof ISelectionInstance);
+        assertNotNull(((ISelectionInstance) list.get(0)).getChild());
+        assertTrue(((ISelectionInstance) list.get(0)).getChild() instanceof IEventTaskInstance);
+            
+        assertTrue(list.get(0).getTask() instanceof ISelection);
+        assertEquals(1, ((ISelection) list.get(0).getTask()).getChildren().size());
+        assertTrue(((ISelection) list.get(0).getTask()).getChildren().get(0) instanceof IEventTask);
+        
+        assertEquals(((ISelectionInstance) list.get(0)).getChild().getTask(),
+                     ((ISelection) list.get(0).getTask()).getChildren().get(0));
+
+        new TaskTreeValidator().validate(list);
+    }
+
+    /**
+     *
+     */
+    @Test
+    public void test_Selection_03() {
+        String blub =
+            "UserSession {" +
+            "  Selection sel1 {" +
+            "    MouseClick c1 { }" +
+            "  }" +
+            "  Selection sel1 {" +
+            "    MouseClick c1 { }" +
+            "  }" +
+            "}";
+
+        TaskTreeDecoder decoder = new TaskTreeDecoder(new TaskFactory(), new TaskBuilder());
+
+        ITaskInstanceList list = decoder.decode(blub);
+
+        assertTrue(list.get(0) instanceof ISelectionInstance);
+        assertNotNull(((ISelectionInstance) list.get(0)).getChild());
+        assertTrue(((ISelectionInstance) list.get(0)).getChild() instanceof IEventTaskInstance);
+
+        assertTrue(list.get(0).getTask() instanceof ISelection);
+        assertEquals(1, ((ISelection) list.get(0).getTask()).getChildren().size());
+        assertTrue(((ISelection) list.get(0).getTask()).getChildren().get(0) instanceof IEventTask);
+
+        assertTrue(list.get(1) instanceof ISelectionInstance);
+        assertNotNull(((ISelectionInstance) list.get(1)).getChild());
+        assertTrue(((ISelectionInstance) list.get(1)).getChild() instanceof IEventTaskInstance);
+
+        assertTrue(list.get(1).getTask() instanceof ISelection);
+        assertEquals(1, ((ISelection) list.get(1).getTask()).getChildren().size());
+        assertTrue(((ISelection) list.get(1).getTask()).getChildren().get(0) instanceof IEventTask);
+
+        assertFalse(list.get(0).equals(list.get(1)));
+        assertTrue(list.get(0).getTask().equals(list.get(1).getTask()));
+        
+        assertFalse(((ISelectionInstance) list.get(0)).getChild().equals
+                        (((ISelectionInstance) list.get(1)).getChild()));
+        assertTrue(((ISelectionInstance) list.get(0)).getChild().getTask().equals
+                       (((ISelectionInstance) list.get(1)).getChild().getTask()));
+        
+        assertTrue(((ISelection) list.get(0).getTask()).getChildren().get(0).equals
+                       (((ISelectionInstance) list.get(0)).getChild().getTask()));
+        assertTrue(((ISelection) list.get(0).getTask()).getChildren().get(0).equals
+                       (((ISelectionInstance) list.get(1)).getChild().getTask()));
+
+        new TaskTreeValidator().validate(list);
+    }
+
+    /**
+     *
+     */
+    @Test
+    public void test_Selection_04() {
+        String blub =
+            "UserSession {" +
+            "  Selection sel1 {" +
+            "    MouseClick c1 { }" +
+            "  }" +
+            "  Selection sel1 {" +
+            "    MouseClick c2 { }" +
+            "  }" +
+            "}";
+
+        TaskTreeDecoder decoder = new TaskTreeDecoder(new TaskFactory(), new TaskBuilder());
+
+        ITaskInstanceList list = decoder.decode(blub);
+
+        assertTrue(list.get(0) instanceof ISelectionInstance);
+        assertNotNull(((ISelectionInstance) list.get(0)).getChild());
+        assertTrue(((ISelectionInstance) list.get(0)).getChild() instanceof IEventTaskInstance);
+
+        assertTrue(list.get(0).getTask() instanceof ISelection);
+        assertEquals(2, ((ISelection) list.get(0).getTask()).getChildren().size());
+        assertTrue(((ISelection) list.get(0).getTask()).getChildren().get(0) instanceof IEventTask);
+        assertTrue(((ISelection) list.get(0).getTask()).getChildren().get(1) instanceof IEventTask);
+
+        assertTrue(list.get(1) instanceof ISelectionInstance);
+        assertNotNull(((ISelectionInstance) list.get(1)).getChild());
+        assertTrue(((ISelectionInstance) list.get(1)).getChild() instanceof IEventTaskInstance);
+
+        assertTrue(list.get(1).getTask() instanceof ISelection);
+        assertEquals(2, ((ISelection) list.get(1).getTask()).getChildren().size());
+        assertTrue(((ISelection) list.get(1).getTask()).getChildren().get(0) instanceof IEventTask);
+        assertTrue(((ISelection) list.get(1).getTask()).getChildren().get(1) instanceof IEventTask);
+
+        assertFalse(list.get(0).equals(list.get(1)));
+        assertTrue(list.get(0).getTask().equals(list.get(1).getTask()));
+
+        assertFalse(((ISelectionInstance) list.get(0)).getChild().equals
+                        (((ISelectionInstance) list.get(1)).getChild()));
+        assertFalse(((ISelectionInstance) list.get(0)).getChild().getTask().equals
+                        (((ISelectionInstance) list.get(1)).getChild().getTask()));
+
+        assertTrue(((ISelection) list.get(0).getTask()).getChildren().get(0).equals
+                       (((ISelectionInstance) list.get(0)).getChild().getTask()));
+        assertTrue(((ISelection) list.get(0).getTask()).getChildren().get(1).equals
+                       (((ISelectionInstance) list.get(1)).getChild().getTask()));
+
+        new TaskTreeValidator().validate(list);
+    }
+
+    /**
+     *
+     */
+    @Test(expected=java.lang.IllegalArgumentException.class)
+    public void test_Selection_05() {
+        String blub =
+            "UserSession {" +
+            "  Selection sel1 {" +
+            "    MouseClick c1 { }" +
+            "    MouseClick c2 { }" +
+            "  }" +
+            "}";
+
+        TaskTreeDecoder decoder = new TaskTreeDecoder(new TaskFactory(), new TaskBuilder());
+
+        decoder.decode(blub);
+    }
+
+    /**
+     *
+     */
+    @Test(expected=java.lang.IllegalArgumentException.class)
+    public void test_Iteration_01() {
+        String blub =
+            "UserSession {" +
+            "  Iteration it1 { }" +
+            "}";
+
+        TaskTreeDecoder decoder = new TaskTreeDecoder(new TaskFactory(), new TaskBuilder());
+        
+        decoder.decode(blub);
+    }
+
+    /**
+     *
+     */
+    @Test
+    public void test_Iteration_02() {
+        String blub =
+            "UserSession {" +
+            "  Iteration it1 {" +
+            "    MouseClick c1 { }" +
+            "  }" +
+            "}";
+
+        TaskTreeDecoder decoder = new TaskTreeDecoder(new TaskFactory(), new TaskBuilder());
+            
+        ITaskInstanceList list = decoder.decode(blub);
+            
+        assertTrue(list.get(0) instanceof IIterationInstance);
+        assertEquals(1, ((IIterationInstance) list.get(0)).size());
+        assertTrue(((IIterationInstance) list.get(0)).get(0) instanceof IEventTaskInstance);
+            
+        assertTrue(list.get(0).getTask() instanceof IIteration);
+        assertNotNull(((IIteration) list.get(0).getTask()).getMarkedTask());
+        assertTrue(((IIteration) list.get(0).getTask()).getMarkedTask() instanceof IEventTask);
+        
+        assertEquals(((IIterationInstance) list.get(0)).get(0).getTask(),
+                     ((IIteration) list.get(0).getTask()).getMarkedTask());
+
+        new TaskTreeValidator().validate(list);
+    }
+
+    /**
+     *
+     */
+    @Test
+    public void test_Iteration_03() {
+        String blub =
+            "UserSession {" +
+            "  Iteration it1 {" +
+            "    MouseClick c1 { }" +
+            "    MouseClick c1 { }" +
+            "    MouseClick c1 { }" +
+            "  }" +
+            "}"; 
+
+        TaskTreeDecoder decoder = new TaskTreeDecoder(new TaskFactory(), new TaskBuilder());
+           
+        ITaskInstanceList list = decoder.decode(blub);
+           
+        assertTrue(list.get(0) instanceof IIterationInstance);
+        assertEquals(3, ((IIterationInstance) list.get(0)).size());
+        assertTrue(((IIterationInstance) list.get(0)).get(0) instanceof IEventTaskInstance);
+        assertTrue(((IIterationInstance) list.get(0)).get(1) instanceof IEventTaskInstance);
+        assertTrue(((IIterationInstance) list.get(0)).get(2) instanceof IEventTaskInstance);
+           
+        assertTrue(list.get(0).getTask() instanceof IIteration);
+        assertNotNull(((IIteration) list.get(0).getTask()).getMarkedTask());
+        assertTrue(((IIteration) list.get(0).getTask()).getMarkedTask() instanceof IEventTask);
+       
+        assertEquals(((IIterationInstance) list.get(0)).get(0).getTask(),
+                     ((IIteration) list.get(0).getTask()).getMarkedTask());
+        assertEquals(((IIterationInstance) list.get(0)).get(1).getTask(),
+                     ((IIteration) list.get(0).getTask()).getMarkedTask());
+        assertEquals(((IIterationInstance) list.get(0)).get(2).getTask(),
+                     ((IIteration) list.get(0).getTask()).getMarkedTask());
+
+        new TaskTreeValidator().validate(list);
+    }
+
+    /**
+     *
+     */
+    @Test
+    public void test_Iteration_04() {
+        String blub =
+            "UserSession {" +
+            "  Iteration it1 {" +
+            "    MouseClick c1 { }" +
+            "    MouseClick c1 { }" +
+            "    MouseClick c1 { }" +
+            "  }" +
+            "  Iteration it1 {" +
+            "    MouseClick c1 { }" +
+            "  }" +
+            "}";
+
+        TaskTreeDecoder decoder = new TaskTreeDecoder(new TaskFactory(), new TaskBuilder());
+
+        ITaskInstanceList list = decoder.decode(blub);
+
+        assertTrue(list.get(0) instanceof IIterationInstance);
+        assertEquals(3, ((IIterationInstance) list.get(0)).size());
+        assertTrue(((IIterationInstance) list.get(0)).get(0) instanceof IEventTaskInstance);
+        assertTrue(((IIterationInstance) list.get(0)).get(1) instanceof IEventTaskInstance);
+        assertTrue(((IIterationInstance) list.get(0)).get(2) instanceof IEventTaskInstance);
+
+        assertTrue(list.get(0).getTask() instanceof IIteration);
+        assertNotNull(((IIteration) list.get(0).getTask()).getMarkedTask());
+        assertTrue(((IIteration) list.get(0).getTask()).getMarkedTask() instanceof IEventTask);
+
+        assertTrue(list.get(1) instanceof IIterationInstance);
+        assertEquals(1, ((IIterationInstance) list.get(1)).size());
+        assertTrue(((IIterationInstance) list.get(1)).get(0) instanceof IEventTaskInstance);
+
+        assertTrue(list.get(1).getTask() instanceof IIteration);
+        assertNotNull(((IIteration) list.get(1).getTask()).getMarkedTask());
+        assertTrue(((IIteration) list.get(1).getTask()).getMarkedTask() instanceof IEventTask);
+
+        assertFalse(list.get(0).equals(list.get(1)));
+        assertTrue(list.get(0).getTask().equals(list.get(1).getTask()));
+        
+        assertFalse(((IIterationInstance) list.get(0)).get(0).equals
+                        (((IIterationInstance) list.get(1)).get(0)));
+        assertTrue(((IIterationInstance) list.get(0)).get(0).getTask().equals
+                   (((IIterationInstance) list.get(1)).get(0).getTask()));
+    
+        assertFalse(((IIterationInstance) list.get(0)).get(1).equals
+                        (((IIterationInstance) list.get(1)).get(0)));
+        assertTrue(((IIterationInstance) list.get(0)).get(1).getTask().equals
+                   (((IIterationInstance) list.get(1)).get(0).getTask()));
+    
+        assertFalse(((IIterationInstance) list.get(0)).get(2).equals
+                        (((IIterationInstance) list.get(1)).get(0)));
+        assertTrue(((IIterationInstance) list.get(0)).get(2).getTask().equals
+                       (((IIterationInstance) list.get(1)).get(0).getTask()));
+        
+        new TaskTreeValidator().validate(list);
+    }
+
+
+    /**
+     *
+     */
+    @Test(expected=java.lang.IllegalArgumentException.class)
+    public void test_Iteration_05() {
+        String blub =
+            "UserSession {" +
+            "  Iteration it1 {" +
+            "    MouseClick c1 { }" +
+            "  }" +
+            "  Iteration it1 {" +
+            "    MouseClick c2 { }" +
+            "  }" +
+            "}";
+
+        TaskTreeDecoder decoder = new TaskTreeDecoder(new TaskFactory(), new TaskBuilder());
+
+        decoder.decode(blub);
+    }
+
+    /**
+     *
+     */
+    @Test(expected=java.lang.IllegalArgumentException.class)
+    public void test_Iteration_06() {
+        String blub =
+            "UserSession {" +
+            "  Iteration it1 {" +
+            "    MouseClick c1 { }" +
+            "    MouseClick c2 { }" +
+            "  }" +
+            "}";
+
+        TaskTreeDecoder decoder = new TaskTreeDecoder(new TaskFactory(), new TaskBuilder());
+
+        decoder.decode(blub);
+    }
+
+    /**
+     *
+     */
+    @Test(expected=java.lang.IllegalArgumentException.class)
+    public void test_Optional_01() {
+        String blub =
+            "UserSession {" +
+            "  Optional op1 { }" +
+            "}";
+
+        TaskTreeDecoder decoder = new TaskTreeDecoder(new TaskFactory(), new TaskBuilder());
+        
+        decoder.decode(blub);
+    }
+
+    /**
+     *
+     */
+    @Test
+    public void test_Optional_02() {
+        String blub =
+            "UserSession {" +
+            "  Optional op1 {" +
+            "    MouseClick c1 { }" +
+            "  }" +
+            "}";
+
+        TaskTreeDecoder decoder = new TaskTreeDecoder(new TaskFactory(), new TaskBuilder());
+            
+        ITaskInstanceList list = decoder.decode(blub);
+            
+        assertTrue(list.get(0) instanceof IOptionalInstance);
+        assertNotNull(((IOptionalInstance) list.get(0)).getChild());
+        assertTrue(((IOptionalInstance) list.get(0)).getChild() instanceof IEventTaskInstance);
+            
+        assertTrue(list.get(0).getTask() instanceof IOptional);
+        assertNotNull(((IOptional) list.get(0).getTask()).getMarkedTask());
+        assertTrue(((IOptional) list.get(0).getTask()).getMarkedTask() instanceof IEventTask);
+        
+        assertEquals(((IOptionalInstance) list.get(0)).getChild().getTask(),
+                     ((IOptional) list.get(0).getTask()).getMarkedTask());
+
+        new TaskTreeValidator().validate(list);
+    }
+
+    /**
+     *
+     */
+    @Test
+    public void test_Optional_03() {
+        String blub =
+            "UserSession {" +
+            "  Optional op1 {" +
+            "    MouseClick c1 { }" +
+            "  }" +
+            "  Optional op1 {" +
+            "    MouseClick c1 { }" +
+            "  }" +
+            "}";
+
+        TaskTreeDecoder decoder = new TaskTreeDecoder(new TaskFactory(), new TaskBuilder());
+
+        ITaskInstanceList list = decoder.decode(blub);
+
+        assertTrue(list.get(0) instanceof IOptionalInstance);
+        assertNotNull(((IOptionalInstance) list.get(0)).getChild());
+        assertTrue(((IOptionalInstance) list.get(0)).getChild() instanceof IEventTaskInstance);
+
+        assertTrue(list.get(0).getTask() instanceof IOptional);
+        assertNotNull(((IOptional) list.get(0).getTask()).getMarkedTask());
+        assertTrue(((IOptional) list.get(0).getTask()).getMarkedTask() instanceof IEventTask);
+
+        assertTrue(list.get(1) instanceof IOptionalInstance);
+        assertNotNull(((IOptionalInstance) list.get(1)).getChild());
+        assertTrue(((IOptionalInstance) list.get(1)).getChild() instanceof IEventTaskInstance);
+
+        assertTrue(list.get(1).getTask() instanceof IOptional);
+        assertNotNull(((IOptional) list.get(1).getTask()).getMarkedTask());
+        assertTrue(((IOptional) list.get(1).getTask()).getMarkedTask() instanceof IEventTask);
+
+        assertFalse(list.get(0).equals(list.get(1)));
+        assertTrue(list.get(0).getTask().equals(list.get(1).getTask()));
+        
+        assertFalse(((IOptionalInstance) list.get(0)).getChild().equals
+                        (((IOptionalInstance) list.get(1)).getChild()));
+        assertTrue(((IOptionalInstance) list.get(0)).getChild().getTask().equals
+                   (((IOptionalInstance) list.get(1)).getChild().getTask()));
+        
+        new TaskTreeValidator().validate(list);
+    }
+
+    /**
+     *
+     */
+    @Test(expected=java.lang.IllegalArgumentException.class)
+    public void test_Optional_04() {
+        String blub =
+            "UserSession {" +
+            "  Optional op1 {" +
+            "    MouseClick c1 { }" +
+            "    MouseClick c1 { }" +
+            "  }" +
+            "}";
+
+        TaskTreeDecoder decoder = new TaskTreeDecoder(new TaskFactory(), new TaskBuilder());
+
+        decoder.decode(blub);
+    }
+
+    /**
+     *
+     */
+    @Test(expected=java.lang.IllegalArgumentException.class)
+    public void test_Optional_05() {
+        String blub =
+            "UserSession {" +
+            "  Optional op1 {" +
+            "    MouseClick c1 { }" +
+            "  }" +
+            "  Optional op1 {" +
+            "    MouseClick c2 { }" +
+            "  }" +
+            "}";
+
+        TaskTreeDecoder decoder = new TaskTreeDecoder(new TaskFactory(), new TaskBuilder());
+
+        decoder.decode(blub);
+    }
+
+    /**
+     *
+     */
+    @Test(expected=java.lang.IllegalArgumentException.class)
+    public void test_Optional_06() {
+        String blub =
+            "UserSession {" +
+            "  Optional op1 {" +
+            "    MouseClick c1 { }" +
+            "    MouseClick c2 { }" +
+            "  }" +
+            "}";
+
+        TaskTreeDecoder decoder = new TaskTreeDecoder(new TaskFactory(), new TaskBuilder());
+
+        decoder.decode(blub);
+    }
+}
