Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/IReplayDecorator.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/IReplayDecorator.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/IReplayDecorator.java	(revision 922)
@@ -0,0 +1,55 @@
+package de.ugoe.cs.autoquest;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ * This interface defines the structure of decorators used when writing replay
+ * files.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public interface IReplayDecorator extends Serializable {
+
+	/**
+	 * <p>
+	 * Header of the file. Called at the beginning of the writing.
+	 * </p>
+	 * 
+	 * @return file header
+	 */
+	String getHeader();
+
+	/**
+	 * <p>
+	 * Footer of the file. Called at the end of the writing.
+	 * </p>
+	 * 
+	 * @return file footer
+	 */
+	String getFooter();
+
+	/**
+	 * <p>
+	 * Session Header. Called before each session.
+	 * </p>
+	 * 
+	 * @param sessionId
+	 *            id of the session
+	 * @return session header
+	 */
+	String getSessionHeader(int sessionId);
+
+	/**
+	 * <p>
+	 * Session Footer. Called after each session.
+	 * </p>
+	 * 
+	 * @param sessionId
+	 *            id of the session
+	 * @return session footer
+	 */
+	String getSessionFooter(int sessionId);
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/SequenceInstanceOf.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/SequenceInstanceOf.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/SequenceInstanceOf.java	(revision 922)
@@ -0,0 +1,79 @@
+package de.ugoe.cs.autoquest;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+import de.ugoe.cs.autoquest.eventcore.Event;
+
+/**
+ * <p>
+ * Helper class that can be used to determine if an object is a sequence or a
+ * collection of sequences. {@code instanceof} does not work, because of
+ * the type erasure of generics.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class SequenceInstanceOf {
+	
+	/**
+	 * <p>
+	 * Private constructor to prevent initializing of the class.
+	 * </p>
+	 */
+	private SequenceInstanceOf() {
+		
+	}
+
+	/**
+	 * <p>
+	 * Checks if an object is of type {@link Collection}&lt;{@link List}&lt;
+	 * {@link Event}&lt;?&gt;&gt;&gt;.
+	 * </p>
+	 * 
+	 * @param obj
+	 *            object that is checked
+	 * @return true, if the obj is of type {@link Collection}&lt;{@link List}
+	 *         &lt; {@link Event}&lt;?&gt;&gt;&gt;; false otherwise
+	 */
+	public static boolean isCollectionOfSequences(Object obj) {
+		try {
+			if (obj instanceof Collection<?>) {
+				Object listObj = ((Collection<?>) obj).iterator().next();
+				if (listObj instanceof List<?>) {
+					if (((List<?>) listObj).iterator().next() instanceof Event) {
+						return true;
+					}
+				}
+			}
+		} catch (NoSuchElementException e) {
+		}
+		return false;
+	}
+
+	/**
+	 * <p>
+	 * Checks if an object is of type {@link List}&lt;{@link Event}
+	 * &lt;?&gt;&gt;.
+	 * </p>
+	 * 
+	 * @param obj
+	 *            object that is checked
+	 * @return true, if obj is of type {@link List}&lt;{@link Event}
+	 *         &lt;?&gt;&gt;; false otherwise
+	 */
+	public static boolean isEventSequence(Object obj) {
+		try {
+			if (obj instanceof List<?>) {
+				if (((List<?>) obj).iterator().next() instanceof Event) {
+					return true;
+				}
+			}
+		} catch (NoSuchElementException e) {
+		}
+		return false;
+	}
+
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/Event.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/Event.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/Event.java	(revision 922)
@@ -0,0 +1,251 @@
+package de.ugoe.cs.autoquest.eventcore;
+
+import java.io.Serializable;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * <p>
+ * Base class for all events. An event is described by its {@link #type} and its {@link #target}.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ * 
+ * @param <T>
+ *            Can be used to declare that events belong to a specific platform without subclassing.
+ */
+public class Event implements Serializable {
+
+    /**
+     * <p>
+     * Id for object serialization.
+     * </p>
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * <p>
+     * Global start event that can be used to indicate the start of a sequence.
+     * </p>
+     */
+    public static final Event STARTEVENT = new Event(new StringEventType("START"));
+
+    /**
+     * <p>
+     * Global end event that can be used to indicate the end of a sequence.
+     */
+    public static final Event ENDEVENT = new Event(new StringEventType("END"));
+
+    /**
+     * <p>
+     * Type of the event.
+     * </p>
+     */
+    protected IEventType type;
+
+    /**
+     * </p> Target of the event.
+     */
+    protected IEventTarget target = null;
+
+    /**
+     * <p>
+     * List of {@link IReplayable}s of type T that describes the replay of an event. The
+     * {@link IReplayable}s can be interpreted as <it>sub-events</it> on the platform level that
+     * make up the abstract event.
+     * </p>
+     */
+    protected List<IReplayable> replay = new LinkedList<IReplayable>();
+
+    /**
+     * <p>
+     * Constructor. Creates a new Event with a given type. The type must not be null.
+     * </p>
+     * 
+     * @param type
+     *            type of the event
+     */
+    public Event(IEventType type) {
+        if (type == null) {
+            throw new IllegalArgumentException("Event type must not be null");
+        }
+        this.type = type;
+    }
+
+    /**
+     * <p>
+     * Constructor. Creates a new Event with a given type and target. The type must not be null.
+     * </p>
+     * 
+     * @param type
+     *            type of the event
+     * @param target
+     *            target of the event
+     */
+    public Event(IEventType type, IEventTarget target) {
+        this(type);
+        this.target = target;
+    }
+
+    /**
+     * <p>
+     * Two events are equal, if their {@link #type} and {@link #target} are equal.
+     * </p>
+     * <p>
+     * See {@link Object#equals(Object)} for further information.
+     * </p>
+     * 
+     * @param other
+     *            Event that is compared to this
+     * @return true, if events are equal, false otherwise
+     */
+    @Override
+    public boolean equals(Object other) {
+        if (this == other) {
+            return true;
+        }
+        if (other instanceof Event) {
+            Event otherEvent = (Event) other;
+            if (target != null) {
+                return type.equals(otherEvent.type) && target.equals(otherEvent.target);
+            }
+            else {
+                return type.equals(otherEvent.type) && otherEvent.target == null;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * <p>
+     * Returns {@link #getId()} as String representation of the event.
+     * </p>
+     * 
+     * @return String representation of the event
+     */
+    @Override
+    public String toString() {
+        return getId();
+    }
+
+    /**
+     * <p>
+     * Returns the {@link #target} of the event.
+     * </p>
+     * 
+     * @return {@link #target} of the event
+     */
+    public IEventTarget getTarget() {
+        return target;
+    }
+
+    /**
+     * <p>
+     * Returns the {@link #type} of the event.
+     * </p>
+     * 
+     * @return {@link #type} of the event
+     */
+    public IEventType getType() {
+        return type;
+    }
+    
+    /**
+     * <p>
+     * Returns the combination of {@link #type} and {@link #target} as id.
+     * </p>
+     *
+     * @return string of the form (type,target)
+     */
+    public String getId() {
+        String id = type.toString();
+        if( target!=null ) {
+            id += "." + target.getStringIdentifier();
+        }
+        return id;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public int hashCode() {
+        int multiplier = 17;
+        int hash = 42;
+        if (type != null) {
+            hash = multiplier * hash + type.hashCode();
+        }
+        if (target != null) {
+            hash = multiplier * hash + target.hashCode();
+        }
+        return hash;
+    }
+
+    /**
+     * <p>
+     * Sets the target of the event. Once set, the target cannot be changed.
+     * </p>
+     * 
+     * @param target
+     *            target of the event
+     * @return true, if target was changed, false otherwise
+     */
+    public boolean setTarget(IEventTarget target) {
+        if (this.target != null) {
+            return false;
+        }
+        this.target = target;
+        return true;
+    }
+
+    /**
+     * <p>
+     * Adds a new {@link IReplayable} of type T to the replay sequence.
+     * </p>
+     * 
+     * @param replayable
+     *            element that is added to the sequence
+     * @throws IllegalArgumentException
+     *             thrown is replayable is null
+     */
+    public void addReplayable(IReplayable replayable) {
+        if (replayable == null) {
+            throw new IllegalArgumentException("replayble must not be null");
+        }
+        replay.add(replayable);
+    }
+
+    /**
+     * <p>
+     * Adds a {@link List}ist of {@link IReplayable} to the replay sequence.
+     * </p>
+     * 
+     * @param generatedReplaySeq
+     *            {@link List} that is added to the sequence
+     * @throws IllegalArgumentException
+     *             thrown if generatedReplaySeq is null
+     */
+    public void addReplayableSequence(List<? extends IReplayable> generatedReplaySeq) {
+        if (generatedReplaySeq == null) {
+            throw new IllegalArgumentException("generatedReplaySeq must not be null");
+        }
+        replay.addAll(generatedReplaySeq);
+    }
+
+    /**
+     * <p>
+     * Returns a the list of replay events.
+     * </p>
+     * <p>
+     * The return value is a copy of the list used internally!
+     * </p>
+     * 
+     * @return list of replay events.
+     */
+    public List<IReplayable> getReplayables() {
+        return new LinkedList<IReplayable>(replay);
+    }
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/IEventTarget.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/IEventTarget.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/IEventTarget.java	(revision 922)
@@ -0,0 +1,36 @@
+
+package de.ugoe.cs.autoquest.eventcore;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ * Common interface for event targets. An event target can, e.g., be an element of a GUI or Web
+ * server. A concrete event-driven software platform can define its event targets through the
+ * implementation of this interface.
+ * </p>
+ * 
+ * @version 1.0
+ * @author Steffen Herbold
+ */
+public interface IEventTarget extends Serializable {
+
+    /**
+     * <p>
+     * Returns the name of event-driven software platform to which the target belongs.
+     * </p>
+     * 
+     * @return name of the platform
+     */
+    public String getPlatform();
+
+    /**
+     * <p>
+     * Returns a string identifier of the target. This is very convenient for visualizations of
+     * events.
+     * </p>
+     * 
+     * @return target identifier
+     */
+    public String getStringIdentifier();
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/IEventType.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/IEventType.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/IEventType.java	(revision 922)
@@ -0,0 +1,26 @@
+
+package de.ugoe.cs.autoquest.eventcore;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ * Common interface for event types. An event type can be, e.g., a mouse click, a keyboard
+ * interactions in case of GUI platforms or a HTTP request in case of a Web application.
+ * </p>
+ * 
+ * @version 1.0
+ * @author Steffen Herbold
+ */
+public interface IEventType extends Serializable {
+
+    /**
+     * <p>
+     * Returns the name of the event type.
+     * </p>
+     * 
+     * @return name of the event type
+     */
+    public String getName();
+
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/IReplayable.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/IReplayable.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/IReplayable.java	(revision 922)
@@ -0,0 +1,37 @@
+package de.ugoe.cs.autoquest.eventcore;
+
+import java.io.Serializable;
+
+import de.ugoe.cs.autoquest.IReplayDecorator;
+
+/**
+ * <p>
+ * This interface is used by {@link ReplayableEvent}to describe how events can
+ * be replayed. It can be used to define a sequence of fine-grained platform
+ * events that make up an abstract event.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public interface IReplayable extends Serializable {
+
+	/**
+	 * <p>
+	 * Returns a string to be written to the replay script that describes the
+	 * replayable platform event.
+	 * </p>
+	 * 
+	 * @return string for the replay script
+	 */
+	String getReplay();
+	
+	/**
+	 * <p>
+	 * Returns the replay decorator associated with the replayable. Returns null if no replay decorator is associated with the replayable.
+	 * </p>
+	 *
+	 * @return replay decorator
+	 */
+	IReplayDecorator getDecorator();
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/StringEventType.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/StringEventType.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/StringEventType.java	(revision 922)
@@ -0,0 +1,89 @@
+package de.ugoe.cs.autoquest.eventcore;
+
+/**
+ * <p>
+ * A simple event type that is identified by a string.
+ * </p>
+ * 
+ * @version $Revision: $ $Date: Aug 16, 2012$
+ * @author 2012, last modified by $Author: sherbold$
+ */
+public class StringEventType implements IEventType {
+
+    /**
+     * <p>
+     * Id for object serialization.
+     * </p>
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * <p>
+     * String that identifies the event type.
+     * </p>
+     */
+    private String str;
+
+    /**
+     * <p>
+     * Constructor. Creates a new StringEventType. str must not be null.
+     * </p>
+     * 
+     * @param str
+     *            string that identifies the event type
+     * @throws IllegalArgumentException
+     *             thrown if str is null
+     */
+    public StringEventType(String str) throws IllegalArgumentException {
+        if (str == null) {
+            throw new IllegalArgumentException("str must not be null");
+        }
+        this.str = str;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.ugoe.cs.autoquest.eventcore.IEventType#getName()
+     */
+    @Override
+    public String getName() {
+        return "StringEventType";
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        return str;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public int hashCode() {
+        return str.hashCode();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    @Override
+    public boolean equals(Object other) {
+        if (other == this) {
+            return true;
+        }
+        if (other instanceof StringEventType) {
+            return str.equals(((StringEventType) other).str);
+        }
+        return false;
+    }
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/IInteraction.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/IInteraction.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/IInteraction.java	(revision 922)
@@ -0,0 +1,34 @@
+
+package de.ugoe.cs.autoquest.eventcore.gui;
+
+import de.ugoe.cs.autoquest.eventcore.IEventType;
+
+/**
+ * <p>
+ * An interaction is a special event type which represents the interaction of a user with an element
+ * of a GUI. An example is a mouse click on a button.
+ * </p>
+ * 
+ * @version 1.0
+ * @author Patrick Harms
+ */
+public interface IInteraction extends IEventType {
+    /**
+     * <p>
+     * Determines whether an event type starts a logical sequence, i.e., a task.
+     * </p>
+     * 
+     * @return true if a logical sequence is started; false otherwise
+     */
+    public boolean startsLogicalSequence();
+
+    /**
+     * <p>
+     * Determines whether an event type finishes a logical sequence, i.e., a task.
+     * </p>
+     * 
+     * @return true if a logical sequence is finished; false otherwise
+     */
+    public boolean finishesLogicalSequence();
+
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/KeyInteraction.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/KeyInteraction.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/KeyInteraction.java	(revision 922)
@@ -0,0 +1,54 @@
+
+package de.ugoe.cs.autoquest.eventcore.gui;
+
+import de.ugoe.cs.autoquest.keyboardmaps.VirtualKey;
+
+/**
+ * <p>
+ * Base class for all keyboard interaction event types.
+ * </p>
+ * 
+ * @version 1.0
+ * @author Patrick Harms
+ */
+public abstract class KeyInteraction implements IInteraction {
+
+    /**
+     * <p>
+     * Id for object serialization.
+     * </p>
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * <p>
+     * the key associated with the interaction
+     * </p>
+     */
+    private VirtualKey key;
+
+    /**
+     * <p>
+     * Constructor. Creates a new KeyInteraction.
+     * </p>
+     * 
+     * @param key
+     *            key associated with the interaction
+     */
+    public KeyInteraction(VirtualKey key) {
+        super();
+        this.key = key;
+    }
+
+    /**
+     * <p>
+     * Returns the key associated with the interaction.
+     * </p>
+     * 
+     * @return the key
+     */
+    public VirtualKey getKey() {
+        return key;
+    }
+
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/KeyInteractionCorrector.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/KeyInteractionCorrector.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/KeyInteractionCorrector.java	(revision 922)
@@ -0,0 +1,279 @@
+
+package de.ugoe.cs.autoquest.eventcore.gui;
+
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Set;
+import java.util.logging.Level;
+
+import de.ugoe.cs.autoquest.eventcore.Event;
+import de.ugoe.cs.autoquest.keyboardmaps.VirtualKey;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * This class provides the functionality to sort and clean up all key interactions in a log. In
+ * particular:
+ * <ol>
+ * <li>In case a combination key (e.g., shift, alt, control) is held down, multiple
+ * {@link KeyPressed} events are logged, even though only the first one is of importance. This class
+ * removes all {@link KeyPressed} events for combination keys except the first.</li>
+ * <li>In case a normal key is held down, multiple {@link KeyPressed} events are logged, but there
+ * is only one {@link KeyReleased} event. This class adds a {@link KeyReleased} event for all such
+ * {@link KeyPressed} events.</li>
+ * <li>Due to message filtering of applications, it is possible that a {@link KeyReleased} event
+ * without a preceding {@link KeyPressed} event is logged. This class either adds the missing
+ * {@link KeyPressed} right in front of the {@link KeyReleased} or removes the {@link KeyReleased}
+ * depending on the {@link #mode}.
+ * <li>As a result of steps 2-3, we have always a matching {@link KeyPressed}/{@link KeyReleased}
+ * pairs for all normal keys. This class replaces these pairs with a {@link KeyTyped} event at the
+ * position of the {@link KeyPressed} event.</li>
+ * <li>Sometimes combination keys are not released in the same order they have been pressed. This
+ * class ensures that the {@link KeyReleased} are in the opposite order of the {@link KeyPressed}
+ * events for all combination keys.</li>
+ * </ol>
+ * </p>
+ * 
+ * @version 1.0
+ * @author Steffen Herbold
+ */
+public class KeyInteractionCorrector {
+
+    /**
+     * <p>
+     * Describes the clean-up mode.
+     * </p>
+     * 
+     * @version 1.0
+     * @author Steffen Herbold
+     */
+    public static enum CleanupMode {
+        /**
+         * <p>
+         * Single {@link KeyReleased} are removed from the sequence.
+         * </p>
+         */
+        REMOVAL,
+
+        /**
+         * <p>
+         * {@link KeyPressed} events are added to single {@link KeyReleased} events
+         * </p>
+         */
+        ADDITION
+    };
+
+    /**
+     * <p>
+     * 
+     * </p>
+     */
+    private final CleanupMode mode;
+
+    /**
+     * <p>
+     * Constructor. Creates a new {@link KeyInteractionCorrector} with {@link #mode}=
+     * {@link CleanupMode#ADDITION}.
+     * </p>
+     */
+    public KeyInteractionCorrector() {
+        this(CleanupMode.ADDITION);
+    }
+
+    /**
+     * <p>
+     * Constructor. Creates a new {@link KeyInteractionCorrector}.
+     * </p>
+     * 
+     * @param mode
+     *            {@link #mode} of the instance
+     */
+    public KeyInteractionCorrector(CleanupMode mode) {
+        this.mode = mode;
+    }
+
+    /**
+     * <p>
+     * Sorts and cleans up key interactions according to the class specification (@see
+     * {@link KeyInteractionCorrector} class comment).
+     * </p>
+     * <p>
+     * This method returns a sorted copy of a sequence, the sequence itself is not changed.
+     * </p>
+     * 
+     * @param sequence
+     *            sequence which is sorted
+     * @return sorted copy of sequence
+     */
+    public List<Event> sortKeyInteractions(final List<Event> sequence) {
+        List<Event> sortedSequence = new LinkedList<Event>(sequence);
+
+        handleIncompleteKeyPairs(sortedSequence);
+        sortCombinationKeyPairs(sortedSequence);
+
+        return sortedSequence;
+    }
+
+    /**
+     * <p>
+     * Performs tasks 1-4 defined in the class description. Operations are performed in-place on the
+     * passed sequence.
+     * </p>
+     * 
+     * @param sequence
+     *            sequence which is sorted
+     */
+    private void sortCombinationKeyPairs(List<Event> sequence) {
+        LinkedList<VirtualKey> pressedCombinationKeys = new LinkedList<VirtualKey>();
+
+        for (int i = 0; i < sequence.size(); i++) {
+            Event event = sequence.get(i);
+            if (event.getType() instanceof KeyPressed) {
+                final VirtualKey key = ((KeyPressed) event.getType()).getKey();
+                if (key.isCombinationKey()) {
+                    pressedCombinationKeys.add(key);
+                }
+            }
+            if (event.getType() instanceof KeyReleased) {
+                final VirtualKey key = ((KeyReleased) event.getType()).getKey();
+                if (key.isCombinationKey()) {
+                    /*
+                     * if( pressedCombinationKeys.isEmpty() ) { Console.traceln(Level.INFO, "" + i);
+                     * for( int j=i-30 ; j<=i ; j++ ) { Console.traceln(Level.INFO,
+                     * sequence.get(i).toString()); } }
+                     */
+                    if (key.equals(pressedCombinationKeys.getLast())) {
+                        pressedCombinationKeys.removeLast();
+                    }
+                    else {
+                        // look-ahead to find new position
+                        int offset;
+                        for (offset = 1; offset + i < sequence.size(); offset++) {
+                            Event lookaheadEvent = sequence.get(i + offset);
+                            if (lookaheadEvent.getType() instanceof KeyReleased) {
+                                if (((KeyReleased) lookaheadEvent.getType()).getKey()
+                                    .equals(pressedCombinationKeys.getLast()))
+                                {
+                                    break;
+                                }
+                            }
+                        }
+                        sequence.add(i + offset + 1, event);
+                        sequence.remove(i);
+                        i--;
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * <p>
+     * Performs task 5 defined in the class description. Operations are performed in-place on the
+     * passed sequence.
+     * </p>
+     * 
+     * @param sequence
+     *            sequence which is sorted
+     */
+    private void handleIncompleteKeyPairs(List<Event> sequence) {
+        Set<VirtualKey> pressedKeys = new HashSet<VirtualKey>();
+        int firstPressedIndex = -1;
+
+        Set<VirtualKey> pressedCombinationKeysSession = new HashSet<VirtualKey>();
+
+        for (int i = 0; i < sequence.size(); i++) {
+            Event event = sequence.get(i);
+            if (event.getType() instanceof KeyboardFocusChange) {
+                if (firstPressedIndex != -1) {
+                    sequence.remove(i);
+                    sequence.add(firstPressedIndex, event);
+                }
+            }
+
+            if (event.getType() instanceof KeyPressed) {
+                if (pressedKeys.isEmpty()) {
+                    firstPressedIndex = i;
+                }
+                VirtualKey key = ((KeyPressed) event.getType()).getKey();
+                if (!key.isCombinationKey()) {
+                    ListIterator<Event> iter = sequence.listIterator(i);
+                    iter.next();
+                    iter.set(new Event(new KeyTyped(key), event.getTarget()));
+                }
+                else {
+                    pressedCombinationKeysSession.add(key);
+                    if (pressedKeys.contains(key)) {
+                        sequence.remove(i);
+                        i--;
+                    }
+                }
+                pressedKeys.add(key);
+            }
+            if (event.getType() instanceof KeyReleased) {
+                VirtualKey key = ((KeyReleased) event.getType()).getKey();
+                if (!key.isCombinationKey()) {
+                    if (pressedKeys.contains(key)) {
+                        sequence.remove(i);
+                        i--;
+                    }
+                    else {
+                        // found KeyReleased event without KeyPressed
+                        switch (mode)
+                        {
+                            case REMOVAL:
+                                sequence.remove(i);
+                                i--;
+                                break;
+                            case ADDITION:
+                                ListIterator<Event> iter = sequence.listIterator(i);
+                                iter.next();
+                                iter.set(new Event(new KeyTyped(key), event.getTarget()));
+                                break;
+                            default:
+                                throw new AssertionError(
+                                                         "reached source code that should be unreachable");
+                        }
+                    }
+                }
+                else {
+                    if (!pressedKeys.contains(key)) {
+                        if (pressedCombinationKeysSession.contains(key)) {
+                            Console.traceln(Level.SEVERE, "Found a " + key +
+                                " KeyReleased event without a KeyPressed event." +
+                                "The event will be dropped and the session is possibly faulty.");
+                            sequence.remove(i);
+                            i--;
+                        }
+                        else {
+                            Console
+                                .traceln(Level.SEVERE,
+                                         "Found a " +
+                                             key +
+                                             " KeyReleased event without a KeyPressed event." +
+                                             "Since no KeyPressed of key " +
+                                             key +
+                                             " has been part of the session " +
+                                             "till now, we assume that the key has been pressed since the beginning " +
+                                             "of the session and add a KeyPressed event for " +
+                                             key + " to the start " + "of the session.");
+                            sequence.add(0, new Event(new KeyPressed(key), event.getTarget()));
+                            i++;
+                        }
+                    }
+                }
+                pressedKeys.remove(key);
+                if (pressedKeys.isEmpty()) {
+                    firstPressedIndex = -1;
+                }
+            }
+        }
+        if (!pressedKeys.isEmpty()) {
+            Console
+                .traceln(Level.WARNING,
+                         "There was probably a failure during the handling of incomplete key event pairs.");
+        }
+    }
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/KeyInteractionTargetCorrector.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/KeyInteractionTargetCorrector.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/KeyInteractionTargetCorrector.java	(revision 922)
@@ -0,0 +1,68 @@
+// Module    : $RCSfile: KeyInteractionTargetCorrector.java,v $
+// Version   : $Revision: 0.0 $  $Author: pharms $  $Date: 29.08.2012 $
+// Project   : quest-core-events
+// Creation  : 2012 by pharms
+// Copyright : Patrick Harms, 2012
+package de.ugoe.cs.autoquest.eventcore.gui;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import de.ugoe.cs.autoquest.eventcore.Event;
+import de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement;
+
+/**
+ * <p>
+ * This class iterates the provided sequence and sets the target of all key interaction events
+ * to the GUI element having the current keyboard focus. The current keyboard focus is determined
+ * either by keyboard focus events or by using the target of the first key interaction in the
+ * provided sequence. Events changing the keyboard focus are discarded herewith.
+ * </p>
+ * 
+ * @version $Revision: $ $Date: 29.08.2012$
+ * @author 2012, last modified by $Author: pharms$
+ */
+public class KeyInteractionTargetCorrector {
+    
+    /**
+     * <p>
+     * This method performs the work described in the description of the class. A new list is
+     * instantiated and returned. This list is filled with the events provided by the sequence
+     * being the parameter of the method except for key interaction events. Those are replaced
+     * by a new event with the identical event type but the corrected event target.
+     * </p>
+     * 
+     * @param sequence the event sequence to correct the key interactions targets in
+     * 
+     * @return the resulting sequence, in which key interactions have the correct target, i.e.
+     *         the GUI element having the keyboard focus
+     */
+    public List<Event> correctKeyInteractionTargets(List<Event> sequence) {
+        List<Event> resultingSequence = new LinkedList<Event>();
+        IGUIElement currentKeyboardFocusGUIElement = null;
+        
+        for (Event event : sequence) {
+            if (event.getTarget() instanceof IGUIElement) {
+                if (event.getType() instanceof KeyboardFocusChange) {
+                    currentKeyboardFocusGUIElement = (IGUIElement) event.getTarget();
+                    event = null;
+                }
+                else if (event.getType() instanceof KeyInteraction) {
+                    if (currentKeyboardFocusGUIElement == null) {
+                        currentKeyboardFocusGUIElement = (IGUIElement) event.getTarget();
+                    }
+                    
+                    if (!currentKeyboardFocusGUIElement.equals(event.getTarget())) {
+                        event = new Event(event.getType(), currentKeyboardFocusGUIElement);
+                    }
+                }
+            }
+            
+            if (event != null) {
+                resultingSequence.add(event);
+            }
+        }
+        
+        return resultingSequence;
+    }
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/KeyPressed.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/KeyPressed.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/KeyPressed.java	(revision 922)
@@ -0,0 +1,97 @@
+
+package de.ugoe.cs.autoquest.eventcore.gui;
+
+import de.ugoe.cs.autoquest.keyboardmaps.VirtualKey;
+
+/**
+ * <p>
+ * Event type for pressing down a key.
+ * </p>
+ * 
+ * @version 1.0
+ * @author Patrick Harms
+ */
+public class KeyPressed extends KeyInteraction {
+
+    /**
+     * <p>
+     * Id for object serialization.
+     * </p>
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * <p>
+     * Constructor. Creates a new {@link KeyPressed} event type.
+     * </p>
+     * 
+     * @see KeyInteraction#KeyInteraction(VirtualKey)
+     */
+    public KeyPressed(VirtualKey key) {
+        super(key);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.harms.attef.userinteraction.Interaction#getName()
+     */
+    public String getName() {
+        return "KeyPressed " + super.getKey();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        return "pressing key " + super.getKey();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.harms.attef.userinteraction.Interaction#startsLogicalSequence()
+     */
+    public boolean startsLogicalSequence() {
+        // TODO handle lock keys correctly
+        return super.getKey().isCombinationKey();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.harms.attef.userinteraction.Interaction#finishesLogicalSequence()
+     */
+    public boolean finishesLogicalSequence() {
+        return false;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    @Override
+    public boolean equals(Object other) {
+        if (other instanceof KeyPressed) {
+            return (super.getKey() == ((KeyPressed) other).getKey());
+        }
+        else {
+            return false;
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public int hashCode() {
+        return super.getKey().hashCode();
+    }
+
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/KeyReleased.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/KeyReleased.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/KeyReleased.java	(revision 922)
@@ -0,0 +1,94 @@
+package de.ugoe.cs.autoquest.eventcore.gui;
+
+import de.ugoe.cs.autoquest.keyboardmaps.VirtualKey;
+
+/**
+ * <p>
+ * Event type for releasing a key.
+ * </p>
+ * 
+ * @version 1.0
+ * @author Steffen Herbold
+ */
+public class KeyReleased extends KeyInteraction {
+
+    /**
+     * <p>
+     * Id for object serialization.
+     * </p>
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * <p>
+     * Constructor. Creates a new {@link KeyReleased} event type.
+     * </p>
+     * 
+     * @see KeyInteraction#KeyInteraction(VirtualKey)
+     */
+    public KeyReleased(VirtualKey key) {
+        super(key);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.harms.attef.userinteraction.Interaction#getName()
+     */
+    public String getName() {
+        return "KeyReleased " + super.getKey();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        return "releasing key " + super.getKey();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.harms.attef.userinteraction.Interaction#startsLogicalSequence()
+     */
+    public boolean startsLogicalSequence() {
+        return false;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.harms.attef.userinteraction.Interaction#finishesLogicalSequence()
+     */
+    public boolean finishesLogicalSequence() {
+        // TODO handle lock keys correctly
+        return super.getKey().isCombinationKey();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    @Override
+    public boolean equals(Object other) {
+        if (other instanceof KeyReleased) {
+            return (super.getKey() == ((KeyReleased) other).getKey());
+        }
+        else {
+            return false;
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public int hashCode() {
+        return super.getKey().hashCode();
+    }
+
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/KeyTyped.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/KeyTyped.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/KeyTyped.java	(revision 922)
@@ -0,0 +1,98 @@
+
+package de.ugoe.cs.autoquest.eventcore.gui;
+
+import de.ugoe.cs.autoquest.keyboardmaps.VirtualKey;
+
+/**
+ * <p>
+ * Event type for typing a key, i.e., pressing and releasing it right away.
+ * </p>
+ * 
+ * @version 1.0
+ * @author Steffen Herbold
+ */
+public class KeyTyped extends KeyInteraction {
+
+    /**
+     * <p>
+     * Id for object serialization.
+     * </p>
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * <p>
+     * Constructor. Creates a new {@link KeyTyped} event type.
+     * </p>
+     * 
+     * @see KeyInteraction#KeyInteraction(VirtualKey)
+     */
+    public KeyTyped(VirtualKey key) {
+        super(key);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.harms.attef.userinteraction.Interaction#getName()
+     */
+    public String getName() {
+        return "KeyTyped " + super.getKey();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        return "typed key " + super.getKey();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.harms.attef.userinteraction.Interaction#startsLogicalSequence()
+     */
+    public boolean startsLogicalSequence() {
+        // TODO handle lock keys correctly
+        return super.getKey().isCombinationKey();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.harms.attef.userinteraction.Interaction#finishesLogicalSequence()
+     */
+    public boolean finishesLogicalSequence() {
+        // TODO handle lock keys correctly
+        return super.getKey().isCombinationKey();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    @Override
+    public boolean equals(Object other) {
+        if (other instanceof KeyTyped) {
+            return (super.getKey() == ((KeyTyped) other).getKey());
+        }
+        else {
+            return false;
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public int hashCode() {
+        return super.getKey().hashCode();
+    }
+
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/KeyboardFocusChange.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/KeyboardFocusChange.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/KeyboardFocusChange.java	(revision 922)
@@ -0,0 +1,83 @@
+
+package de.ugoe.cs.autoquest.eventcore.gui;
+
+/**
+ * <p>
+ * Event type for keyboard focus changes. The target of the respective event has obtained the
+ * keyboard focus of the application.
+ * </p>
+ * 
+ * @version 1.0
+ * @author Patrick Harms
+ */
+public class KeyboardFocusChange implements IInteraction {
+
+    /**
+     * <p>
+     * Id for object serialization.
+     * </p>
+     */
+    private static final long serialVersionUID = 1L;
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.harms.attef.userinteraction.Interaction#getName()
+     */
+    public String getName() {
+        return "KeyboardFocusChange";
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.ugoe.cs.tasktree.userinteraction.Interaction#startsLogicalSequence()
+     */
+    @Override
+    public boolean startsLogicalSequence() {
+        return true;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.ugoe.cs.tasktree.userinteraction.Interaction#finishesLogicalSequence()
+     */
+    @Override
+    public boolean finishesLogicalSequence() {
+        return true;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        return "keyboard focus changed";
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof KeyboardFocusChange) {
+            return true;
+        }
+        return false;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public int hashCode() {
+        return getClass().hashCode();
+    }
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/MouseButtonDown.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/MouseButtonDown.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/MouseButtonDown.java	(revision 922)
@@ -0,0 +1,114 @@
+
+package de.ugoe.cs.autoquest.eventcore.gui;
+
+/**
+ * <p>
+ * Event type for pressing a mouse button.
+ * </p>
+ * 
+ * @version 1.0
+ * @author Patrick Harms
+ */
+public class MouseButtonDown extends MouseButtonInteraction {
+
+    /**
+     * <p>
+     * Id for object serialization.
+     * </p>
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * <p>
+     * Constructor. Creates a new {@link MouseButtonDown} event type.
+     * </p>
+     * 
+     * @see MouseButtonInteraction#MouseButtonInteraction(Button)
+     */
+    public MouseButtonDown(Button button) {
+        super(button);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.harms.attef.userinteraction.Interaction#getName()
+     */
+    public String getName() {
+        if (super.getButton() == Button.LEFT) {
+            return "LeftMouseButtonDown";
+        }
+        else if (super.getButton() == Button.MIDDLE) {
+            return "MiddleMouseButtonDown";
+        }
+        else if (super.getButton() == Button.RIGHT) {
+            return "RightMouseButtonDown";
+        }
+        else {
+            return "UnknownMouseButtonDown";
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        if (super.getButton() == Button.LEFT) {
+            return "left mouse button down";
+        }
+        else if (super.getButton() == Button.MIDDLE) {
+            return "middle mouse button down";
+        }
+        else if (super.getButton() == Button.RIGHT) {
+            return "right mouse button down";
+        }
+        else {
+            return "unknown mouse button down";
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.harms.attef.userinteraction.Interaction#startsLogicalSequence()
+     */
+    public boolean startsLogicalSequence() {
+        return true;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.harms.attef.userinteraction.Interaction#finishesLogicalSequence()
+     */
+    public boolean finishesLogicalSequence() {
+        return false;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof MouseButtonDown) {
+            return getButton().equals(((MouseButtonDown) obj).getButton());
+        }
+        return false;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public int hashCode() {
+        return getButton().hashCode();
+    }
+
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/MouseButtonInteraction.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/MouseButtonInteraction.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/MouseButtonInteraction.java	(revision 922)
@@ -0,0 +1,85 @@
+
+package de.ugoe.cs.autoquest.eventcore.gui;
+
+/**
+ * <p>
+ * Base class for all mouse interaction event types.
+ * </p>
+ * 
+ * @version 1.0
+ * @author Patrick Harms
+ */
+public abstract class MouseButtonInteraction extends MouseInteraction {
+
+    /**
+     * <p>
+     * Id for object serialization.
+     * </p>
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * <p>
+     * Describes the pressed mouse button.
+     * </p>
+     * 
+     * @version 1.0
+     * @author Patrick Harms
+     */
+    public static enum Button {
+        LEFT, MIDDLE, RIGHT, X;
+    }
+
+    /**
+     * <p>
+     * The button used for mouse interaction
+     * </p>
+     */
+    private Button button;
+
+    /**
+     * <p>
+     * Constructor. Creates a new {@link MouseButtonInteraction}
+     * </p>
+     * 
+     * @param button
+     *            the button associated with the interaction
+     */
+    public MouseButtonInteraction(Button button) {
+        this.button = button;
+    }
+
+    /**
+     * <p>
+     * Returns the button associated with the interaction.
+     * </p>
+     * 
+     * @return the button
+     */
+    public Button getButton() {
+        return button;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof MouseButtonInteraction) {
+            return getButton().equals(((MouseButtonInteraction) obj).getButton());
+        }
+        return false;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public int hashCode() {
+        return getButton().hashCode();
+    }
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/MouseButtonUp.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/MouseButtonUp.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/MouseButtonUp.java	(revision 922)
@@ -0,0 +1,113 @@
+
+package de.ugoe.cs.autoquest.eventcore.gui;
+
+/**
+ * <p>
+ * Event type for releasing a mouse button.
+ * </p>
+ * 
+ * @version 1.0
+ * @author Patrick Harms
+ */
+public class MouseButtonUp extends MouseButtonInteraction {
+
+    /**
+     * <p>
+     * Id for object serialization.
+     * </p>
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * <p>
+     * Constructor. Creates a new {@link MouseButtonUp} event type.
+     * </p>
+     * 
+     * @see MouseButtonInteraction#MouseButtonInteraction(Button)
+     */
+    public MouseButtonUp(Button button) {
+        super(button);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.harms.attef.userinteraction.Interaction#getName()
+     */
+    public String getName() {
+        if (super.getButton() == Button.LEFT) {
+            return "LeftMouseButtonUp";
+        }
+        else if (super.getButton() == Button.MIDDLE) {
+            return "MiddleMouseButtonUp";
+        }
+        else if (super.getButton() == Button.RIGHT) {
+            return "RightMouseButtonUp";
+        }
+        else {
+            return "UnknownMouseButtonUp";
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        if (super.getButton() == Button.LEFT) {
+            return "left mouse button up";
+        }
+        else if (super.getButton() == Button.MIDDLE) {
+            return "middle mouse button up";
+        }
+        else if (super.getButton() == Button.RIGHT) {
+            return "right mouse button up";
+        }
+        else {
+            return "unknown mouse button up";
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.harms.attef.userinteraction.Interaction#startsLogicalSequence()
+     */
+    public boolean startsLogicalSequence() {
+        return false;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.harms.attef.userinteraction.Interaction#finishesLogicalSequence()
+     */
+    public boolean finishesLogicalSequence() {
+        return true;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof MouseButtonUp) {
+            return getButton().equals(((MouseButtonUp) obj).getButton());
+        }
+        return false;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public int hashCode() {
+        return getButton().hashCode();
+    }
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/MouseClick.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/MouseClick.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/MouseClick.java	(revision 922)
@@ -0,0 +1,113 @@
+
+package de.ugoe.cs.autoquest.eventcore.gui;
+
+/**
+ * <p>
+ * Event type for a mouse click, i.e., pressing and releasing it right away.
+ * </p>
+ * 
+ * @version 1.0
+ * @author Patrick Harms
+ */
+public class MouseClick extends MouseButtonInteraction {
+
+    /**
+     * <p>
+     * Id for object serialization.
+     * </p>
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * <p>
+     * Constructor. Creates a new {@link MouseClick} event type.
+     * </p>
+     * 
+     * @see MouseButtonInteraction#MouseButtonInteraction(Button)
+     */
+    public MouseClick(Button button) {
+        super(button);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.harms.attef.userinteraction.Interaction#getName()
+     */
+    public String getName() {
+        if (super.getButton() == Button.LEFT) {
+            return "LeftMouseClick";
+        }
+        else if (super.getButton() == Button.MIDDLE) {
+            return "MiddleMouseClick";
+        }
+        else if (super.getButton() == Button.RIGHT) {
+            return "RightMouseClick";
+        }
+        else {
+            return "UnknownMouseButtonClick";
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        if (super.getButton() == Button.LEFT) {
+            return "left mouse click";
+        }
+        else if (super.getButton() == Button.MIDDLE) {
+            return "middle mouse click";
+        }
+        else if (super.getButton() == Button.RIGHT) {
+            return "right mouse click";
+        }
+        else {
+            return "unknown mouse button click";
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.harms.attef.userinteraction.Interaction#startsLogicalSequence()
+     */
+    public boolean startsLogicalSequence() {
+        return false;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.harms.attef.userinteraction.Interaction#finishesLogicalSequence()
+     */
+    public boolean finishesLogicalSequence() {
+        return false;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof MouseClick) {
+            return getButton().equals(((MouseClick) obj).getButton());
+        }
+        return false;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public int hashCode() {
+        return getButton().hashCode();
+    }
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/MouseClickCondenser.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/MouseClickCondenser.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/MouseClickCondenser.java	(revision 922)
@@ -0,0 +1,107 @@
+
+package de.ugoe.cs.autoquest.eventcore.gui;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import de.ugoe.cs.autoquest.eventcore.Event;
+import de.ugoe.cs.autoquest.eventcore.IEventTarget;
+
+/**
+ * <p>
+ * This class condenses mouse clicks, i.e. it reduces a sequence of mouse button down, mouse button
+ * up and mouse click with the same button on the same event target to a single mouse click with
+ * that button on that target. The mouse button down and mouse button up events are discarded. For
+ * this, it iterates the provided sequence and identifies any match of the named event sequence
+ * pattern. This match is condensed to the mouse click event.
+ * </p>
+ * 
+ * @version 1.0
+ * @author Patrick Harms
+ */
+public class MouseClickCondenser {
+
+    /**
+     * <p>
+     * This method performs the work described in the description of the class. A new list is
+     * instantiated and returned. This list is filled with the events provided by the sequence being
+     * the parameter of the method except for mouse button down and mouse button up events which are
+     * followed by a mouse click event with the same button on the same target.
+     * </p>
+     * 
+     * @param sequence
+     *            the event sequence to condense the mouse clicks in
+     * 
+     * @return the resulting sequence, in which mouse clicks are condensed to single mouse click
+     *         events
+     */
+    public List<Event> condenseMouseClicks(List<Event> sequence) {
+        List<Event> resultingSequence = new LinkedList<Event>();
+
+        int index = 0;
+        while (index < sequence.size()) // -2 because we don't need to go to the end
+        {
+            if ((index + 2) < sequence.size()) {
+                Event mouseButtonDown = sequence.get(index);
+                Event mouseButtonUp = sequence.get(index + 1);
+                Event mouseClick = sequence.get(index + 2);
+                if (mouseClickSequenceFound(mouseButtonDown, mouseButtonUp, mouseClick)) {
+                    // skip the mouse button down and mouse button up event
+                    index += 2;
+                }
+            }
+
+            resultingSequence.add(sequence.get(index));
+            index++;
+        }
+
+        return resultingSequence;
+    }
+
+    /**
+     * 
+     */
+    private boolean mouseClickSequenceFound(Event mouseButtonDown,
+                                            Event mouseButtonUp,
+                                            Event mouseClick)
+    {
+        // check the first in a row of three for validity
+        if (!(mouseButtonDown.getType() instanceof MouseButtonDown)) {
+            return false;
+        }
+
+        // check the second node for validity
+        if (!(mouseButtonUp.getType() instanceof MouseButtonUp)) {
+            return false;
+        }
+
+        IEventTarget eventTarget = mouseButtonDown.getTarget();
+
+        if (!eventTarget.equals(mouseButtonUp.getTarget())) {
+            return false;
+        }
+
+        MouseButtonInteraction.Button button =
+            ((MouseButtonDown) mouseButtonDown.getType()).getButton();
+
+        if (!button.equals(((MouseButtonUp) mouseButtonUp.getType()).getButton())) {
+            return false;
+        }
+
+        // check the third node for validity
+        if (!(mouseClick.getType() instanceof MouseClick)) {
+            return false;
+        }
+
+        if (!eventTarget.equals(mouseClick.getTarget())) {
+            return false;
+        }
+
+        if (!button.equals(((MouseClick) mouseClick.getType()).getButton())) {
+            return false;
+        }
+
+        return true;
+    }
+
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/MouseDoubleClick.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/MouseDoubleClick.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/MouseDoubleClick.java	(revision 922)
@@ -0,0 +1,114 @@
+
+package de.ugoe.cs.autoquest.eventcore.gui;
+
+/**
+ * <p>
+ * Event type for a double click, i.e., pressing the mouse, releasing it, pressing it, and releasing
+ * it again right away.
+ * </p>
+ * 
+ * @version 1.0
+ * @author Patrick Harms
+ */
+public class MouseDoubleClick extends MouseButtonInteraction {
+
+    /**
+     * <p>
+     * Id for object serialization.
+     * </p>
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * <p>
+     * Constructor. Creates a new {@link MouseDoubleClick} event type.
+     * </p>
+     * 
+     * @see MouseButtonInteraction#MouseButtonInteraction(Button)
+     */
+    public MouseDoubleClick(Button button) {
+        super(button);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.harms.attef.userinteraction.Interaction#getName()
+     */
+    public String getName() {
+        if (super.getButton() == Button.LEFT) {
+            return "LeftMouseDoubleClick";
+        }
+        else if (super.getButton() == Button.MIDDLE) {
+            return "MiddleMouseDoubleClick";
+        }
+        else if (super.getButton() == Button.RIGHT) {
+            return "RightMouseDoubleClick";
+        }
+        else {
+            return "UnknownMouseButtonDoubleClick";
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        if (super.getButton() == Button.LEFT) {
+            return "left mouse double click";
+        }
+        else if (super.getButton() == Button.MIDDLE) {
+            return "middle mouse double click";
+        }
+        else if (super.getButton() == Button.RIGHT) {
+            return "right mouse double click";
+        }
+        else {
+            return "unknown mouse button double click";
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.harms.attef.userinteraction.Interaction#startsLogicalSequence()
+     */
+    public boolean startsLogicalSequence() {
+        return false;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.harms.attef.userinteraction.Interaction#finishesLogicalSequence()
+     */
+    public boolean finishesLogicalSequence() {
+        return false;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof MouseDoubleClick) {
+            return getButton().equals(((MouseDoubleClick) obj).getButton());
+        }
+        return false;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public int hashCode() {
+        return getButton().hashCode();
+    }
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/MouseInteraction.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/MouseInteraction.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/MouseInteraction.java	(revision 922)
@@ -0,0 +1,20 @@
+package de.ugoe.cs.autoquest.eventcore.gui;
+
+/**
+ * <p>
+ * Base class for all mouse interaction event types.
+ * </p>
+ * 
+ * @version 1.0
+ * @author Patrick Harms
+ */
+public abstract class MouseInteraction implements IInteraction {
+
+    /**
+     * <p>
+     * Id for object serialization.
+     * </p>
+     */
+    private static final long serialVersionUID = 1L;
+
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/TextInput.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/TextInput.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/TextInput.java	(revision 922)
@@ -0,0 +1,211 @@
+
+package de.ugoe.cs.autoquest.eventcore.gui;
+
+import java.util.Collections;
+import java.util.List;
+
+import de.ugoe.cs.autoquest.eventcore.Event;
+
+/**
+ * <p>
+ * A text input represents a list of key events that together represent entering text into a text
+ * field or text area.
+ * </p>
+ * 
+ * @version 1.0
+ * @author Patrick Harms, Steffen Herbold
+ */
+public class TextInput implements IInteraction {
+
+    /**
+     * <p>
+     * Defines how the {@link TextInput}s are evaluated as equal.
+     * </p>
+     * 
+     * @version 1.0
+     * @author Steffen Herbold
+     */
+    public enum TextEquality {
+        /**
+         * <p>
+         * Two text inputs are equal if their {@link TextInput#textInputEvents} are equal.
+         * </p>
+         */
+        LEXICAL,
+        /**
+         * <p>
+         * Two text inputs are equal if their {@link TextInput#enteredText}s are equal.
+         * </p>
+         */
+        SYNTACTICAL,
+        /**
+         * <p>
+         * All text inputs are equal.
+         * </p>
+         */
+        SEMANTICAL
+    };
+
+    /**
+     * <p>
+     * Id for object serialization.
+     * </p>
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * <p>
+     * The text resulting from the text input events.
+     * </p>
+     */
+    private String enteredText;
+
+    /**
+     * <p>
+     * The text input events that caused the entering of the text.
+     * </p>
+     */
+    private List<Event> textInputEvents;
+
+    /**
+     * <p>
+     * Defines how this TextInput event evaluates the equality.
+     * </p>
+     */
+    private final TextEquality equalityType;
+
+    /**
+     * <p>
+     * Constructor. Creates a new {@link TextInput} with {@link TextEquality#LEXICAL} equality.
+     * </p>
+     * 
+     * @param enteredText
+     *            text resulting from the inputs
+     * @param textInputEvents
+     *            text input events of which this input consists
+     */
+    public TextInput(String enteredText, List<Event> textInputEvents) {
+        this(enteredText, textInputEvents, TextEquality.LEXICAL);
+    }
+
+    /**
+     * <p>
+     * Constructor. Creates a new {@link TextInput}..
+     * </p>
+     * 
+     * @param enteredText
+     *            text resulting from the inputs
+     * @param textInputEvents
+     *            text input events of which this input consists
+     * @param equalityType
+     *            defines how this event evaluates the equality (@see {@link TextEquality})
+     */
+    public TextInput(String enteredText, List<Event> textInputEvents, TextEquality equalityType) {
+        this.enteredText = enteredText;
+        this.textInputEvents = textInputEvents;
+        this.equalityType = equalityType;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.harms.attef.userinteraction.Interaction#getName()
+     */
+    public String getName() {
+        return "TextInput(\"" + enteredText + "\")";
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        return "text input \"" + enteredText + "\"";
+    }
+
+    /**
+     * <p>
+     * Returns the entered text.
+     * </p>
+     * 
+     * @return the entered text
+     */
+    public String getEnteredText() {
+        return enteredText;
+    }
+
+    /**
+     * <p>
+     * Returns the events of which this {@link TextInput} consists. The returned list is immutable.
+     * </p>
+     * 
+     * @return the textInputEvents
+     */
+    public List<Event> getTextInputEvents() {
+        return Collections.unmodifiableList(textInputEvents);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.harms.attef.userinteraction.Interaction#startsLogicalSequence()
+     */
+    public boolean startsLogicalSequence() {
+        return false;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.harms.attef.userinteraction.Interaction#finishesLogicalSequence()
+     */
+    public boolean finishesLogicalSequence() {
+        return false;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        else if (obj instanceof TextInput) {
+            switch (equalityType)
+            {
+                case LEXICAL:
+                    return textInputEvents.equals(((TextInput) obj).textInputEvents);
+                case SYNTACTICAL:
+                    return enteredText.equals(((TextInput) obj).enteredText);
+                case SEMANTICAL:
+                    return true;
+                default:
+                    throw new AssertionError("reached source code that should be unreachable");
+            }
+        }
+        return false;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public int hashCode() {
+        int hashCode = getClass().hashCode();
+        if (equalityType == TextEquality.LEXICAL) {
+            hashCode += enteredText.hashCode() + textInputEvents.size();
+        }
+        else if (equalityType == TextEquality.SYNTACTICAL) {
+            hashCode += enteredText.hashCode();
+        }
+        return hashCode;
+    }
+
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/TextInputDetector.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/TextInputDetector.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/TextInputDetector.java	(revision 922)
@@ -0,0 +1,330 @@
+
+package de.ugoe.cs.autoquest.eventcore.gui;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+
+import de.ugoe.cs.autoquest.eventcore.Event;
+import de.ugoe.cs.autoquest.eventcore.IEventTarget;
+import de.ugoe.cs.autoquest.eventcore.gui.KeyInteraction;
+import de.ugoe.cs.autoquest.eventcore.gui.KeyPressed;
+import de.ugoe.cs.autoquest.eventcore.gui.KeyReleased;
+import de.ugoe.cs.autoquest.eventcore.gui.TextInput.TextEquality;
+import de.ugoe.cs.autoquest.eventcore.guimodel.ITextArea;
+import de.ugoe.cs.autoquest.eventcore.guimodel.ITextField;
+import de.ugoe.cs.autoquest.keyboardmaps.KeyboardMap;
+import de.ugoe.cs.autoquest.keyboardmaps.KeyboardMapFactory;
+import de.ugoe.cs.autoquest.keyboardmaps.VirtualKey;
+
+/**
+ * <p>
+ * The text input detector iterates a list of events and searches for subsequent key events. Those
+ * are replaced by a single text input event representing the text entered through the key events.
+ * The replacement is only done, if the key events have a text field or text area as target
+ * </p>
+ * 
+ * @version $Revision: $ $Date: 18.03.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+public class TextInputDetector {
+
+    /** the keyboard map to use for character recognition */
+    private KeyboardMap keyboardMap = KeyboardMapFactory.createKeyboardMap(Locale.GERMAN);
+
+    /** the keys pressed in parallel */
+    List<VirtualKey> pressedKeys = new ArrayList<VirtualKey>();
+
+    private final TextEquality textEqualityType;
+
+    /**
+     * <p>
+     * Constructor. Creates a new TextInputDectector that generates {@link TextInput} with
+     * {@link TextEquality#LEXICAL} equality.
+     * </p>
+     * 
+     */
+    public TextInputDetector() {
+        this(TextEquality.LEXICAL);
+    }
+
+    /**
+     * <p>
+     * Constructor. Creates a new TextInputDectector that generates {@link TextInput} with a given
+     * {@link TextEquality} type.
+     * </p>
+     * 
+     * @param textEqualityType
+     *            equality type of the generated events
+     */
+    public TextInputDetector(TextEquality textEqualityType) {
+        this.textEqualityType = textEqualityType;
+    }
+
+    /**
+     * <p>
+     * in the provided list of events, this method detects any event sequences that consists of key
+     * interactions and replaces them with a single text input interaction. This contains the
+     * entered text as well as the replaced key interaction events
+     * </p>
+     * 
+     * @param sequence
+     *            the event sequence to search for text input events
+     * 
+     * @return the resulting sequence, in which key interactions on text fields and areas are
+     *         reduced to text input interactions
+     */
+    public List<Event> detectTextInputs(List<Event> sequence) {
+        List<Event> resultingSequence = new LinkedList<Event>();
+
+        int textEntryStartIndex = -1;
+        IEventTarget lastEventTarget = null;
+
+        int index = 0;
+        Event currentEvent = null;
+        Event textInputEvent = null;
+        while (index < sequence.size()) {
+            currentEvent = sequence.get(index);
+            textInputEvent = null;
+
+            if (isKeyInteraction(currentEvent) && isDataInputEventTarget(currentEvent.getTarget()))
+            {
+                if (textEntryStartIndex < 0) {
+                    textEntryStartIndex = index;
+                    lastEventTarget = currentEvent.getTarget();
+                }
+                else if (!lastEventTarget.equals(currentEvent.getTarget())) {
+                    textInputEvent =
+                        handleTextEntrySequence(sequence, textEntryStartIndex, index - 1,
+                                                lastEventTarget);
+
+                    textEntryStartIndex = index;
+                    lastEventTarget = currentEvent.getTarget();
+                }
+                currentEvent = null;
+            }
+            else {
+                if (textEntryStartIndex >= 0) {
+                    textInputEvent =
+                        handleTextEntrySequence(sequence, textEntryStartIndex, index - 1,
+                                                lastEventTarget);
+
+                    textEntryStartIndex = -1;
+                    lastEventTarget = null;
+                }
+
+            }
+
+            if (textInputEvent != null) {
+                resultingSequence.add(textInputEvent);
+            }
+
+            if (currentEvent != null) {
+                resultingSequence.add(currentEvent);
+            }
+
+            index++;
+        }
+
+        if (textEntryStartIndex >= 0) {
+            textInputEvent =
+                handleTextEntrySequence(sequence, textEntryStartIndex, sequence.size() - 1,
+                                        lastEventTarget);
+
+            if (textInputEvent != null) {
+                resultingSequence.add(textInputEvent);
+            }
+        }
+
+        return resultingSequence;
+    }
+
+    /**
+     * <p>
+     * returns true if the provide event is a key interaction; false else
+     * </p>
+     * 
+     * @param event
+     *            the even to check
+     * 
+     * @return as described
+     */
+    private boolean isKeyInteraction(Event event) {
+        return (event.getType() instanceof KeyInteraction);
+    }
+
+    /**
+     * <p>
+     * creates a single text input event as replacement for key interactions being part of the
+     * subsequence of events denoted by the start and end index in the provide event sequence. If no
+     * text was entered, because the subsequence only contained key released events, then no text
+     * input event is generated (the method returns null).
+     * </p>
+     * 
+     * @param sequence
+     *            the event sequence of which the subsequence is analyzed
+     * @param startIndex
+     *            the start index in the event sequence from which the analysis should start
+     *            (inclusive)
+     * @param endIndex
+     *            the end index in the event sequence where the analysis should end (inclusive)
+     * @param eventTarget
+     *            the event target to be used for the new event
+     * 
+     * @return a text input event representing the text input resulting from the events of the
+     *         provided subsequence
+     * 
+     * @throws IllegalArgumentException
+     *             if the denoted subsequence contains other events than key interactions
+     */
+    private Event handleTextEntrySequence(List<Event> sequence,
+                                          int startIndex,
+                                          int endIndex,
+                                          IEventTarget eventTarget)
+    {
+        List<Event> textInputEvents = new ArrayList<Event>();
+
+        String enteredText = determineEnteredText(sequence, startIndex, endIndex, textInputEvents);
+
+        if ((enteredText != null) && (!"".equals(enteredText))) {
+            TextInput textInput = new TextInput(enteredText, textInputEvents, textEqualityType);
+            return new Event(textInput, eventTarget);
+        }
+        else {
+            return null;
+        }
+    }
+
+    /**
+     * <p>
+     * check if an event target is a data input field, i.e. a text field or a text area
+     * </p>
+     * 
+     * @param eventTarget
+     *            the event target to check
+     * 
+     * @return true, if it is a text field or a text area ; false else
+     */
+    private boolean isDataInputEventTarget(IEventTarget eventTarget) {
+        return ((eventTarget instanceof ITextField) || (eventTarget instanceof ITextArea));
+    }
+
+    /**
+     * <p>
+     * determines the text entered in the event subsequence denoted by the start and end index of
+     * the provided event sequence. The method records any pressed and released key interaction as
+     * well as combinations of pressed key interactions (such as shift + letter) and determines the
+     * respective character. All identified characters are then combined to the entered text. The
+     * method also identifies the usage of the back space. The enter key is ignored for text fields
+     * in which pressing the enter key results in finishing the text entry. All analyzed key
+     * interaction events are stored in the provided text input events result list. If the
+     * subsequence only contains key released events, no text was entered and the returned text is
+     * null.
+     * </p>
+     * 
+     * @param sequence
+     *            the event sequence of which the subsequence is analyzed
+     * @param startIndex
+     *            the start index in the event sequence from which the analysis should start
+     *            (inclusive)
+     * @param endIndex
+     *            the end index in the event sequence where the analysis should end (inclusive)
+     * @param textInputEvents
+     *            a buffer to contain any key interaction event analyzed (in out)
+     * 
+     * @return the text entered through the interaction events of the denoted subsequence
+     * 
+     * @throws IllegalArgumentException
+     *             if the denoted sequence contains other events than key interactions
+     */
+    private String determineEnteredText(List<Event> sequence,
+                                        int startIndex,
+                                        int endIndex,
+                                        List<Event> textInputEvents)
+        throws IllegalArgumentException
+    {
+        Event event;
+        StringBuffer enteredText = new StringBuffer();
+
+        for (int i = startIndex; i <= endIndex; i++) {
+            event = sequence.get(i);
+
+            if (event.getType() instanceof KeyPressed || event.getType() instanceof KeyTyped) {
+                VirtualKey key = ((KeyInteraction) event.getType()).getKey();
+
+                pressedKeys.add(key);
+
+                if (key == VirtualKey.BACK_SPACE) {
+                    if (enteredText.length() > 0) {
+                        enteredText.deleteCharAt(enteredText.length() - 1);
+                    }
+                }
+                else if (key == VirtualKey.ENTER) {
+                    // text fields only contain one line of code. Therefore the return is ignored.
+                    if (!(event.getTarget() instanceof ITextField)) {
+                        enteredText.append(getCharacter(key, pressedKeys));
+                    }
+                }
+                else {
+                    char theChar = getCharacter(key, pressedKeys);
+                    if (theChar != Character.UNASSIGNED) {
+                        enteredText.append(theChar);
+                    }
+                }
+            }
+            else if (event.getType() instanceof KeyReleased || event.getType() instanceof KeyTyped)
+            {
+                pressedKeys.remove(((KeyInteraction) event.getType()).getKey());
+            }
+            else {
+                throw new IllegalArgumentException(
+                                                   "the subsequence denoted by the indexes contains other interactions than "
+                                                       + "just key strokes");
+            }
+
+            textInputEvents.add(event);
+        }
+
+        if (enteredText.length() > 0) {
+            return enteredText.toString();
+        }
+        else {
+            return null;
+        }
+    }
+
+    /**
+     * <p>
+     * determines the character matching the pressed key depending on other keys pressed in parallel
+     * such as the shift key.
+     * </p>
+     * 
+     * @param key
+     *            the key for which the character shall be determined
+     * @param pressedKeys
+     *            the list of other keys pressed in parallel
+     * 
+     * @return the character resulting from the combination of pressed keys
+     */
+    private char getCharacter(VirtualKey key, List<VirtualKey> pressedKeys) {
+        boolean numlock = false;
+        boolean shift = false;
+        boolean altgr = false;
+
+        for (VirtualKey pressedKey : pressedKeys) {
+            if (pressedKey.isShiftKey()) {
+                shift = !shift;
+            }
+            else if (pressedKey == VirtualKey.ALT_GRAPH) {
+                altgr = !altgr;
+            }
+            else if (pressedKey == VirtualKey.NUM_LOCK) {
+                numlock = !numlock;
+            }
+        }
+
+        return keyboardMap.getCharacterFor(key, numlock, shift, altgr, false);
+    }
+
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/TextSelection.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/TextSelection.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/TextSelection.java	(revision 922)
@@ -0,0 +1,81 @@
+
+package de.ugoe.cs.autoquest.eventcore.gui;
+
+/**
+ * <p>
+ * Event type for selecting text.
+ * </p>
+ * 
+ * @version 1.0
+ * @author Patrick Harms
+ */
+public class TextSelection implements IInteraction {
+
+    /**
+     * <p>
+     * Id for object serialization.
+     * </p>
+     */
+    private static final long serialVersionUID = 1L;
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.harms.attef.userinteraction.Interaction#getName()
+     */
+    public String getName() {
+        return "TextSelection";
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        return "text selection";
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.harms.attef.userinteraction.Interaction#startsLogicalSequence()
+     */
+    public boolean startsLogicalSequence() {
+        return false;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.harms.attef.userinteraction.Interaction#finishesLogicalSequence()
+     */
+    public boolean finishesLogicalSequence() {
+        return false;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof TextSelection) {
+            return true;
+        }
+        return false;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public int hashCode() {
+        return getClass().hashCode();
+    }
+
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/ValueSelection.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/ValueSelection.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/gui/ValueSelection.java	(revision 922)
@@ -0,0 +1,115 @@
+
+package de.ugoe.cs.autoquest.eventcore.gui;
+
+/**
+ * <p>
+ * Event type for selecting a value.
+ * </p>
+ * 
+ * @version 1.0
+ * @author Patrick Harms
+ */
+public class ValueSelection<T> implements IInteraction {
+
+    /**
+     * <p>
+     * Id for object serialization.
+     * </p>
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * <p>
+     * The selected value.
+     * </p>
+     */
+    private T selectedValue;
+
+    /**
+     * <p>
+     * Constructor. Creates a new ValueSelection.
+     * </p>
+     * 
+     * @param selectedValue
+     *            the selected value
+     */
+    public ValueSelection(T selectedValue) {
+        this.selectedValue = selectedValue;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.harms.attef.userinteraction.Interaction#getName()
+     */
+    public String getName() {
+        return "ValueSelection";
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        return "select value";
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.harms.attef.userinteraction.Interaction#startsLogicalSequence()
+     */
+    public boolean startsLogicalSequence() {
+        return false;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.harms.attef.userinteraction.Interaction#finishesLogicalSequence()
+     */
+    public boolean finishesLogicalSequence() {
+        return false;
+    }
+
+    /**
+     * <p>
+     * Returns the selected value associated with this event.
+     * </p>
+     * 
+     * @return the selectedValue
+     */
+    public T getSelectedValue() {
+        return selectedValue;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if ((obj == null) || (!(obj instanceof ValueSelection<?>))) {
+            return false;
+        }
+
+        ValueSelection<?> otherValueSelection = (ValueSelection<?>) obj;
+
+        return ((otherValueSelection != null) && ((selectedValue == otherValueSelection.selectedValue) || ((selectedValue != null) && (selectedValue
+            .equals(otherValueSelection.selectedValue)))));
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public int hashCode() {
+        return selectedValue.hashCode();
+    }
+
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/AbstractDefaultGUIElement.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/AbstractDefaultGUIElement.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/AbstractDefaultGUIElement.java	(revision 922)
@@ -0,0 +1,268 @@
+
+package de.ugoe.cs.autoquest.eventcore.guimodel;
+
+import java.util.IdentityHashMap;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * <p>
+ * Skeletal implementation for GUI elements.
+ * </p>
+ * 
+ * @version 1.0
+ * @author Patrick Harms
+ */
+public abstract class AbstractDefaultGUIElement implements IGUIElement {
+
+    /**
+     * <p>
+     * Id for object serialization.
+     * </p>
+     */
+    public static final long serialVersionUID = 1L;
+
+    /**
+     * <p>
+     * The reference to equal GUI element manager (needed to preserve singleton behavior, even
+     * though the objects are not singleton).
+     * </p>
+     */
+    private static final EqualGUIElementManager equalGUIElementManager =
+        new EqualGUIElementManager();
+
+    /**
+     * <p>
+     * Specification of the GUI element
+     * </p>
+     */
+    private final IGUIElementSpec specification;
+
+    /**
+     * <p>
+     * Reference to the parent element
+     * </p>
+     */
+    private final IGUIElement parent;
+
+    /**
+     * <p>
+     * Constructor. Creates a new AbstractDefaultGUIElement.
+     * </p>
+     * 
+     * @param specification
+     *            specification of the created GUI element
+     * @param parent
+     *            parent of the created GUI element; null means the element is a top-level window
+     */
+    public AbstractDefaultGUIElement(IGUIElementSpec specification, IGUIElement parent) {
+        this.specification = specification;
+        this.parent = parent;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.ugoe.cs.tasktree.guimodel.GUIElement#getSpecification()
+     */
+    @Override
+    public IGUIElementSpec getSpecification() {
+        return specification;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement#getParent()
+     */
+    @Override
+    public IGUIElement getParent() {
+        return parent;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement#addEqualGUIElement(IGUIElement)
+     */
+    @Override
+    public void addEqualGUIElement(IGUIElement equalElement) {
+        equalGUIElementManager.addEqualGUIElements(this, equalElement);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see GUIElement#equals(GUIElement)
+     */
+    public final boolean equals(Object other) {
+        // implement final, as GUI elements are all singletons and they equal only if they are the
+        // same object or if they are in the list of equal GUI elements
+        return super.equals(other) || equalGUIElementManager.equals(this, other);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public final int hashCode() {
+        // implement final, as GUI elements are all singletons and they equal only if they are the
+        // same object. If there are several GUI element objects that represent the same GUI element
+        // then they are stored in the list of equal elements. In this case, the hash code of the
+        // list is unique within the system
+        return equalGUIElementManager.hashCode(this);
+    }
+
+    /**
+     * <p>
+     * This internal helper class manages equal GUI elements. This is necessary, as we often first
+     * identify many GUI elements as different and later use a heuristic to determine that they are
+     * the same. This class provides the means to preserve the singleton behavior of the GUI
+     * elements after we merge two GUI elements.
+     * </p>
+     * 
+     * @version 1.0
+     * @author Patrick Harms
+     */
+    private static class EqualGUIElementManager {
+
+        /**
+         * <p>
+         * The internal map of GUI elements mapping each registered element to its equal variants.
+         * We use the {@link IdentityHashMap} as a normal hash map would not work because of the
+         * changing of the hash code of GUI elements at runtime.
+         * </p>
+         */
+        private IdentityHashMap<IGUIElement, List<IGUIElement>> identityHashMap =
+            new IdentityHashMap<IGUIElement, List<IGUIElement>>();
+
+        /**
+         * <p>
+         * Adds a new equals relationship between two {@link IGUIElement}s to the equality manager.
+         * </p>
+         * 
+         * @param guiElement1
+         *            first equal GUI element
+         * @param guiElement2
+         *            second equal GUI element
+         */
+        private synchronized void addEqualGUIElements(IGUIElement guiElement1,
+                                                      IGUIElement guiElement2)
+        {
+            List<IGUIElement> list1 = identityHashMap.get(guiElement1);
+            List<IGUIElement> list2 = identityHashMap.get(guiElement2);
+
+            if (list1 == null) {
+                if (list2 == null) {
+                    list2 = new LinkedList<IGUIElement>();
+                    list2.add(guiElement1);
+                    list2.add(guiElement2);
+                    identityHashMap.put(guiElement1, list2);
+                    identityHashMap.put(guiElement2, list2);
+                }
+                else {
+                    addIfNotContained(list2, guiElement1);
+                    identityHashMap.put(guiElement1, list2);
+                }
+            }
+            else {
+                if (list2 == null) {
+                    addIfNotContained(list1, guiElement2);
+                    identityHashMap.put(guiElement2, list1);
+                }
+                else if (list1 != list2) {
+                    list1.addAll(list2);
+                    identityHashMap.put(guiElement2, list1);
+                }
+                // else
+                // in this case, both GUI elements should already be registered with the same
+                // lists.
+            }
+        }
+
+        /**
+         * <p>
+         * Returns the object hash of a {@link IGUIElement}.
+         * </p>
+         * 
+         * @param guiElement
+         *            gui element whose object hash is determined
+         * @return the object hash
+         */
+        private synchronized int hashCode(IGUIElement guiElement) {
+            return System.identityHashCode(getEqualElementsList(guiElement));
+        }
+
+        /**
+         * <p>
+         * Determines the equality of two {@link IGUIElement}s based on the information of the
+         * identify manager. Two elements are equal, if they have been added as equal using
+         * {@link #addEqualGUIElements(IGUIElement, IGUIElement)}.
+         * </p>
+         * 
+         * @param guiElement
+         *            GUI element to which the object is compared
+         * @param other
+         *            object that is compared to the GUI element
+         * @return
+         */
+        private synchronized boolean equals(IGUIElement guiElement, Object other) {
+            if (other instanceof IGUIElement) {
+                for (IGUIElement candidate : getEqualElementsList(guiElement)) {
+                    if (candidate == other) {
+                        return true;
+                    }
+                }
+            }
+
+            return false;
+        }
+
+        /**
+         * <p>
+         * Returns the equal {@link IGUIElement} of a given {@link IGUIElement}.
+         * </p>
+         * 
+         * @param guiElement
+         *            GUI element of which the equal elements are returned
+         * @return the equal GUI elements
+         */
+        private List<IGUIElement> getEqualElementsList(IGUIElement guiElement) {
+            List<IGUIElement> returnValue = identityHashMap.get(guiElement);
+
+            if (returnValue == null) {
+                returnValue = new LinkedList<IGUIElement>();
+                returnValue.add(guiElement);
+                identityHashMap.put(guiElement, returnValue);
+            }
+
+            return returnValue;
+        }
+
+        /**
+         * <p>
+         * Adds {@link IGUIElement} as equal to a list of {@link IGUIElement} if and only if it is
+         * not already contained.
+         * </p>
+         * 
+         * @param equalElementsList
+         *            list of {@link IGUIElement} to which the GUI element is added
+         * @param guiElement
+         *            GUI element to be added
+         */
+        private void addIfNotContained(List<IGUIElement> equalElementsList, IGUIElement guiElement)
+        {
+            for (IGUIElement candidate : equalElementsList) {
+                if (candidate == guiElement) {
+                    return;
+                }
+            }
+
+            equalElementsList.add(guiElement);
+        }
+
+    }
+
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/GUIElementFactory.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/GUIElementFactory.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/GUIElementFactory.java	(revision 922)
@@ -0,0 +1,262 @@
+
+package de.ugoe.cs.autoquest.eventcore.guimodel;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Properties;
+import java.util.logging.Level;
+
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Creates {@link IGUIElement}s from a given specification. Implemented as singleton.
+ * </p>
+ * 
+ * @version 1.0
+ * @author Patrick Harms
+ */
+public class GUIElementFactory implements IGUIElementFactory {
+
+    /**
+     * <p>
+     * Instance of the class (singleton)
+     * </p>
+     */
+    private static GUIElementFactory instance = new GUIElementFactory();
+
+    /**
+     * <p>
+     * Constructor. Creates a new GUIElementFactory. Private to preserve singleton property.
+     * </p>
+     */
+    private GUIElementFactory() {}
+
+    /**
+     * <p>
+     * Returns the instance of this class.
+     * </p>
+     * 
+     * @return the instance
+     */
+    public static synchronized GUIElementFactory getInstance() {
+        return instance;
+    }
+
+    /**
+     * <p>
+     * A property mapping that defines to which Java class is created given the type of the GUI
+     * element found in the specification.
+     * </p>
+     */
+    private Properties mappingsFromConfiguration;
+
+    
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElementFactory#instantiateGUIElement(de.ugoe.cs.autoquest
+     * .eventcore.guimodel.IGUIElementSpec, de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement)
+     */
+    @Override
+    public IGUIElement instantiateGUIElement(IGUIElementSpec specification, IGUIElement parent)
+        throws GUIModelConfigurationException
+    {
+        Properties mappings = getMappingsFromConfiguration();
+        IGUIElement guiElement = null;
+
+        String className = mappings.getProperty(specification.getType());
+        if (className != null) {
+            try {
+                Class<?> clazz = this.getClass().getClassLoader().loadClass(className);
+
+                if (!IGUIElement.class.isAssignableFrom(clazz)) {
+                    Console.traceln(Level.WARNING, "configured GUI element representing class " +
+                        className + " is no valid GUIElement derivate.");
+
+                    return null;
+                }
+
+                Constructor<?> constructor = null;
+                Class<?> parentClass = (parent == null) ? null : parent.getClass();
+
+                // search for a constructor, that perfectly matches the types
+                for (Constructor<?> candidate : clazz.getConstructors()) {
+                    if ((parentClass != null) && (candidate.getParameterTypes().length == 2) &&
+                        (candidate.getParameterTypes()[0].equals(specification.getClass())) &&
+                        (candidate.getParameterTypes()[1].equals(parentClass)))
+                    {
+                        constructor = candidate;
+                        break;
+                    }
+                    else if (parentClass == null) {
+                        if ((candidate.getParameterTypes().length >= 1) &&
+                            (candidate.getParameterTypes()[0].equals(specification.getClass())))
+                        {
+                            constructor = candidate;
+                            break;
+                        }
+                    }
+                }
+
+                if (constructor == null) {
+                    // search for an assignable constructor
+                    for (Constructor<?> candidate : clazz.getConstructors()) {
+                        if ((candidate.getParameterTypes().length == 2) &&
+                            (candidate.getParameterTypes()[0].isInstance(specification)) &&
+                            (candidate.getParameterTypes()[1].isInstance(parent)))
+                        {
+                            constructor = candidate;
+                            break;
+                        }
+                    }
+
+                }
+                
+                if (constructor != null) {
+                    guiElement = (IGUIElement) constructor.newInstance(specification, parent);
+                }
+                else {
+                    throw new NoSuchMethodException
+                        ("no constructor with two parameters and assignable parameter types for " +
+                         specification.getClass() + " and " +
+                         (parent != null ? parent.getClass() : "null") + " found in class " +
+                         clazz);
+                }
+
+            }
+            catch (ClassNotFoundException e) {
+                Console.traceln(Level.WARNING, "configured GUI element representing class " +
+                                className + " can not be loaded.");
+                throw new GUIModelConfigurationException
+                    ("configured GUI element representing class " + className +
+                     " can not be loaded.", e);
+            }
+            catch (SecurityException e) {
+                Console.traceln(Level.WARNING, "configured GUI element representing class " +
+                                className + " can not be instantiated due to security reasons.");
+                throw new GUIModelConfigurationException
+                    ("configured GUI element representing class " + className +
+                     " can not be instantiated due to security reasons.", e);
+            }
+            catch (NoSuchMethodException e) {
+                Console.traceln(Level.WARNING, "configured GUI element representing class " +
+                                className + " does not provide an appropriate constructor.");
+                throw new GUIModelConfigurationException
+                    ("configured GUI element representing class " + className +
+                     " does not provide an appropriate constructor.", e);
+            }
+            catch (IllegalArgumentException e) {
+                Console.traceln(Level.WARNING, "configured GUI element representing class " +
+                                className + " does not provide an appropriate constructor " +
+                                "accepting the provided parameters.");
+                throw new GUIModelConfigurationException
+                    ("configured GUI element representing class " + className + " does not " +
+                     "provide an appropriate constructor accepting the provided parameters.", e);
+            }
+            catch (InstantiationException e) {
+                Console.traceln(Level.WARNING, "configured GUI element representing class " +
+                                className + " can not be instantiated.");
+                throw new GUIModelConfigurationException
+                    ("configured GUI element representing class " + className +
+                     " can not be instantiated.", e);
+            }
+            catch (IllegalAccessException e) {
+                Console.traceln(Level.WARNING, "configured GUI element representing class " +
+                                className + " can not be instantiated.");
+                throw new GUIModelConfigurationException
+                    ("configured GUI element representing class " + className +
+                     " can not be instantiated.", e);
+            }
+            catch (InvocationTargetException e) {
+                Console.traceln(Level.WARNING, "configured GUI element representing class " +
+                                className + " can not be instantiated.");
+                throw new GUIModelConfigurationException
+                    ("configured GUI element representing class " + className +
+                     " can not be instantiated.", e);
+            }
+        }
+        
+        if (guiElement == null ) {
+            Console.traceln(Level.WARNING, "no class representing GUI elements of type " +
+                            specification.getType() + " found. Please extend GUI element " +
+                            "mapping files.");
+            throw new GUIModelConfigurationException
+                ("no class representing GUI elements of type " + specification.getType() +
+                 " found. Please extend GUI element mapping files");
+        }
+
+        return guiElement;
+    }
+
+    /**
+     * <p>
+     * Loads the mappings for GUI elements. All files that start with &quot;guimapping&quot;, end
+     * with &quot;.txt&quot;, and are located in the folter &quot;data/guimappings&quot; (relative
+     * to the working directory) are loaded.
+     * </p>
+     * 
+     * @return loaded GUI mappings
+     */
+    private synchronized Properties getMappingsFromConfiguration()
+        throws GUIModelConfigurationException
+    {
+        if (mappingsFromConfiguration != null) {
+            return mappingsFromConfiguration;
+        }
+        else {
+            mappingsFromConfiguration = new Properties();
+
+            File mappingsFolder = new File("data/guimappings");
+            File[] children = mappingsFolder.listFiles();
+
+            if (children != null) {
+                for (File mappingsFile : children) {
+                    if (!mappingsFile.isDirectory() &&
+                        mappingsFile.getName().startsWith("guimapping") &&
+                        mappingsFile.getName().endsWith(".txt"))
+                    {
+                        InputStream inStream = null;
+                        try {
+                            inStream = new FileInputStream(mappingsFile);
+                            mappingsFromConfiguration.load(inStream);
+                        }
+                        catch (FileNotFoundException e) {
+                            throw new GUIModelConfigurationException(
+                                                                     "could not read mapping configuration file " +
+                                                                         mappingsFile, e);
+                        }
+                        catch (IOException e) {
+                            throw new GUIModelConfigurationException(
+                                                                     "could not read mapping configuration file " +
+                                                                         mappingsFile, e);
+                        }
+                        finally {
+                            if (inStream != null) {
+                                try {
+                                    inStream.close();
+                                }
+                                catch (IOException e) {
+                                    // ignore
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            else {
+                throw new GUIModelConfigurationException(
+                                                         "no GUI mappings file provided in folder " +
+                                                             mappingsFolder);
+            }
+
+            return mappingsFromConfiguration;
+        }
+    }
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/GUIModel.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/GUIModel.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/GUIModel.java	(revision 922)
@@ -0,0 +1,585 @@
+
+package de.ugoe.cs.autoquest.eventcore.guimodel;
+
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.logging.Level;
+
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * A GUI model is a tree of {@link IGUIElements} and represents a complete GUI of a software. It is
+ * platform independent. It may have several root nodes, as some GUIs are made up of several Frames
+ * being independent from each other. The GUI model is filled using the
+ * {@link #integratePath(List, IGUIElementFactory)} method.
+ * </p>
+ * 
+ * @version 1.0
+ * @author Patrick Harms, Steffen Herbold
+ */
+public class GUIModel {
+
+    /**
+     * <p>
+     * The root node of the tree not provided externally.
+     * </p>
+     */
+    private TreeNode root = new TreeNode();
+
+    /**
+     * <p>
+     * A list with all nodes currently known
+     * </p>
+     */
+    private List<TreeNode> allNodes = new ArrayList<TreeNode>();
+
+    /**
+     * <p>
+     * Integrates a path of GUI elements into the GUI model. The GUI model itself is a tree and
+     * therefore a set of different paths through the tree that start with a root node and end with
+     * a leaf node. Such a path can be added to the tree. The method checks, if any of the GUI
+     * elements denoted by the path already exists. If so, it reuses it. It may therefore also
+     * return an existing GUI element being the leaf node of the provided path. If a GUI element of
+     * the path does not exist yet, it creates a new one using the provided GUI element factory.
+     * </p>
+     * <p>
+     * If a GUI element specification describes an existing GUI element or not is determined through
+     * comparing the GUI element specifications of the existing GUI elements with the ones provided
+     * in the path. The comparison is done using the
+     * {@link IGUIElementSpec#getSimilarity(IGUIElementSpec)} method. The comparison is only done on
+     * the correct levels. I.e. the currently known root elements of the tree are only compared to
+     * the first element in the path. If the correct one is found or created, its children are
+     * compared only to the second specification in the path, and so on.
+     * </p>
+     * <p>
+     * The returned GUI elements are singletons. I.e. it is tried to return always the identical
+     * object for the same denoted element. However, while creating the GUI model, the similarity of
+     * GUI elements may change. Therefore, the method might determine, that two formerly different
+     * nodes are now similar. (This may happen, e.g. if GUI elements do not have initial names which
+     * are set afterwards. Therefore, first they are handled differently and later they can be
+     * identified as being the same.) In such a case, there are already several GUI element objects
+     * instantiated for the same GUI element. The singleton paradigm gets broken. Therefore, such
+     * GUI element objects are registered with each other, so that their equal method can determine
+     * equality again correctly, although the objects are no singletons anymore.
+     * </p>
+     * 
+     * @param guiElementPath
+     *            the path to integrate into the model
+     * @param guiElementFactory
+     *            the GUI element factory to be used for instantiating GUI element objects
+     * 
+     * @return The GUI element object representing the GUI element denoted by the provided path
+     * 
+     * @throws GUIModelException
+     *             thrown in cases such as the GUI element object could not be instantiated
+     * @throws IllegalArgumentException
+     *             if the provided path is invalid.
+     */
+    public IGUIElement integratePath(List<? extends IGUIElementSpec> guiElementPath,
+                                     IGUIElementFactory guiElementFactory)
+        throws GUIModelException, IllegalArgumentException
+    {
+        if ((guiElementPath == null) || (guiElementPath.size() <= 0)) {
+            throw new IllegalArgumentException("GUI element path must contain at least one element");
+        }
+
+        List<IGUIElementSpec> remainingPath = new LinkedList<IGUIElementSpec>();
+
+        for (IGUIElementSpec spec : guiElementPath) {
+            remainingPath.add(spec);
+        }
+
+        return integratePath(root, remainingPath, guiElementFactory);
+    }
+
+    /**
+     * <p>
+     * Returns all children of the provided GUI element or null, if it does not have any or the node
+     * is unknown.
+     * </p>
+     * 
+     * @param guiElement
+     *            the GUI element of which the children shall be returned
+     * 
+     * @return As described
+     */
+    public List<IGUIElement> getChildren(IGUIElement guiElement) {
+        List<IGUIElement> result = null;
+        for (TreeNode node : allNodes) {
+            if (node.guiElement.equals(guiElement)) {
+                if (result == null) {
+                    result = new ArrayList<IGUIElement>();
+
+                    if (node.children != null) {
+                        for (TreeNode child : node.children) {
+                            result.add(child.guiElement);
+                        }
+                    }
+                }
+                else {
+                    Console
+                        .traceln(Level.SEVERE,
+                                 "Multiple nodes in the internal GUI model match the same GUI element. "
+                                     + "This should not be the case and the GUI model is probably invalid.");
+                }
+            }
+        }
+
+        return result;
+    }
+
+    /**
+     * <p>
+     * Returns the parent GUI element of the provided GUI element or null, if it does not have a
+     * parent (i.e. if it is a root node) or if the node is unknown.
+     * </p>
+     * 
+     * @param guiElement
+     *            the GUI element of which the parent shall be returned
+     * 
+     * @return As described
+     */
+    public IGUIElement getParent(IGUIElement guiElement) {
+        IGUIElement parent = null;
+
+        for (TreeNode node : allNodes) {
+            for (TreeNode child : node.children) {
+                if (child.guiElement.equals(guiElement)) {
+                    if (parent != null) {
+                        parent = node.guiElement;
+                    }
+                    else {
+                        Console
+                            .traceln(Level.SEVERE,
+                                     "Multiple nodes in the internal GUI model match the same GUI element. "
+                                         + "This should not be the case and the GUI model is probably invalid.");
+                    }
+                }
+            }
+        }
+
+        return parent;
+    }
+
+    /**
+     * <p>
+     * Returns all root GUI elements of the model or an empty list, if the model is empty
+     * </p>
+     * 
+     * @return As described
+     */
+    public List<IGUIElement> getRootElements() {
+        List<IGUIElement> roots = new ArrayList<IGUIElement>();
+
+        if (root.children != null) {
+            for (TreeNode rootChild : root.children) {
+                roots.add(rootChild.guiElement);
+            }
+        }
+
+        return roots;
+    }
+
+    /**
+     * <p>
+     * dumps the GUI model to the provided stream. Each node is represented through its toString()
+     * method. If a node has children, those are dumped indented and surrounded by braces.
+     * </p>
+     * 
+     * @param out
+     *            The stream to dump the textual representation of the model to
+     * @param encoding
+     *            The encoding to be used while dumping
+     */
+    public void dump(OutputStream out, String encoding) {
+        PrintStream stream;
+
+        if (out instanceof PrintStream) {
+            stream = (PrintStream) out;
+        }
+        else {
+            String enc = encoding == null ? "UTF-8" : encoding;
+            try {
+                stream = new PrintStream(out, true, enc);
+            }
+            catch (UnsupportedEncodingException e) {
+                throw new IllegalArgumentException("encodind " + enc + " not supported");
+            }
+        }
+
+        for (IGUIElement root : getRootElements()) {
+            dumpGUIElement(stream, root, "");
+        }
+    }
+
+    /**
+     * <p>
+     * By calling this method, the GUIModel is traversed and similar nodes are merged.
+     * </p>
+     * 
+     */
+    public void condenseModel() {
+        mergeSubTree(root);
+    }
+    
+    /**
+     * <p>
+     * Merges the tree nodes of two GUI elements. The GUI elements need to have the same parent.
+     * </p>
+     * 
+     * @param guiElement1
+     *            the first merge GUI element
+     * @param guiElement2
+     *            the second merge GUI element
+     * @throws IllegalArgumentException
+     *             thrown if the two GUI elements do not have the same parent
+     */
+    public void mergeGUIElements(IGUIElement guiElement1, IGUIElement guiElement2)
+        throws IllegalArgumentException
+    {
+        // check if both nodes have the same parent
+        IGUIElement parentElement = guiElement1.getParent();
+        if (parentElement != null && !parentElement.equals(guiElement2.getParent())) {
+            throw new IllegalArgumentException("can only merge nodes with the same parent");
+        }
+
+        // get the TreeNode of the parent of the GUI elements
+        TreeNode parent = findNode(parentElement);
+
+        // get the TreeNodes for both GUI elements
+        TreeNode node1 = findNode(guiElement1);
+        TreeNode node2 = findNode(guiElement2);
+
+        if (node1 == null || node2 == null) {
+            throw new IllegalArgumentException(
+                                               "Error while merging nodes: one element is not part of the GUI model!");
+        }
+
+        TreeNode replacement = mergeTreeNodes(node1, node2);
+
+        if (parent != null) {
+            // remove node1 and node2 from the parent's children and add the replacement instead
+            // assumes that there are no duplicates of node1 and node2
+            if (parent.children != null) {
+                parent.children.set(parent.children.indexOf(node1), replacement);
+                parent.children.remove(node2);
+            }
+        }
+
+    }
+
+    /**
+     * <p>
+     * internally integrates a path as the children of the provided parent node. This method is
+     * recursive and calls itself, for the child of the parent node, that matches the first element
+     * in the remaining path.
+     * </p>
+     * 
+     * @param parentNode
+     *            the parent node to add children for
+     * @param guiElementPath
+     *            the path of children to be created starting with the parent node
+     * @param guiElementFactory
+     *            the GUI element factory to be used for instantiating GUI element objects
+     * 
+     * @return The GUI element object representing the GUI element denoted by the provided path
+     * 
+     * @throws GUIModelException
+     *             thrown in cases such as the GUI element object could not be instantiated
+     */
+    private IGUIElement integratePath(TreeNode parentNode,
+                                      List<? extends IGUIElementSpec> remainingPath,
+                                      IGUIElementFactory guiElementFactory)
+        throws GUIModelException
+    {
+        IGUIElementSpec specToIntegrateElementFor = remainingPath.remove(0);
+
+        TreeNode child = findEqualChild(parentNode, specToIntegrateElementFor);
+        if (child == null) {
+            IGUIElement newElement =
+                guiElementFactory.instantiateGUIElement(specToIntegrateElementFor,
+                                                        parentNode.guiElement);
+
+            child = parentNode.addChild(newElement);
+        }
+
+        if (remainingPath.size() > 0) {
+            return integratePath(child, remainingPath, guiElementFactory);
+        }
+        else {
+            return child.guiElement;
+        }
+    }
+
+    /**
+     * <p>
+     * Searches the children of a tree node to see if the {@link IGUIElementSpec} of equals the
+     * specification of the {@link TreeNode#guiElement} of the child. If a match is found, the child
+     * is returned.
+     * </p>
+     * 
+     * @param parentNode
+     *            parent node whose children are searched
+     * @param specToMatch
+     *            specification that is searched for
+     * @return matching child node or null if no child matches
+     */
+    private TreeNode findEqualChild(TreeNode parentNode, IGUIElementSpec specToMatch) {
+        if (parentNode.children != null) {
+            for (TreeNode child : parentNode.children) {
+                if (specToMatch.equals(child.guiElement.getSpecification())) {
+                    return child;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * <p>
+     * Merges all similar nodes in the sub-tree of the GUI model defined by the subTreeRoot.
+     * </p>
+     * <p>
+     * The merging order is a bottom-up. This means, that we first call mergeSubTree recursively for
+     * the grand children of the subTreeRoot, before we merge subTreeRoot.
+     * </p>
+     * <p>
+     * The merging strategy is top-down. This means, that every time we merge two child nodes, we
+     * call mergeSubTree recursively for all children of the merged nodes in order to check if we
+     * can merge the children, too.
+     * </p>
+     * 
+     * @param subTreeRoot
+     *            root node of the sub-tree that is merged
+     */
+    private void mergeSubTree(TreeNode subTreeRoot) {
+        if (subTreeRoot.children == null || subTreeRoot.children.isEmpty()) {
+            return;
+        }
+
+        // lets first merge the grand children of the parentNode
+        for (TreeNode child : subTreeRoot.children) {
+            mergeSubTree(child);
+        }
+
+        boolean performedMerge;
+
+        do {
+            performedMerge = false;
+            for (int i = 0; !performedMerge && i < subTreeRoot.children.size(); i++) {
+                IGUIElementSpec elemSpec1 =
+                    subTreeRoot.children.get(i).guiElement.getSpecification();
+                for (int j = i + 1; !performedMerge && j < subTreeRoot.children.size(); j++) {
+                    IGUIElementSpec elemSpec2 =
+                        subTreeRoot.children.get(j).guiElement.getSpecification();
+                    if (elemSpec1.getSimilarity(elemSpec2)) {
+                        TreeNode replacement =
+                            mergeTreeNodes(subTreeRoot.children.get(i), subTreeRoot.children.get(j));
+
+                        subTreeRoot.children.set(i, replacement);
+                        subTreeRoot.children.remove(j);
+                        performedMerge = true;
+                        i--;
+                        break;
+                    }
+                }
+            }
+        }
+        while (performedMerge);
+    }
+
+    /**
+     * <p>
+     * merges two nodes with each other. Merging means registering the GUI element objects with each
+     * other for equality checks. Further it add all children of both nodes to a new replacing node.
+     * Afterwards, all similar nodes of the replacement node are merged as well.
+     * </p>
+     * 
+     * @param treeNode1
+     *            the first of the two nodes to be merged
+     * @param treeNode2
+     *            the second of the two nodes to be merged
+     * @return a tree node being the merge of the two provided nodes.
+     */
+    private TreeNode mergeTreeNodes(TreeNode treeNode1, TreeNode treeNode2) {
+        // the following two lines are needed to preserve the references to the existing GUI
+        // elements. If two elements are the same, one should be deleted to make the elements
+        // singletons again. However, there may exist references to both objects. To preserve
+        // these, we simply register the equal GUI elements with each other so that an equals
+        // check can return true.
+        treeNode1.guiElement.addEqualGUIElement(treeNode2.guiElement);
+        treeNode2.guiElement.addEqualGUIElement(treeNode1.guiElement);
+
+        // and now a replacement node that is the merge of treeNode1 and treeNode2 is created
+        TreeNode replacement = new TreeNode();
+        replacement.guiElement = treeNode1.guiElement;
+        if (treeNode1.children != null) {
+            for (TreeNode child : treeNode1.children) {
+                replacement.addChildNode(child);
+            }
+        }
+        if (treeNode2.children != null) {
+            for (TreeNode child : treeNode2.children) {
+                replacement.addChildNode(child);
+            }
+        }
+
+        mergeSubTree(replacement);
+
+        replacement.guiElement.updateSpecification(treeNode2.guiElement.getSpecification());
+
+        // finally, update the known nodes list
+        // if you don't do this getChildren will return wrong things and very bad things happen!
+        allNodes.remove(treeNode1);
+        allNodes.remove(treeNode2);
+        allNodes.add(replacement);
+
+        return replacement;
+    }
+
+    /**
+     * <p>
+     * dumps a GUI element to the stream. A dump contains the toString() representation of the GUI
+     * element as well as a indented list of its children surrounded by braces.
+     * </p>
+     * 
+     * @param out
+     *            {@link PrintStream} where the guiElement is dumped to
+     * @param guiElement
+     *            the guiElement whos string represenation is dumped
+     * @param indent
+     *            indent string of the dumping
+     */
+    private void dumpGUIElement(PrintStream out, IGUIElement guiElement, String indent) {
+        out.print(indent);
+        out.print(guiElement);
+
+        List<IGUIElement> children = getChildren(guiElement);
+
+        if ((children != null) && (children.size() > 0)) {
+            out.println(" {");
+
+            for (IGUIElement child : children) {
+                dumpGUIElement(out, child, indent + "  ");
+            }
+
+            out.print(indent);
+            out.print("}");
+        }
+
+        out.println();
+    }
+    
+    /**
+     * <p>
+     * Retrieves the TreeNode associated with a GUI element. Returns null if no such TreeNode is
+     * found.
+     * </p>
+     * 
+     * @param element
+     *            the GUI element
+     * @return associated TreeNode; null if no such node exists
+     */
+    private TreeNode findNode(IGUIElement element) {
+        if (element == null) {
+            return null;
+        }
+
+        TreeNode result = null;
+        for (TreeNode node : allNodes) {
+            if (node.guiElement.equals(element)) {
+                if (result == null) {
+                    result = node;
+                }
+                else {
+                    Console
+                        .traceln(Level.SEVERE,
+                                 "Multiple nodes in the internal GUI model match the same GUI element. "
+                                     + "This should not be the case and the GUI model is probably invalid.");
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
+     * <p>
+     * Used internally for building up the tree of GUI elements.
+     * </p>
+     * 
+     * @version 1.0
+     * @author Patrick Harms, Steffen Herbold
+     */
+    private class TreeNode {
+
+        /**
+         * <p>
+         * GUI element associated with the TreeNode.
+         * </p>
+         */
+        private IGUIElement guiElement;
+
+        /**
+         * <p>
+         * Children of the TreeNode.
+         * </p>
+         */
+        private List<TreeNode> children;
+
+        /**
+         * <p>
+         * Adds a child to the current node while keeping all lists of nodes up to date
+         * </p>
+         * 
+         * @param guiElement
+         *            GUI element that will be associated with the new child
+         * @return the added child
+         */
+        private TreeNode addChild(IGUIElement guiElement) {
+            if (children == null) {
+                children = new ArrayList<TreeNode>();
+            }
+
+            TreeNode child = new TreeNode();
+            child.guiElement = guiElement;
+            children.add(child);
+
+            allNodes.add(child);
+
+            return child;
+        }
+
+        /**
+         * 
+         * <p>
+         * Adds a TreeNode as child to the current node. This way, the whole sub-tree is added.
+         * </p>
+         * 
+         * @param node
+         *            child node that is added
+         * @return node that has been added
+         */
+        private TreeNode addChildNode(TreeNode node) {
+            if (children == null) {
+                children = new ArrayList<TreeNode>();
+            }
+            children.add(node);
+            return node;
+        }
+
+        /*
+         * (non-Javadoc)
+         * 
+         * @see java.lang.Object#toString()
+         */
+        @Override
+        public String toString() {
+            return guiElement.toString();
+        }
+    }
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/GUIModelConfigurationException.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/GUIModelConfigurationException.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/GUIModelConfigurationException.java	(revision 922)
@@ -0,0 +1,69 @@
+
+package de.ugoe.cs.autoquest.eventcore.guimodel;
+
+/**
+ * <p>
+ * Exception that is thrown if there is a failure during the creation of a {@link IGUIElement} by
+ * the {@link GUIElementFactory}.
+ * </p>
+ * 
+ * @version 1.0
+ * @author Patrick Harms
+ */
+public class GUIModelConfigurationException extends GUIModelException {
+
+    /**
+     * <p>
+     * Id for object serialization.
+     * </p>
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * <p>
+     * Constructor. Creates a new GUIModelConfigurationException.
+     * </p>
+     */
+    public GUIModelConfigurationException() {
+        super();
+    }
+
+    /**
+     * <p>
+     * Constructor. Creates a new GUIModelConfigurationException.
+     * </p>
+     * 
+     * @param message
+     *            message of the exception
+     */
+    public GUIModelConfigurationException(String message) {
+        super(message);
+    }
+
+    /**
+     * <p>
+     * Constructor. Creates a new GUIModelConfigurationException.
+     * </p>
+     * 
+     * @param cause
+     *            cause of the exception
+     */
+    public GUIModelConfigurationException(Throwable cause) {
+        super(cause);
+    }
+
+    /**
+     * <p>
+     * Constructor. Creates a new GUIModelConfigurationException.
+     * </p>
+     * 
+     * @param message
+     *            message of the exception
+     * @param cause
+     *            cause of the exception
+     */
+    public GUIModelConfigurationException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/GUIModelException.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/GUIModelException.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/GUIModelException.java	(revision 922)
@@ -0,0 +1,68 @@
+
+package de.ugoe.cs.autoquest.eventcore.guimodel;
+
+/**
+ * <p>
+ * Exception that is thrown if there are problems with the {@link GUIModel}.
+ * </p>
+ * 
+ * @version 1.0
+ * @author Patrick Harms
+ */
+public class GUIModelException extends Exception {
+
+    /**
+     * <p>
+     * Id for object serialization.
+     * </p>
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * <p>
+     * Constructor. Creates a new GUIModelException.
+     * </p>
+     */
+    public GUIModelException() {
+        super();
+    }
+
+    /**
+     * <p>
+     * Constructor. Creates a new GUIModelException.
+     * </p>
+     * 
+     * @param message
+     *            message of the exception
+     */
+    public GUIModelException(String message) {
+        super(message);
+    }
+
+    /**
+     * <p>
+     * Constructor. Creates a new GUIModelException.
+     * </p>
+     * 
+     * @param cause
+     *            cause of the exception
+     */
+    public GUIModelException(Throwable cause) {
+        super(cause);
+    }
+
+    /**
+     * <p>
+     * Constructor. Creates a new GUIModelException.
+     * </p>
+     * 
+     * @param message
+     *            message of the exception
+     * @param cause
+     *            cause of the exception
+     */
+    public GUIModelException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IButton.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IButton.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IButton.java	(revision 922)
@@ -0,0 +1,13 @@
+package de.ugoe.cs.autoquest.eventcore.guimodel;
+
+/**
+ * <p>
+ * Marker interface for GUI elements that represent a button
+ * </p>
+ * 
+ * @version 1.0
+ * @author Patrick Harms
+ */
+public interface IButton extends IGUIElement {
+
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/ICanvas.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/ICanvas.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/ICanvas.java	(revision 922)
@@ -0,0 +1,14 @@
+package de.ugoe.cs.autoquest.eventcore.guimodel;
+
+/**
+ * <p>
+ * Marker interface for GUI elements that represent a canvas, i.e. something to display data or
+ * media
+ * </p>
+ * 
+ * @version 1.0
+ * @author Patrick Harms
+ */
+public interface ICanvas extends IGUIElement {
+    
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/ICheckBox.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/ICheckBox.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/ICheckBox.java	(revision 922)
@@ -0,0 +1,13 @@
+package de.ugoe.cs.autoquest.eventcore.guimodel;
+
+/**
+ * <p>
+ * Marker interface for GUI elements that represent a check box
+ * </p>
+ * 
+ * @version 1.0
+ * @author Patrick Harms
+ */
+public interface ICheckBox extends IGUIElement {
+
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IComboBox.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IComboBox.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IComboBox.java	(revision 922)
@@ -0,0 +1,13 @@
+package de.ugoe.cs.autoquest.eventcore.guimodel;
+
+/**
+ * <p>
+ * Marker interface for GUI elements that represent a combo box
+ * </p>
+ * 
+ * @version 1.0
+ * @author Patrick Harms
+ */
+public interface IComboBox extends IGUIElement {
+
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IDialog.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IDialog.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IDialog.java	(revision 922)
@@ -0,0 +1,14 @@
+package de.ugoe.cs.autoquest.eventcore.guimodel;
+
+/**
+ * <p>
+ * Marker interface for GUI elements that represent a dialog
+ * </p>
+ * 
+ * @version 1.0
+ * @author Patrick Harms
+ */
+public interface IDialog extends IGUIElement
+{
+
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IFrame.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IFrame.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IFrame.java	(revision 922)
@@ -0,0 +1,13 @@
+package de.ugoe.cs.autoquest.eventcore.guimodel;
+
+/**
+ * <p>
+ * Marker interface for GUI elements that represent a frame or window
+ * </p>
+ * 
+ * @version 1.0
+ * @author Patrick Harms
+ */
+public interface IFrame extends IGUIElement {
+
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IGUIElement.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IGUIElement.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IGUIElement.java	(revision 922)
@@ -0,0 +1,75 @@
+
+package de.ugoe.cs.autoquest.eventcore.guimodel;
+
+import de.ugoe.cs.autoquest.eventcore.IEventTarget;
+
+/**
+ * <p>
+ * Common interface for all GUI elements.
+ * </p>
+ * 
+ * @version 1.0
+ * @author Patrick Harms
+ */
+public interface IGUIElement extends IEventTarget {
+
+    /**
+     * <p>
+     * Returns the specification of the GUI element.
+     * </p>
+     * 
+     * @return the specification
+     */
+    public IGUIElementSpec getSpecification();
+
+    /**
+     * <p>
+     * Returns the parent of the GUI element.
+     * </p>
+     * 
+     * @return the parent
+     */
+    public IGUIElement getParent();
+
+    /**
+     * <p>
+     * Defines that {@link IGUIElement} implementations have to define equals.
+     * </p>
+     * 
+     * @see Object#equals(Object)
+     */
+    @Override
+    public boolean equals(Object other);
+
+    /**
+     * <p>
+     * Defines that {@link IGUIElement} implementations have to define hashCode.
+     * </p>
+     * 
+     * @see Object#hashCode()
+     */
+    @Override
+    public int hashCode();
+
+    /**
+     * <p>
+     * Updates the specification of a GUI element with another specification, e.g., to add further
+     * known names of the GUI element.
+     * </p>
+     * 
+     * @param furtherSpec
+     *            additional specification
+     */
+    public void updateSpecification(IGUIElementSpec furtherSpec);
+
+    /**
+     * <p>
+     * The {@link IGUIElement} that is passed by this function is equal to the current GUI element
+     * and will hereafter be treated as such.
+     * </p>
+     * 
+     * @param guiElement
+     *            GUI element that is equal
+     */
+    public void addEqualGUIElement(IGUIElement equalElement);
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IGUIElementFactory.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IGUIElementFactory.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IGUIElementFactory.java	(revision 922)
@@ -0,0 +1,29 @@
+package de.ugoe.cs.autoquest.eventcore.guimodel;
+
+/**
+ * <p>
+ * Common interface for GUI element factories. 
+ * </p>
+ * 
+ * @version 1.0
+ * @author Patrick Harms
+ */
+public interface IGUIElementFactory {
+
+    /**
+     * <p>
+     * Instantiates a new {@link IGUIElement} from a given specification.
+     * </p>
+     * 
+     * @param specification
+     *            specification of the new GUI element
+     * @param parent
+     *            parent of the new GUI element
+     * @return created GUI element
+     * @throws GUIModelConfigurationException
+     *             thrown if there is a problem during the creation of the GUI element
+     */
+    public IGUIElement instantiateGUIElement(IGUIElementSpec specification, IGUIElement parent)
+        throws GUIModelConfigurationException;
+    
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IGUIElementSpec.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IGUIElementSpec.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IGUIElementSpec.java	(revision 922)
@@ -0,0 +1,56 @@
+
+package de.ugoe.cs.autoquest.eventcore.guimodel;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ * Common interface for GUI element specifications.
+ * </p>
+ * 
+ * @version 1.0
+ * @author Patrick Harms
+ */
+public interface IGUIElementSpec extends Serializable {
+
+    /**
+     * <p>
+     * Returns a string represenation of the GUI element type that this specification represents.
+     * </p>
+     * 
+     * @return
+     */
+    public String getType();
+
+    /**
+     * <p>
+     * Evaluates if two GUI specifications are similar. Similar means that a heuristic determines
+     * that the two GUI specifications describe the same GUI element.
+     * </p>
+     * 
+     * @param other
+     *            specification whose similarity to this is evaluated
+     * @return true if the specifications are similar; false otherwise
+     */
+    public boolean getSimilarity(IGUIElementSpec other);
+
+    /**
+     * <p>
+     * Defines that {@link IGUIElement} implementations have to define equals.
+     * </p>
+     * 
+     * @see Object#equals(Object)
+     */
+    @Override
+    public boolean equals(Object other);
+
+    /**
+     * <p>
+     * Defines that {@link IGUIElement} implementations have to define hashCode.
+     * </p>
+     * 
+     * @see Object#hashCode()
+     */
+    @Override
+    public int hashCode();
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IListBox.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IListBox.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IListBox.java	(revision 922)
@@ -0,0 +1,13 @@
+package de.ugoe.cs.autoquest.eventcore.guimodel;
+
+/**
+ * <p>
+ * Marker interface for GUI elements that represent a list or list box
+ * </p>
+ * 
+ * @version 1.0
+ * @author Patrick Harms
+ */
+public interface IListBox extends IGUIElement {
+
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IMenu.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IMenu.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IMenu.java	(revision 922)
@@ -0,0 +1,13 @@
+package de.ugoe.cs.autoquest.eventcore.guimodel;
+
+/**
+ * <p>
+ * Marker interface for GUI elements that represent a menu
+ * </p>
+ * 
+ * @version 1.0
+ * @author Patrick Harms
+ */
+public interface IMenu extends IGUIElement {
+
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IMenuBar.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IMenuBar.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IMenuBar.java	(revision 922)
@@ -0,0 +1,13 @@
+package de.ugoe.cs.autoquest.eventcore.guimodel;
+
+/**
+ * <p>
+ * Marker interface for GUI elements that represent a menu bar
+ * </p>
+ * 
+ * @version 1.0
+ * @author Patrick Harms
+ */
+public interface IMenuBar extends IMenu {
+
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IMenuButton.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IMenuButton.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IMenuButton.java	(revision 922)
@@ -0,0 +1,13 @@
+package de.ugoe.cs.autoquest.eventcore.guimodel;
+
+/**
+ * <p>
+ * Marker interface for GUI elements that represent a button in a menu
+ * </p>
+ * 
+ * @version 1.0
+ * @author Patrick Harms
+ */
+public interface IMenuButton extends IButton {
+
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IPanel.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IPanel.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IPanel.java	(revision 922)
@@ -0,0 +1,13 @@
+package de.ugoe.cs.autoquest.eventcore.guimodel;
+
+/**
+ * <p>
+ * Marker interface for GUI elements that represent a panel for structuring GUI content
+ * </p>
+ * 
+ * @version 1.0
+ * @author Patrick Harms
+ */
+public interface IPanel extends IGUIElement {
+
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IRadioButton.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IRadioButton.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IRadioButton.java	(revision 922)
@@ -0,0 +1,13 @@
+package de.ugoe.cs.autoquest.eventcore.guimodel;
+
+/**
+ * <p>
+ * Marker interface for GUI elements that represent a radio button
+ * </p>
+ * 
+ * @version 1.0
+ * @author Patrick Harms
+ */
+public interface IRadioButton extends IGUIElement {
+
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IScrollBar.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IScrollBar.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IScrollBar.java	(revision 922)
@@ -0,0 +1,13 @@
+package de.ugoe.cs.autoquest.eventcore.guimodel;
+
+/**
+ * <p>
+ * Marker interface for GUI elements that represent a scroll bar of a scroll pane
+ * </p>
+ * 
+ * @version 1.0
+ * @author Patrick Harms
+ */
+public interface IScrollBar extends IGUIElement {
+
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IScrollPane.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IScrollPane.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IScrollPane.java	(revision 922)
@@ -0,0 +1,13 @@
+package de.ugoe.cs.autoquest.eventcore.guimodel;
+
+/**
+ * <p>
+ * Marker interface for GUI elements that represent a scroll pane
+ * </p>
+ * 
+ * @version 1.0
+ * @author Patrick Harms
+ */
+public interface IScrollPane extends IGUIElement {
+
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IShape.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IShape.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IShape.java	(revision 922)
@@ -0,0 +1,14 @@
+package de.ugoe.cs.autoquest.eventcore.guimodel;
+
+/**
+ * <p>
+ * Marker interface for GUI elements that represent any kind of shape not covered by the other
+ * marker interfaces
+ * </p>
+ * 
+ * @version 1.0
+ * @author Patrick Harms
+ */
+public interface IShape extends IGUIElement {
+
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/ISplitPane.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/ISplitPane.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/ISplitPane.java	(revision 922)
@@ -0,0 +1,13 @@
+package de.ugoe.cs.autoquest.eventcore.guimodel;
+
+/**
+ * <p>
+ * Marker interface for GUI elements that represent a split pane
+ * </p>
+ * 
+ * @version 1.0
+ * @author Patrick Harms
+ */
+public interface ISplitPane extends IGUIElement {
+
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/ITabbedPane.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/ITabbedPane.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/ITabbedPane.java	(revision 922)
@@ -0,0 +1,13 @@
+package de.ugoe.cs.autoquest.eventcore.guimodel;
+
+/**
+ * <p>
+ * Marker interface for GUI elements that represent a tabbed pane
+ * </p>
+ * 
+ * @version 1.0
+ * @author Patrick Harms
+ */
+public interface ITabbedPane extends IGUIElement {
+
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/ITable.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/ITable.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/ITable.java	(revision 922)
@@ -0,0 +1,13 @@
+package de.ugoe.cs.autoquest.eventcore.guimodel;
+
+/**
+ * <p>
+ * Marker interface for GUI elements that represent a table
+ * </p>
+ * 
+ * @version 1.0
+ * @author Patrick Harms
+ */
+public interface ITable extends IGUIElement {
+
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/ITextArea.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/ITextArea.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/ITextArea.java	(revision 922)
@@ -0,0 +1,13 @@
+package de.ugoe.cs.autoquest.eventcore.guimodel;
+
+/**
+ * <p>
+ * Marker interface for GUI elements that represent a multi line text area
+ * </p>
+ * 
+ * @version 1.0
+ * @author Patrick Harms
+ */
+public interface ITextArea extends IGUIElement {
+
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/ITextField.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/ITextField.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/ITextField.java	(revision 922)
@@ -0,0 +1,13 @@
+package de.ugoe.cs.autoquest.eventcore.guimodel;
+
+/**
+ * <p>
+ * Marker interface for GUI elements that represent a single line text field
+ * </p>
+ * 
+ * @version 1.0
+ * @author Patrick Harms
+ */
+public interface ITextField extends IGUIElement {
+
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IToolBar.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IToolBar.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/IToolBar.java	(revision 922)
@@ -0,0 +1,13 @@
+package de.ugoe.cs.autoquest.eventcore.guimodel;
+
+/**
+ * <p>
+ * Marker interface for GUI elements that represent a tool bar
+ * </p>
+ * 
+ * @version 1.0
+ * @author Patrick Harms
+ */
+public interface IToolBar extends IGUIElement {
+
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/ITrackBar.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/ITrackBar.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/ITrackBar.java	(revision 922)
@@ -0,0 +1,13 @@
+package de.ugoe.cs.autoquest.eventcore.guimodel;
+
+/**
+ * <p>
+ * Marker interface for GUI elements that represent a track bar
+ * </p>
+ * 
+ * @version 1.0
+ * @author Patrick Harms
+ */
+public interface ITrackBar extends IGUIElement {
+
+}
Index: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/ITree.java
===================================================================
--- trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/ITree.java	(revision 922)
+++ trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/ITree.java	(revision 922)
@@ -0,0 +1,13 @@
+package de.ugoe.cs.autoquest.eventcore.guimodel;
+
+/**
+ * <p>
+ * Marker interface for GUI elements that represent a tree view
+ * </p>
+ * 
+ * @version 1.0
+ * @author Patrick Harms
+ */
+public interface ITree extends IGUIElement {
+
+}
