//   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.eventcore.Event;
import de.ugoe.cs.autoquest.eventcore.gui.Scroll;
import de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement;
import de.ugoe.cs.autoquest.eventcore.guimodel.ITextArea;
import de.ugoe.cs.autoquest.eventcore.guimodel.ITextField;
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_Scroll_01() {
        String blub =
            "UserSession {" +
            "  Scroll body1 { }" +
            "}";

        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(((IEventTaskInstance) list.get(0)).getEvent().getType() instanceof Scroll);
        
        new TaskTreeValidator().validate(list);
    }

    /**
     *
     */
    @Test
    public void test_Scroll_02() {
        String blub =
            "UserSession {" +
            "  Scroll body1 { }" +
            "  Scroll body2 { }" +
            "}";

        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(((IEventTaskInstance) list.get(0)).getEvent().getType() instanceof Scroll);

        assertTrue(list.get(1) instanceof IEventTaskInstance);
        assertTrue(list.get(1).getTask() instanceof IEventTask);
        assertTrue(((IEventTaskInstance) list.get(1)).getEvent().getType() instanceof Scroll);
        
        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_Scroll_03() {
        String blub =
            "UserSession {" +
            "  Scroll body1 { }" +
            "  Scroll body1 { }" +
            "}";

        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(((IEventTaskInstance) list.get(0)).getEvent().getType() instanceof Scroll);

        assertTrue(list.get(1) instanceof IEventTaskInstance);
        assertTrue(list.get(1).getTask() instanceof IEventTask);
        assertTrue(((IEventTaskInstance) list.get(1)).getEvent().getType() instanceof Scroll);
        
        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_Scroll_04() {
        String blub =
            "UserSession {" +
            "  Scroll body1 (1 2) { }" +
            "}";

        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(((IEventTaskInstance) list.get(0)).getEvent().getType() instanceof Scroll);
        
        Scroll scroll = (Scroll) ((IEventTaskInstance) list.get(0)).getEvent().getType();
        
        assertEquals(1, scroll.getXPosition());
        assertEquals(2, scroll.getYPosition());
        
        new TaskTreeValidator().validate(list);
    }

    /**
     *
     */
    @Test
    public void test_GuiElements_01() {
        String blub =
            "UserSession {" +
            "  MouseClick elem1 { }" +
            "}";

        TaskTreeDecoder decoder = new TaskTreeDecoder(new TaskFactory(), new TaskBuilder());
        
        ITaskInstanceList list = decoder.decode(blub);
        
        assertTrue(list.get(0) instanceof IEventTaskInstance);
        
        Event event = ((IEventTaskInstance) list.get(0)).getEvent();
        
        assertTrue(event.getTarget() instanceof IGUIElement);
        assertFalse(event.getTarget() instanceof ITextArea);
        assertFalse(event.getTarget() instanceof ITextField);
        
        new TaskTreeValidator().validate(list);
    }

    /**
     *
     */
    @Test
    public void test_GuiElements_02() {
        String blub =
            "UserSession {" +
            "  TextInput elem1 { }" +
            "}";

        TaskTreeDecoder decoder = new TaskTreeDecoder(new TaskFactory(), new TaskBuilder());
        
        ITaskInstanceList list = decoder.decode(blub);
        
        assertTrue(list.get(0) instanceof IEventTaskInstance);
        
        Event event = ((IEventTaskInstance) list.get(0)).getEvent();
        
        assertTrue(event.getTarget() instanceof IGUIElement);
        assertFalse(event.getTarget() instanceof ITextArea);
        assertTrue(event.getTarget() instanceof ITextField);
        
        new TaskTreeValidator().validate(list);
    }

    /**
     *
     */
    @Test
    public void test_GuiElements_03() {
        String blub =
            "UserSession {" +
            "  OtherInteraction elem1 { }" +
            "  TextInput elem1 { }" +
            "}";

        TaskTreeDecoder decoder = new TaskTreeDecoder(new TaskFactory(), new TaskBuilder());
        
        ITaskInstanceList list = decoder.decode(blub);
        
        assertTrue(list.get(0) instanceof IEventTaskInstance);
        
        Event event = ((IEventTaskInstance) list.get(0)).getEvent();
        
        assertTrue(event.getTarget() instanceof IGUIElement);
        assertFalse(event.getTarget() instanceof ITextArea);
        assertTrue(event.getTarget() instanceof ITextField);
        
        assertTrue(list.get(1) instanceof IEventTaskInstance);
        
        event = ((IEventTaskInstance) list.get(1)).getEvent();
        
        assertTrue(event.getTarget() instanceof IGUIElement);
        assertFalse(event.getTarget() instanceof ITextArea);
        assertTrue(event.getTarget() instanceof ITextField);
        
        new TaskTreeValidator().validate(list);
    }

    /**
     *
     */
    @Test
    public void test_GuiElements_04() {
        String blub =
            "UserSession {" +
            "  Sequence seq1 {" +
            "    TextInput elem1 { }" +
            "  }" +
            "}";

        TaskTreeDecoder decoder = new TaskTreeDecoder(new TaskFactory(), new TaskBuilder());
        
        ITaskInstanceList list = decoder.decode(blub);
        
        assertTrue(list.get(0) instanceof ISequenceInstance);
        assertTrue(((ISequenceInstance) list.get(0)).get(0) instanceof IEventTaskInstance);
        
        Event event = ((IEventTaskInstance) ((ISequenceInstance) list.get(0)).get(0)).getEvent();
        
        assertTrue(event.getTarget() instanceof IGUIElement);
        assertFalse(event.getTarget() instanceof ITextArea);
        assertTrue(event.getTarget() instanceof ITextField);
        
        new TaskTreeValidator().validate(list);
    }

    /**
     *
     */
    @Test
    public void test_GuiElements_05() {
        String blub =
            "UserSession {" +
            "  Selection sel1 {" +
            "    TextInput elem1 { }" +
            "  }" +
            "}";

        TaskTreeDecoder decoder = new TaskTreeDecoder(new TaskFactory(), new TaskBuilder());
        
        ITaskInstanceList list = decoder.decode(blub);
        
        assertTrue(list.get(0) instanceof ISelectionInstance);
        assertTrue(((ISelectionInstance) list.get(0)).getChild() instanceof IEventTaskInstance);
        
        Event event =
            ((IEventTaskInstance) ((ISelectionInstance) list.get(0)).getChild()).getEvent();
        
        assertTrue(event.getTarget() instanceof IGUIElement);
        assertFalse(event.getTarget() instanceof ITextArea);
        assertTrue(event.getTarget() instanceof ITextField);
        
        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);
    }

    /**
     *
     */
    @Test
    public void test_Optional_07() {
        String blub =
            "UserSession {" +
            "  Optional op1 {" +
            "    MouseClick c1 { }" +
            "  }" +
            "  Optional op1 { }" +
            "}";

        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);
        assertNull(((IOptionalInstance) list.get(1)).getChild());

        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()));
        
        new TaskTreeValidator().validate(list);
    }

    /**
     *
     */
    @Test
    public void test_Optional_08() {
        String blub =
            "UserSession {" +
            "  Optional op1 { }" +
            "  Optional op1 {" +
            "    MouseClick c1 { }" +
            "  }" +
            "}";

        TaskTreeDecoder decoder = new TaskTreeDecoder(new TaskFactory(), new TaskBuilder());

        ITaskInstanceList list = decoder.decode(blub);

        assertTrue(list.get(0) instanceof IOptionalInstance);
        assertNull(((IOptionalInstance) list.get(0)).getChild());

        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()));
        
        new TaskTreeValidator().validate(list);
    }
}
