Index: /tags/quest-pre-eventrefactoring/JFCMonitor/.classpath
===================================================================
--- /tags/quest-pre-eventrefactoring/JFCMonitor/.classpath	(revision 540)
+++ /tags/quest-pre-eventrefactoring/JFCMonitor/.classpath	(revision 540)
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/JavaHelperLib"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
Index: /tags/quest-pre-eventrefactoring/JFCMonitor/.project
===================================================================
--- /tags/quest-pre-eventrefactoring/JFCMonitor/.project	(revision 540)
+++ /tags/quest-pre-eventrefactoring/JFCMonitor/.project	(revision 540)
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>JFCMonitor</name>
+	<comment></comment>
+	<projects>
+		<project>JavaHelperLib</project>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
Index: /tags/quest-pre-eventrefactoring/JFCMonitor/src/de/ugoe/cs/eventbench/jfcmonitor/JFCComponent.java
===================================================================
--- /tags/quest-pre-eventrefactoring/JFCMonitor/src/de/ugoe/cs/eventbench/jfcmonitor/JFCComponent.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/JFCMonitor/src/de/ugoe/cs/eventbench/jfcmonitor/JFCComponent.java	(revision 540)
@@ -0,0 +1,352 @@
+package de.ugoe.cs.eventbench.jfcmonitor;
+
+import java.awt.Component;
+import java.awt.Container;
+import java.io.File;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.security.InvalidParameterException;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import javax.accessibility.AccessibleContext;
+
+import de.ugoe.cs.util.StringTools;
+
+/**
+ * <p>
+ * This class manages information about the current GUI. It always contains the
+ * current GUI hierarchy.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class JFCComponent {
+
+	/**
+	 * <p>
+	 * Map of all known GUI components.
+	 * </p>
+	 */
+	private static Map<Component, JFCComponent> knownComponents = new HashMap<Component, JFCComponent>();
+
+	/**
+	 * <p>
+	 * Adds a AWT component to the GUI hierarchy. If the component already
+	 * exists in the hierarchy, it is not added a second time.
+	 * </p>
+	 * 
+	 * @param component
+	 *            component that is added
+	 */
+	public static void add(Component component) {
+		add(component, find(component.getParent()));
+	}
+
+	/**
+	 * <p>
+	 * Adds a AWT component to the GUI hierarchy. If the component already
+	 * exists in the hierarchy, it is not added a second time.
+	 * </p>
+	 * 
+	 * @param component
+	 *            component that is added
+	 * @param parent
+	 *            parent of the component
+	 */
+	public static void add(Component component, JFCComponent parent) {
+		if (!knownComponents.containsKey(component)) {
+			knownComponents.put(component, new JFCComponent(component, parent));
+		}
+	}
+
+	/**
+	 * <p>
+	 * Finds a component in the GUI hierarchy and returns the corresponding
+	 * JFComponent instance. Returns null if the component is not found.
+	 * </p>
+	 * 
+	 * @param component
+	 *            component that is searched for
+	 * @return corresponding JFComponent instance; null if the compenent is not
+	 *         found
+	 */
+	public static JFCComponent find(Component component) {
+		return knownComponents.get(component);
+	}
+
+	/**
+	 * <p>
+	 * Removes a component from the GUI hierarchy. In case the component is not
+	 * part of the known hierachy, nothing happens.
+	 * </p>
+	 * 
+	 * @param component
+	 *            component to be removed
+	 */
+	public static void remove(Component component) {
+		JFCComponent jfcComponent = knownComponents.remove(component);
+		if (jfcComponent != null) {
+			jfcComponent.removeFromParent();
+			jfcComponent.removeChildren();
+		}
+	}
+
+	/**
+	 * <p>
+	 * Parent of the GUI component. null means, that the component has no
+	 * parent.
+	 * </p>
+	 */
+	private JFCComponent parent = null;
+
+	/**
+	 * <p>
+	 * Child components of the component.
+	 * </p>
+	 */
+	private List<JFCComponent> children = new LinkedList<JFCComponent>();
+
+	/**
+	 * <p>
+	 * Reference to the actual GUI component.
+	 * </p>
+	 */
+	private Component component;
+
+	/**
+	 * <p>
+	 * Helper attribute that contains the title of the component. Set by
+	 * {@link #setTitle()}.
+	 * </p>
+	 */
+	private String title = null;
+
+	/**
+	 * <p>
+	 * Helper attribute that contains the class of the component. Set by
+	 * {@link #setClass()}.
+	 * </p>
+	 */
+	private String componentClass = null;
+
+	/**
+	 * <p>
+	 * Helper attribute that contains the icon of the component. Set by
+	 * {@link #setIcon()}.
+	 * </p>
+	 */
+	private String icon = null;
+
+	/**
+	 * <p>
+	 * Helper attribute that contains the icon of the component. Set by
+	 * {@link #setIndex()}.
+	 * </p>
+	 */
+	private int index = -1;
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new JFCComponent. Only used internally by
+	 * {@link #add(Component, JFCComponent)}.
+	 * </p>
+	 * 
+	 * @param component
+	 *            component associated with the JFCComponent
+	 * @param parent
+	 *            parent of the component; null if there is no parent
+	 */
+	private JFCComponent(Component component, JFCComponent parent) {
+		if (component == null) {
+			throw new InvalidParameterException(
+					"parameter component must not be null");
+		}
+		this.component = component;
+		this.parent = parent;
+		if (parent != null) {
+			parent.addChild(this);
+		}
+
+		if (component instanceof Container) {
+			for (Component childComponent : ((Container) component)
+					.getComponents()) {
+				add(childComponent, this);
+			}
+		}
+	}
+
+	/**
+	 * <p>
+	 * Adds a child component to the current component.
+	 * </p>
+	 * 
+	 * @param child
+	 *            child component to be added
+	 */
+	private void addChild(JFCComponent child) {
+		children.add(child);
+	}
+
+	/**
+	 * <p>
+	 * Returns an XML representation of the component.
+	 * </p>
+	 * 
+	 * @return XLM snippet
+	 */
+	public String getXML() {
+		setClass();
+		setIcon();
+		setIndex();
+		setTitle();
+		StringBuilder builder = new StringBuilder();
+		if (parent != null) {
+			builder.append(parent.getXML());
+		}
+		builder.append("  <component>" + StringTools.ENDLINE);
+		builder.append("   <param name=\"title\" value=\"" + title + "\" />"
+				+ StringTools.ENDLINE);
+		builder.append("   <param name=\"class\" value=\"" + componentClass
+				+ "\" />" + StringTools.ENDLINE);
+		builder.append("   <param name=\"icon\" value=\"" + icon + "\" />"
+				+ StringTools.ENDLINE);
+		builder.append("   <param name=\"index\" value=\"" + index + "\" />"
+				+ StringTools.ENDLINE);
+		builder.append("   <param name=\"hash\" value=\""
+				+ Integer.toHexString(component.hashCode()) + "\" />"
+				+ StringTools.ENDLINE);
+		builder.append("  </component>" + StringTools.ENDLINE);
+		return builder.toString();
+	}
+
+	/**
+	 * <p>
+	 * Removes a child component from the current component.
+	 * </p>
+	 * 
+	 * @param child
+	 *            child component to be removed
+	 */
+	private void removeChild(JFCComponent child) {
+		children.remove(child);
+	}
+
+	/**
+	 * <p>
+	 * Removes the component from the list of children of its parent.
+	 * </p>
+	 */
+	private void removeFromParent() {
+		if (parent != null) {
+			parent.removeChild(this);
+		}
+	}
+
+	/**
+	 * <p>
+	 * Triggers the removals of all child components from the GUI hierarchy,
+	 * i.e., calls {@link #remove(Component)} for all child components.
+	 * </p>
+	 */
+	private void removeChildren() {
+		for (JFCComponent child : children) {
+			remove(child.component);
+		}
+	}
+
+	/**
+	 * <p>
+	 * Sets the {@link #title} of the component. The title is defined as follows
+	 * (first in the list, that is not null):
+	 * <ul>
+	 * <li>accessible name of the component if available</li>
+	 * <li>{@link #icon} of the component</li>
+	 * <li>name of the component</li>
+	 * <li>coordinates of the component</li>
+	 * </ul>
+	 * </p>
+	 */
+	private void setTitle() {
+		title = null; // reset title
+
+		AccessibleContext accessibleContext = component.getAccessibleContext();
+		if (accessibleContext != null) {
+			title = accessibleContext.getAccessibleName();
+		}
+		if (title == null) {
+			title = icon;
+		}
+		if (title == null) {
+			title = component.getName();
+		}
+		if (title == null) {
+			// use coordinates as last resort
+			title = "Pos(" + component.getX() + "," + component.getY() + ")";
+		}
+	}
+
+	/**
+	 * <p>
+	 * Sets the {@link #componentClass} of the component.
+	 * </p>
+	 */
+	private void setClass() {
+		componentClass = component.getClass().getName();
+	}
+
+	/**
+	 * <p>
+	 * Sets the {@link #icon} of the component.
+	 * </p>
+	 */
+	private void setIcon() {
+		icon = null; // reset icon
+
+		Method getIconMethod;
+		try {
+			getIconMethod = component.getClass().getMethod("getIcon",
+					new Class[0]);
+			if (getIconMethod != null) {
+				Object iconObject = getIconMethod.invoke(component,
+						new Object[] {});
+				if (iconObject != null) {
+					String iconPath = iconObject.toString();
+					if (!iconPath.contains("@")) {
+						System.out.println("iconPath");
+						String[] splitResult = iconPath
+								.split(File.separatorChar == '\\' ? "\\\\"
+										: File.separator);
+						icon = splitResult[splitResult.length - 1];
+					}
+				}
+			}
+		} catch (SecurityException e) {
+		} catch (NoSuchMethodException e) {
+		} catch (IllegalArgumentException e) {
+		} catch (IllegalAccessException e) {
+		} catch (InvocationTargetException e) {
+			System.err.println("Found method with name " + "getIcon"
+					+ " but could not access it.");
+		}
+	}
+
+	/**
+	 * <p>
+	 * Sets the {@link #index} of the component as the index in the parent, if
+	 * it is accessible.
+	 * </p>
+	 */
+	private void setIndex() {
+		index = -1; // reset index
+
+		AccessibleContext accessibleContext = component.getAccessibleContext();
+		if (accessibleContext != null) {
+			index = accessibleContext.getAccessibleIndexInParent();
+		}
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/JFCMonitor/src/de/ugoe/cs/eventbench/jfcmonitor/JFCListener.java
===================================================================
--- /tags/quest-pre-eventrefactoring/JFCMonitor/src/de/ugoe/cs/eventbench/jfcmonitor/JFCListener.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/JFCMonitor/src/de/ugoe/cs/eventbench/jfcmonitor/JFCListener.java	(revision 540)
@@ -0,0 +1,160 @@
+package de.ugoe.cs.eventbench.jfcmonitor;
+
+import java.awt.AWTEvent;
+import java.awt.Component;
+import java.awt.event.AWTEventListener;
+import java.awt.event.FocusEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+
+import de.ugoe.cs.util.StringTools;
+
+/**
+ * <p>
+ * This class implements monitoring of AWT and Swing mouse and keyboard events.
+ * Each of the events is written to an output stream.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class JFCListener implements AWTEventListener {
+
+	/**
+	 * <p>
+	 * Writer for logging events.
+	 * </p>
+	 */
+	final private OutputStreamWriter outputWriter;
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new JFCListener with a given
+	 * {@link OutputStreamWriter}, where the monitored information is logged.
+	 * </p>
+	 * 
+	 * @param outputWriter
+	 *            writer for the logged information
+	 */
+	public JFCListener(OutputStreamWriter outputWriter) {
+		this.outputWriter = outputWriter;
+		try {
+			outputWriter.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+					+ StringTools.ENDLINE);
+			outputWriter.write("<sessions>" + StringTools.ENDLINE);
+		} catch (IOException e) {
+			System.err.println("JFCMONITOR -- Failure writing to log: "
+					+ e.getMessage());
+		}
+	}
+
+	/**
+	 * <p>
+	 * Writes all received {@link MouseEvent}s and {@link KeyEvent}s to the
+	 * {@link #outputWriter}.
+	 * </p>
+	 * 
+	 * @see java.awt.event.AWTEventListener#eventDispatched(java.awt.AWTEvent)
+	 */
+	@Override
+	public void eventDispatched(AWTEvent event) {
+		StringBuilder builder = new StringBuilder();
+
+		if (event instanceof MouseEvent) {
+			if (!isMouseMovement(event.getID())) {
+				MouseEvent mouseEvent = (MouseEvent) event;
+				builder.append("<event id=\"" + event.getID() + "\">"
+						+ StringTools.ENDLINE);
+				builder.append(" <param name=\"X\" value=\""
+						+ mouseEvent.getX() + "\" />" + StringTools.ENDLINE);
+				builder.append(" <param name=\"Y\" value=\""
+						+ mouseEvent.getY() + "\" />" + StringTools.ENDLINE);
+				builder.append(" <param name=\"Button\" value=\""
+						+ mouseEvent.getButton() + "\" />"
+						+ StringTools.ENDLINE);
+				builder.append(" <param name=\"Modifiers\" value=\""
+						+ mouseEvent.getModifiers() + "\" />"
+						+ StringTools.ENDLINE);
+				addSourceInfo(builder, event);
+				builder.append("</event>" + StringTools.ENDLINE);
+			}
+		}
+		else if (event instanceof KeyEvent) {
+			if (event.getID() == KeyEvent.KEY_PRESSED
+					|| event.getID() == KeyEvent.KEY_RELEASED) {
+				KeyEvent keyEvent = (KeyEvent) event;
+				builder.append("<event id=\"" + event.getID() + "\">"
+						+ StringTools.ENDLINE);
+				builder.append(" <param name=\"KeyCode\" value=\""
+						+ keyEvent.getKeyCode() + "\" />" + StringTools.ENDLINE);
+				builder.append(" <param name=\"Modifiers\" value=\""
+						+ keyEvent.getModifiers() + "\" />"
+						+ StringTools.ENDLINE);
+				addSourceInfo(builder, event);
+				builder.append("</event>" + StringTools.ENDLINE);
+			}
+		}
+		else if (event instanceof FocusEvent) {
+			if (event.getID() == FocusEvent.FOCUS_GAINED) {
+				builder.append("<event id=\"" + event.getID() + "\">"
+						+ StringTools.ENDLINE);
+				addSourceInfo(builder, event);
+				builder.append("</event>" + StringTools.ENDLINE);
+			}
+		}
+		if (builder.length() > 0 && outputWriter != null) {
+			try {
+				outputWriter.write(builder.toString());
+				outputWriter.flush();
+			} catch (IOException e) {
+				System.err.println("JFCMONITOR -- Failure writing to log: "
+						+ e.getMessage());
+			}
+		}
+	}
+
+	/**
+	 * <p>
+	 * Appends information about the event to a {@link StringBuilder}.
+	 * </p>
+	 * 
+	 * @param builder
+	 *            {@link StringBuilder} where the information is appended
+	 * @param event
+	 *            event whose information is appended
+	 */
+	private void addSourceInfo(StringBuilder builder, AWTEvent event) {
+		builder.append(" <source>" + StringTools.ENDLINE);
+		builder.append("  <param name=\"toString\" value=\""
+				+ StringTools
+						.xmlEntityReplacement(event.getSource().toString())
+				+ "\" />" + StringTools.ENDLINE);
+		if (event.getSource() instanceof Component) {
+			Component source = (Component) event.getSource();
+			JFCComponent jfcComponent = JFCComponent.find(source);
+			if (jfcComponent != null) {
+				builder.append(jfcComponent.getXML());
+			}
+		}
+		builder.append(" </source>" + StringTools.ENDLINE);
+	}
+
+	/**
+	 * <p>
+	 * Checks if the Id of an {@link AWTEvent} is a mouse movement Id.
+	 * </p>
+	 * 
+	 * @param eventId
+	 *            id of the {@link AWTEvent}
+	 * @return true, if the event is a mouse movement event; false otherwise
+	 */
+	private boolean isMouseMovement(int eventId) {
+		return eventId == MouseEvent.MOUSE_MOVED
+				|| eventId == MouseEvent.MOUSE_DRAGGED
+				|| eventId == MouseEvent.MOUSE_ENTERED
+				|| eventId == MouseEvent.MOUSE_EXITED;
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/JFCMonitor/src/de/ugoe/cs/eventbench/jfcmonitor/JarLauncher.java
===================================================================
--- /tags/quest-pre-eventrefactoring/JFCMonitor/src/de/ugoe/cs/eventbench/jfcmonitor/JarLauncher.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/JFCMonitor/src/de/ugoe/cs/eventbench/jfcmonitor/JarLauncher.java	(revision 540)
@@ -0,0 +1,261 @@
+package de.ugoe.cs.eventbench.jfcmonitor;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Arrays;
+import java.util.jar.JarInputStream;
+import java.util.jar.Manifest;
+
+/**
+ * <p>
+ * Class that launches an executable Jar-file in the same thread and VM where
+ * the JarLauncher instance is created. The requirements on the Jar file are:
+ * <li>Must contain a MANIFEST.</li>
+ * <li>The MANIFEST must define the main-class of the application ("Main-Class"
+ * entry).</li>
+ * <li>The MANIFEST must define the classpath of the application ("Class-Path"
+ * entry).</li>
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class JarLauncher {
+
+	/**
+	 * <p>
+	 * Name of the Jar file to be executed.
+	 * </p>
+	 */
+	private String jarfile;
+
+	/**
+	 * <p>
+	 * Arguments for launching the Jar file.
+	 * </p>
+	 */
+	private String[] args;
+
+	/**
+	 * <p>
+	 * Helper variable with the path to the working directory.
+	 * </p>
+	 */
+	final String workingDir = System.getProperty("user.dir") + "/";
+
+	/**
+	 * <p>
+	 * Internal variable used to store the classpath extracted from the Jar
+	 * file's MANIFEST.
+	 * </p>
+	 */
+	private String[] classPath = new String[] {};
+
+	/**
+	 * <p>
+	 * Internal variable used to store the name (including package information)
+	 * of the Jar file's main function extracted from the Jar file's MANIFEST.
+	 * </p>
+	 */
+	private String mainClassName = "";
+
+	/**
+	 * <p>
+	 * Inner class that defines an exception that is thrown if launching the
+	 * application in the Jar file fails.
+	 * </p>
+	 * 
+	 * @author Steffen Herbold
+	 * @version 1.0
+	 */
+	private static class JarLaunchException extends Exception {
+
+		/**
+		 * <p>
+		 * Id for object serialization.
+		 * </p>
+		 */
+		private static final long serialVersionUID = 1L;
+
+		/**
+		 * <p>
+		 * Constructor. Creates a new JarLaunchException.
+		 * </p>
+		 * 
+		 * @param string
+		 *            error message of the exception
+		 */
+		public JarLaunchException(String string) {
+			super(string);
+		}
+
+		/**
+		 * <p>
+		 * Constructor. Creates a new JarLaunchException as a copy of an
+		 * existing exception.
+		 * </p>
+		 * 
+		 * @param e
+		 *            exception that is copied
+		 */
+		public JarLaunchException(Exception e) {
+			super(e);
+		}
+
+	}
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new JarLauncher.
+	 * </p>
+	 * 
+	 * @param jarfile
+	 *            file to be launched; must not be complete path but in relation
+	 *            to the current working directory
+	 * @param args
+	 *            arguments with which the main function of the Jar file is
+	 *            called
+	 */
+	public JarLauncher(String jarfile, String[] args) {
+		this.jarfile = jarfile;
+		this.args = Arrays.copyOf(args, args.length);
+	}
+
+	/**
+	 * <p>
+	 * Executes the main function of the Jar file associated with this launcher.
+	 * </p>
+	 */
+	public void exec() {
+		try {
+			getInfoFromJar();
+			initClassLoader();
+			runMain();
+		} catch (JarLaunchException e) {
+			System.err.println("Failure to launch application.");
+			System.err.println(e.getMessage());
+		}
+	}
+
+	/**
+	 * <p>
+	 * Retrieves the classpath and main function from the Jar file's MANIFEST.
+	 * </p>
+	 * 
+	 * @throws JarLaunchException
+	 *             thrown if reading of Jar file or MANIFEST fails
+	 */
+	private void getInfoFromJar() throws JarLaunchException {
+		JarInputStream jarInputStream;
+		try {
+			jarInputStream = new JarInputStream(new FileInputStream(workingDir
+					+ jarfile));
+		} catch (FileNotFoundException e) {
+			throw new JarLaunchException(e);
+		} catch (IOException e) {
+			throw new JarLaunchException(e);
+		}
+		Manifest manifest = jarInputStream.getManifest();
+		mainClassName = manifest.getMainAttributes().getValue("Main-Class");
+		String jarClassPath = manifest.getMainAttributes().getValue(
+				"Class-Path");
+		String[] jarClassPathElements = jarClassPath.split(" ");
+		classPath = new String[jarClassPathElements.length];
+		for (int i = 0; i < jarClassPathElements.length; i++) {
+			classPath[i] = "file:" + workingDir + jarClassPathElements[i];
+		}
+		try {
+			jarInputStream.close();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * <p>
+	 * Modifies the {@link ClassLoader} of the current VM such that it includes
+	 * the class path defined in the Jar file's MANIFEST.
+	 * </p>
+	 * 
+	 * @throws JarLaunchException
+	 *             thrown if modification of {@link ClassLoader} fails.
+	 */
+	private void initClassLoader() throws JarLaunchException {
+		URLClassLoader classLoader = (URLClassLoader) ClassLoader
+				.getSystemClassLoader();
+		Method method;
+		try {
+			method = URLClassLoader.class.getDeclaredMethod("addURL",
+					new Class[] { URL.class });
+		} catch (SecurityException e) {
+			throw new JarLaunchException(
+					"addURL method of URLClassLoader not accessible via reflection.");
+		} catch (NoSuchMethodException e) {
+			throw new JarLaunchException(
+					"URLClassLoader does not have addURL method. Should be impossible!!");
+		}
+		method.setAccessible(true);
+
+		try {
+			method.invoke(classLoader, new Object[] { new URL("file:"
+					+ workingDir + jarfile) });
+			for (String element : classPath) {
+				method.invoke(classLoader, new Object[] { new URL(element) });
+			}
+		} catch (IllegalArgumentException e) {
+			throw new JarLaunchException(
+					"Illegal arguments for addURL method. Should be impossible!!");
+		} catch (MalformedURLException e) {
+			throw new JarLaunchException(e);
+		} catch (IllegalAccessException e) {
+			throw new JarLaunchException(
+					"addURL method of URLClassLoader not accessible via reflection.");
+		} catch (InvocationTargetException e) {
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * <p>
+	 * Executes the main function.
+	 * </p>
+	 * 
+	 * @throws JarLaunchException
+	 *             thrown if execution of main function fails or the main
+	 *             function itself throws an exception
+	 */
+	private void runMain() throws JarLaunchException {
+		Class<?> mainClass;
+		try {
+			mainClass = Class.forName(mainClassName);
+		} catch (ClassNotFoundException e) {
+			throw new JarLaunchException("Main class not found: "
+					+ mainClassName);
+		}
+		Method mainMethod;
+		try {
+			mainMethod = mainClass.getMethod("main",
+					new Class[] { String[].class });
+		} catch (SecurityException e) {
+			throw new JarLaunchException("Main method not accessible.");
+		} catch (NoSuchMethodException e) {
+			throw new JarLaunchException("Main method not found.");
+		}
+		try {
+			mainMethod.invoke(null, new Object[] { args });
+		} catch (IllegalArgumentException e) {
+			throw new JarLaunchException(
+					"Illegal arguments for main method. Should be impossible!!");
+		} catch (IllegalAccessException e) {
+			throw new JarLaunchException("Main method not accessible.");
+		} catch (InvocationTargetException e) {
+			throw new JarLaunchException(e);
+		}
+	}
+}
Index: /tags/quest-pre-eventrefactoring/JFCMonitor/src/de/ugoe/cs/eventbench/jfcmonitor/Runner.java
===================================================================
--- /tags/quest-pre-eventrefactoring/JFCMonitor/src/de/ugoe/cs/eventbench/jfcmonitor/Runner.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/JFCMonitor/src/de/ugoe/cs/eventbench/jfcmonitor/Runner.java	(revision 540)
@@ -0,0 +1,92 @@
+package de.ugoe.cs.eventbench.jfcmonitor;
+
+import java.awt.AWTEvent;
+import java.awt.Toolkit;
+import java.awt.event.AWTEventListener;
+import java.awt.event.FocusEvent;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+import java.util.Arrays;
+
+/**
+ * <p>
+ * Start-up class of the application.
+ * </p>
+ * <p>
+ * Launches the application under test in the same JVM.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class Runner {
+
+	/**
+	 * <p>
+	 * Debugging variable. If set to true, the logging is also written to the
+	 * console.
+	 * </p>
+	 */
+	private final static boolean stdOutputWrite = true;
+
+	/**
+	 * <p>
+	 * Main method of the application.
+	 * </p>
+	 * 
+	 * @param args
+	 *            the first parameter defines the Jar file that contains the
+	 *            start-up information of the application under test. The
+	 *            remaining parameters are passed on the toe application under
+	 *            test.
+	 */
+	public static void main(String[] args) {
+		String logfileName = "jfcmonitor_" + System.currentTimeMillis()
+				+ ".log";
+
+		FileOutputStream fis;
+		OutputStreamWriter writer;
+		try {
+			// the writer is not closed explicitly!
+			fis = new FileOutputStream(logfileName, true);
+			writer = new OutputStreamWriter(fis, "UTF-16");
+		} catch (IOException e) {
+			System.err.println("JFCMONITOR -- failure opening logfile: "
+					+ e.getMessage());
+			return;
+		}
+
+		AWTEventListener listenerFile = new JFCListener(writer);
+		Toolkit.getDefaultToolkit().addAWTEventListener(listenerFile,
+				AWTEvent.KEY_EVENT_MASK);
+		Toolkit.getDefaultToolkit().addAWTEventListener(listenerFile,
+				AWTEvent.MOUSE_EVENT_MASK);
+		Toolkit.getDefaultToolkit().addAWTEventListener(listenerFile,
+				FocusEvent.FOCUS_EVENT_MASK);
+		Toolkit.getDefaultToolkit().addAWTEventListener(new WindowMonitor(),
+				AWTEvent.WINDOW_EVENT_MASK);
+
+		if (stdOutputWrite) {
+			AWTEventListener listenerStdOut;
+			try {
+				listenerStdOut = new JFCListener(new OutputStreamWriter(
+						System.out, "UTF-8"));
+				Toolkit.getDefaultToolkit().addAWTEventListener(listenerStdOut,
+						AWTEvent.KEY_EVENT_MASK);
+				Toolkit.getDefaultToolkit().addAWTEventListener(listenerStdOut,
+						AWTEvent.MOUSE_EVENT_MASK);
+				Toolkit.getDefaultToolkit().addAWTEventListener(listenerStdOut,
+						FocusEvent.FOCUS_EVENT_MASK);
+			} catch (UnsupportedEncodingException e) {
+				System.err
+						.println("JFCMONITOR -- failure to create OutputStreamWriter with UTF-8 encoding to System.out");
+			}
+		}
+
+		JarLauncher launcher = new JarLauncher(args[0], Arrays.copyOfRange(
+				args, 1, args.length));
+		launcher.exec();
+	}
+}
Index: /tags/quest-pre-eventrefactoring/JFCMonitor/src/de/ugoe/cs/eventbench/jfcmonitor/WindowMonitor.java
===================================================================
--- /tags/quest-pre-eventrefactoring/JFCMonitor/src/de/ugoe/cs/eventbench/jfcmonitor/WindowMonitor.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/JFCMonitor/src/de/ugoe/cs/eventbench/jfcmonitor/WindowMonitor.java	(revision 540)
@@ -0,0 +1,46 @@
+package de.ugoe.cs.eventbench.jfcmonitor;
+
+import java.awt.AWTEvent;
+import java.awt.Window;
+import java.awt.event.AWTEventListener;
+import java.awt.event.WindowEvent;
+
+/**
+ * <p>
+ * An AWT event listener responsible to monitor the window creation and
+ * destruction.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class WindowMonitor implements AWTEventListener {
+
+	/**
+	 * <p>
+	 * Adds all created windows (and their child components) to the GUI
+	 * hierarchy maintained by {@link JFCComponent} and removes them if a window
+	 * is destroyed.
+	 * </p>
+	 * </p>
+	 * 
+	 * @see java.awt.event.AWTEventListener#eventDispatched(java.awt.AWTEvent)
+	 */
+	@Override
+	public void eventDispatched(AWTEvent event) {
+		Window window;
+		switch (event.getID()) {
+		case WindowEvent.WINDOW_OPENED:
+			window = ((WindowEvent) event).getWindow();
+			JFCComponent.add(window);
+			break;
+		case WindowEvent.WINDOW_CLOSED:
+			window = ((WindowEvent) event).getWindow();
+			JFCComponent.remove(window);
+			break;
+		default:
+			break;
+		}
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/JavaCommons/.project
===================================================================
--- /tags/quest-pre-eventrefactoring/JavaCommons/.project	(revision 540)
+++ /tags/quest-pre-eventrefactoring/JavaCommons/.project	(revision 540)
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>Build</name>
+	<comment></comment>
+	<projects>
+		<project>EventBenchConsole</project>
+		<project>EventBenchCore</project>
+		<project>JavaHelperLib</project>
+	</projects>
+	<buildSpec>
+	</buildSpec>
+	<natures>
+	</natures>
+</projectDescription>
Index: /tags/quest-pre-eventrefactoring/JavaCommons/build.xml
===================================================================
--- /tags/quest-pre-eventrefactoring/JavaCommons/build.xml	(revision 540)
+++ /tags/quest-pre-eventrefactoring/JavaCommons/build.xml	(revision 540)
@@ -0,0 +1,533 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<project basedir="." default="dist" name="EventBench">
+	<!-- General Properties -->
+	<property environment="env" />
+	<property name="build.location" value="bin" />
+	<property name="dist.location" value="dist" />
+	<property name="javadoc.location" value="javadoc" />
+	<property name="downloads.location" value="downloads" />
+	<property name="debuglevel" value="source,lines,vars" />
+	<property name="target" value="1.6" />
+	<property name="source" value="1.6" />
+
+	<!-- Distribution Properties -->
+	<property name="dist.location.main" value="${dist.location}/console" />
+	<property name="dist.location.jfcmonitor" value="${dist.location}/jfcmonitor" />
+	<property name="dist.location.javadoc" value="${dist.location}/javadoc" />
+
+	<!-- EventBenchConsole Properties -->
+	<property name="build.location.eventbenchconsole" value="${build.location}/eventbenchconsole" />
+	<property name="EventBenchConsole.jarname" value="eventbenchconsole.jar" />
+	<property name="EventBenchConsole.location" value="../EventBenchConsole" />
+	<path id="EventBenchConsole.classpath">
+		<pathelement location="${build.location.eventbenchconsole}" />
+		<pathelement location="lib/collections-generic-4.01.jar" />
+		<pathelement location="lib/jdom.jar" />
+		<pathelement location="lib/colt-1.2.0.jar" />
+		<pathelement location="lib/concurrent-1.3.4.jar" />
+		<pathelement location="lib/j3d-core-1.3.1.jar" />
+		<pathelement location="lib/jung-3d-2.0.1.jar" />
+		<pathelement location="lib/jung-3d-demos-2.0.1.jar" />
+		<pathelement location="lib/jung-algorithms-2.0.1.jar" />
+		<pathelement location="lib/jung-api-2.0.1.jar" />
+		<pathelement location="lib/jung-graph-impl-2.0.1.jar" />
+		<pathelement location="lib/jung-io-2.0.1.jar" />
+		<pathelement location="lib/jung-jai-2.0.1.jar" />
+		<pathelement location="lib/jung-jai-samples-2.0.1.jar" />
+		<pathelement location="lib/jung-samples-2.0.1.jar" />
+		<pathelement location="lib/jung-visualization-2.0.1.jar" />
+		<pathelement location="lib/stax-api-1.0.1.jar" />
+		<pathelement location="lib/vecmath-1.3.1.jar" />
+		<pathelement location="lib/wstx-asl-3.2.6.jar" />
+		<pathelement location="lib/commons-codec-1.5.jar" />
+		<pathelement location="lib/org.eclipse.core.commands_3.6.0.I20110111-0800.jar" />
+		<pathelement location="lib/org.eclipse.equinox.common_3.6.0.v20110523.jar" />
+		<pathelement location="lib/org.eclipse.jface_3.7.0.I20110522-1430.jar" />
+		<pathelement location="lib/org.eclipse.osgi_3.7.0.v20110613.jar" />
+		<pathelement location="lib/org.eclipse.swt.win32.win32.x86_3.7.0.v3735b.jar" />
+		<pathelement location="lib/org.eclipse.ui.forms_3.5.100.v20110425.jar" />
+		<pathelement location="lib/org.eclipse.ui.workbench_3.7.0.I20110519-0100.jar" />
+		<pathelement location="lib/gui-model-core.jar" />
+		<pathelement location="lib/log4j-1.2.16.jar" />
+		<pathelement location="lib/jopt-simple-3.3.jar" />
+		<pathelement location="lib/jdom-1.1.3.jar" />
+		<path refid="JavaHelperLib.classpath" />
+		<path refid="EventBenchCore.classpath" />
+	</path>
+
+	<!-- EventBenchCore Properties -->
+	<property name="build.location.eventbenchcore" value="${build.location}/eventbenchcore" />
+	<property name="EventBenchCore.jarname" value="eventbenchcore.jar" />
+	<property name="EventBenchCore.location" value="../EventBenchCore" />
+	<path id="EventBenchCore.classpath">
+		<pathelement location="${build.location.eventbenchcore}" />
+		<pathelement location="lib/Jama-1.0.2.jar" />
+		<pathelement location="lib/colt-1.2.0.jar" />
+		<pathelement location="lib/concurrent-1.3.4.jar" />
+		<pathelement location="lib/j3d-core-1.3.1.jar" />
+		<pathelement location="lib/jung-3d-2.0.1.jar" />
+		<pathelement location="lib/jung-3d-demos-2.0.1.jar" />
+		<pathelement location="lib/jung-algorithms-2.0.1.jar" />
+		<pathelement location="lib/jung-api-2.0.1.jar" />
+		<pathelement location="lib/jung-graph-impl-2.0.1.jar" />
+		<pathelement location="lib/jung-io-2.0.1.jar" />
+		<pathelement location="lib/jung-jai-2.0.1.jar" />
+		<pathelement location="lib/jung-jai-samples-2.0.1.jar" />
+		<pathelement location="lib/jung-samples-2.0.1.jar" />
+		<pathelement location="lib/jung-visualization-2.0.1.jar" />
+		<pathelement location="lib/stax-api-1.0.1.jar" />
+		<pathelement location="lib/vecmath-1.3.1.jar" />
+		<pathelement location="lib/wstx-asl-3.2.6.jar" />
+		<pathelement location="lib/commons-codec-1.5.jar" />
+		<pathelement location="lib/collections-generic-4.01.jar" />
+		<path refid="JavaHelperLib.classpath" />
+	</path>
+
+	<!-- JavaHelperLib Properties -->
+	<property name="build.location.javahelperlib" value="${build.location}/javahelperlib" />
+	<property name="JavaHelperLib.jarname" value="javahelperlib.jar" />
+	<property name="JavaHelperLib.location" value="../JavaHelperLib" />
+	<path id="JavaHelperLib.classpath">
+		<pathelement location="${build.location.javahelperlib}" />
+	</path>
+
+	<!-- JFCMonitor Properties -->
+	<property name="build.location.jfcmonitor" value="${build.location}/jfcmonitor" />
+	<property name="JFCMonitor.jarname" value="jfcmonitor.jar" />
+	<property name="JFCMonitor.location" value="../JFCMonitor" />
+	<path id="JFCMonitor.classpath">
+		<pathelement location="${build.location.jfcmonitor}" />
+		<path refid="JavaHelperLib.classpath" />
+	</path>
+
+	<!-- Emma Configuration -->
+	<property name="coverage.location" value="coverage" />
+	<property name="coverage.instrumented" value="inst" />
+	<property name="coverage.instrumented.javahelperlib" value="${coverage.instrumented}/javahelperlib" />
+	<property name="coverage.instrumented.eventbenchcore" value="${coverage.instrumented}/eventbenchcore" />
+	<property name="coverage.instrumented.eventbenchconsole" value="${coverage.instrumented}/eventbenchconsole" />
+	<path id="emma.classpath">
+		<pathelement location="lib-test/emma.jar" />
+		<pathelement location="lib-test/emma_ant.jar" />
+	</path>
+
+	<taskdef resource="emma_ant.properties" classpathref="emma.classpath" />
+
+	<!-- JUnit Test General Properties -->
+	<property name="test.location.results" value="test-results" />
+	<property name="test.location.data" value="testdata" />
+	<property name="test.location.output" value="testoutput" />
+	<path id="JUnit.classpath">
+		<pathelement location="lib-test/junit-4.10.jar" />
+		<pathelement location="lib-test/junit-addons-1.4.jar" />
+		<pathelement location="lib-test/cglib-nodep.jar" />
+		<pathelement location="lib-test/objenesis.jar" />
+		<pathelement location="lib-test/EqualsVerifier-1.0.2.jar" />
+	</path>
+
+	<!-- JUnit Test EventBenchConsole Properties -->
+	<property name="test.location.eventbenchconsole" value="${build.location}/eventbenchconsole-test" />
+	<property name="EventBenchConsoleTest.location" value="../EventBenchConsoleTest" />
+	<property name="test.eventbenchconsole.main-class" value="de.ugoe.cs.eventbench.jfc.TestAll" />
+	<property name="test.eventbenchconsole.results" value="${test.location.results}/eventbenchconsole" />
+	<path id="EventBenchConsoleJUnitCompile.classpath">
+		<pathelement location="${test.location.eventbenchconsole}" />
+		<path refid="EventBenchConsole.classpath" />
+		<path refid="EventBenchCore.classpath" />
+		<path refid="JUnit.classpath" />
+	</path>
+	<path id="EventBenchConsoleJUnitExecute.classpath">
+		<pathelement location="${coverage.instrumented.eventbenchconsole}" />
+		<path refid="EventBenchConsoleJUnitCompile.classpath" />
+		<path refid="emma.classpath" />
+	</path>
+	
+	<!-- JUnit Test EventBenchCore Properties -->
+	<property name="test.location.eventbenchcore" value="${build.location}/eventbenchcore-test" />
+	<property name="EventBenchCoreTest.location" value="../EventBenchCoreTest" />
+	<property name="test.eventbenchcore.main-class" value="de.ugoe.cs.eventbench.TestAll" />
+	<property name="test.eventbenchcore.results" value="${test.location.results}/eventbenchcore" />
+	<path id="EventBenchCoreJUnitCompile.classpath">
+		<pathelement location="${test.location.eventbenchcore}" />
+		<path refid="EventBenchCore.classpath" />
+		<path refid="JUnit.classpath" />
+	</path>
+	<path id="EventBenchCoreJUnitExecute.classpath">
+		<pathelement location="${coverage.instrumented.eventbenchcore}" />
+		<path refid="EventBenchCoreJUnitCompile.classpath" />
+		<path refid="emma.classpath" />
+	</path>
+
+	<!-- JUnit Test JavaHelperLib Properties -->
+	<property name="test.location.javahelperlib" value="${build.location}/javahelperlib-test" />
+	<property name="JavaHelperLibTest.location" value="../JavaHelperLibTest" />
+	<property name="test.javahelperlib.main-class" value="de.ugoe.cs.util.TestAll" />
+	<property name="test.javahelperlib.results" value="${test.location.results}/javahelperlib" />
+	<path id="JavaHelperLibJUnitCompile.classpath">
+		<pathelement location="${test.location.javahelperlib}" />
+		<path refid="JavaHelperLib.classpath" />
+		<path refid="JUnit.classpath" />
+	</path>
+	<path id="JavaHelperLibJUnitExecute.classpath">
+		<pathelement location="${coverage.instrumented.javahelperlib}" />
+		<path refid="JavaHelperLibJUnitCompile.classpath" />
+		<path refid="emma.classpath" />
+	</path>
+
+	<!-- FindBugs Properties -->
+	<property name="findbugs.results.location" value="findbugs" />
+	<path id="findbugs.classpath">
+		<pathelement location="lib-test/findbugs-ant.jar" />
+	</path>
+	<taskdef name="findbugs" classname="edu.umd.cs.findbugs.anttask.FindBugsTask"
+		classpathref="findbugs.classpath" />
+
+	<!-- Initialization Targets -->
+	<target name="init.build">
+		<mkdir dir="${build.location}" />
+	</target>
+	<target name="init.dist">
+		<mkdir dir="${dist.location}" />
+		<mkdir dir="${dist.location.main}" />
+		<mkdir dir="${dist.location.jfcmonitor}" />
+	</target>
+	<target name="init.downloads">
+		<mkdir dir="${downloads.location}" />
+	</target>
+	<target name="init.javadoc">
+		<mkdir dir="${javadoc.location}" />
+	</target>
+	<target depends="init.build" name="init.eventbenchconsole">
+		<mkdir dir="${build.location.eventbenchconsole}" />
+	</target>
+	<target depends="init.build" name="init.eventbenchcore">
+		<mkdir dir="${build.location.eventbenchcore}" />
+	</target>
+	<target depends="init.build" name="init.javahelperlib">
+		<mkdir dir="${build.location.javahelperlib}" />
+	</target>
+	<target depends="init.build" name="init.jfcmonitor">
+		<mkdir dir="${build.location.jfcmonitor}" />
+	</target>
+	<target depends="init.build" name="init.junit">
+		<mkdir dir="${test.location.results}" />
+		<mkdir dir="${test.location.data}" />
+		<mkdir dir="${test.location.output}" />
+	</target>
+	<target depends="init.junit" name="init.eventbenchconsole-test">
+		<mkdir dir="${test.location.eventbenchconsole}" />
+	</target>
+	<target depends="init.junit" name="init.eventbenchcore-test">
+		<mkdir dir="${test.location.eventbenchcore}" />
+	</target>
+	<target depends="init.junit" name="init.javahelperlib-test">
+		<mkdir dir="${test.location.javahelperlib}" />
+		<copy includeemptydirs="true" todir="${test.location.data}">
+			<fileset dir="${JavaHelperLibTest.location}/testdata" />
+		</copy>
+	</target>
+	<target name="init.emma">
+		<mkdir dir="${coverage.instrumented}" />
+		<mkdir dir="${coverage.location}" />
+	</target>
+	<target name="init.findbugs">
+		<mkdir dir="${findbugs.results.location}" />
+	</target>
+
+	<!-- Clean-up Targets -->
+	<target name="clean.build">
+		<delete dir="${build.location}" />
+	</target>
+	<target name="clean.dist">
+		<delete dir="${dist.location}" />
+	</target>
+	<target name="clean.javadoc">
+		<delete dir="${javadoc.location}" />
+	</target>
+	<target name="clean.junit">
+		<delete dir="${test.location.results}" />
+		<delete dir="${test.location.data}" />
+		<delete dir="${test.location.output}" />
+	</target>
+	<target name="clean.emma">
+		<delete dir="${coverage.instrumented}" />
+	</target>
+	<target name="clean.findbugs">
+		<delete dir="${findbugs.results.location}" />
+	</target>
+	<target depends="clean.build,clean.dist,clean.javadoc,clean.junit,clean.emma,clean.findbugs"
+		name="clean.all" />
+
+	<!-- Build Targets -->
+	<target
+		depends="build.javahelperlib,build.eventbenchcore,build.eventbenchconsole,build.jfcmonitor"
+		name="build" />
+	<target depends="init.eventbenchconsole" name="build.eventbenchconsole">
+		<javac debug="true" debuglevel="${debuglevel}"
+			destdir="${build.location.eventbenchconsole}" source="${source}"
+			target="${target}" includeantruntime="false">
+			<src path="${EventBenchConsole.location}/src" />
+			<classpath refid="EventBenchConsole.classpath" />
+		</javac>
+	</target>
+	<target depends="init.eventbenchcore" name="build.eventbenchcore">
+		<javac debug="true" debuglevel="${debuglevel}"
+			destdir="${build.location.eventbenchcore}" source="${source}" target="${target}"
+			includeantruntime="false">
+			<src path="${EventBenchCore.location}/src" />
+			<classpath refid="EventBenchCore.classpath" />
+		</javac>
+	</target>
+	<target depends="init.javahelperlib" name="build.javahelperlib">
+		<javac debug="true" debuglevel="${debuglevel}" destdir="${build.location.javahelperlib}"
+			source="${source}" target="${target}" includeantruntime="false">
+			<src path="${JavaHelperLib.location}/src" />
+			<classpath refid="JavaHelperLib.classpath" />
+		</javac>
+	</target>
+	<target depends="init.jfcmonitor" name="build.jfcmonitor">
+		<javac debug="true" debuglevel="${debuglevel}" destdir="${build.location.jfcmonitor}"
+			source="${source}" target="${target}" includeantruntime="false">
+			<src path="${JFCMonitor.location}/src" />
+			<classpath refid="JFCMonitor.classpath" />
+		</javac>
+	</target>
+
+	<!-- Distribution Targets -->
+	<target depends="build,init.dist,javadoc" name="dist">
+		<!-- dist of main components, i.e., the console -->
+		<pathconvert property="dist.libs" pathsep=" ">
+			<mapper>
+				<chainedmapper>
+					<flattenmapper />
+					<globmapper from="*" to="lib/*" />
+				</chainedmapper>
+			</mapper>
+			<path>
+				<fileset dir="lib">
+					<include name="**/*.jar" />
+				</fileset>
+			</path>
+		</pathconvert>
+		<property name="dist.classpath"
+			value="${dist.libs} ${JavaHelperLib.jarname} ${EventBenchCore.jarname}"></property>
+		<jar destfile="${dist.location.main}/${EventBenchConsole.jarname}"
+			basedir="${build.location.eventbenchconsole}">
+			<manifest>
+				<attribute name="Built-By" value="${user.name}" />
+				<attribute name="Main-Class" value="de.ugoe.cs.eventbench.Runner" />
+				<attribute name="Class-Path" value="${dist.classpath}" />
+			</manifest>
+		</jar>
+		<jar destfile="${dist.location.main}/${EventBenchCore.jarname}"
+			basedir="${build.location.eventbenchcore}">
+			<manifest>
+				<attribute name="Built-By" value="${user.name}" />
+			</manifest>
+		</jar>
+		<jar destfile="${dist.location.main}/${JavaHelperLib.jarname}"
+			basedir="${build.location.javahelperlib}">
+			<manifest>
+				<attribute name="Built-By" value="${user.name}" />
+				<attribute name="Class-Path" value="${dist.classpath}" />
+			</manifest>
+		</jar>
+		<copy includeemptydirs="false" todir="${dist.location.main}/lib">
+			<fileset dir="lib" />
+		</copy>
+		<copy todir="${dist.location.main}/misc">
+			<fileset dir="${EventBenchConsole.location}/misc" />
+		</copy>
+		<copy todir="${dist.location.main}/rules">
+			<fileset dir="${EventBenchConsole.location}/rules" />
+		</copy>
+
+		<!-- dist of JFCMonitor -->
+		<jar destfile="${dist.location.jfcmonitor}/${JFCMonitor.jarname}"
+			basedir="${build.location.jfcmonitor}">
+			<manifest>
+				<attribute name="Built-By" value="${user.name}" />
+				<attribute name="Main-Class" value="de.ugoe.cs.eventbench.jfcmonitor.Runner" />
+				<attribute name="Class-Path" value="${JavaHelperLib.jarname}" />
+			</manifest>
+		</jar>
+		<copy todir="${dist.location.jfcmonitor}">
+			<fileset file="${dist.location.main}/${JavaHelperLib.jarname}"/>
+		</copy>
+
+		<!-- copy Javadoc to dist -->
+		<copy includeemptydirs="false" todir="${dist.location.javadoc}">
+			<fileset dir="${javadoc.location}" />
+		</copy>
+	</target>
+
+
+	<target depends="init.downloads,dist" name="createDownloads">
+		<zip destfile="${downloads.location}/eventbench-complete.zip">
+			<fileset dir="${dist.location}" />
+		</zip>
+		<zip destfile="${downloads.location}/eventbench-console.zip">
+			<fileset dir="${dist.location.main}" />
+		</zip>
+		<zip destfile="${downloads.location}/eventbench-jfcmonitor.zip">
+			<fileset dir="${dist.location.jfcmonitor}" />
+		</zip>
+		<zip destfile="${downloads.location}/eventbench-javadoc.zip">
+			<fileset dir="${dist.location.javadoc}" />
+		</zip>
+	</target>
+
+	<!-- Javadoc Targets -->
+	<target depends="init.javadoc" name="javadoc"
+		description="o Create Javadocs (Requires Javadoc 1.4+)">
+		<javadoc destdir="${javadoc.location}"
+			additionalparam="-J-Dorg.apache.commons.attributes.javadoc.CATaglet.sources=${basedir}">
+			<classpath refid="JavaHelperLib.classpath" />
+			<classpath refid="EventBenchCore.classpath" />
+			<classpath refid="EventBenchConsole.classpath" />
+			<classpath refid="JFCMonitor.classpath" />
+			<link href="http://download.oracle.com/javase/6/docs/api/" />
+			<fileset dir="${JavaHelperLib.location}/src" includes="**/*.java" />
+			<fileset dir="${EventBenchCore.location}/src" includes="**/*.java" />
+			<fileset dir="${EventBenchConsole.location}/src" includes="**/*.java" />
+			<fileset dir="${JFCMonitor.location}/src" includes="**/*.java" />
+		</javadoc>
+	</target>
+
+	<!-- JUnit Targets -->
+	<target depends="init.eventbenchconsole-test, emma.instrument.eventbenchconsole"
+		name="build.eventbenchconsole-test">
+		<javac debug="true" debuglevel="${debuglevel}" destdir="${test.location.eventbenchconsole}"
+			source="${source}" target="${target}" includeantruntime="false">
+			<src path="${EventBenchConsoleTest.location}/src" />
+			<classpath refid="EventBenchConsoleJUnitCompile.classpath" />
+		</javac>
+	</target>
+	<target depends="init.eventbenchcore-test, emma.instrument.eventbenchcore"
+		name="build.eventbenchcore-test">
+		<javac debug="true" debuglevel="${debuglevel}" destdir="${test.location.eventbenchcore}"
+			source="${source}" target="${target}" includeantruntime="false">
+			<src path="${EventBenchCoreTest.location}/src" />
+			<classpath refid="EventBenchCoreJUnitCompile.classpath" />
+		</javac>
+	</target>
+	<target depends="init.javahelperlib-test, emma.instrument.javahelperlib"
+		name="build.javahelperlib-test">
+		<javac debug="true" debuglevel="${debuglevel}" destdir="${test.location.javahelperlib}"
+			source="${source}" target="${target}" includeantruntime="false">
+			<src path="${JavaHelperLibTest.location}/src" />
+			<classpath refid="JavaHelperLibJUnitCompile.classpath" />
+		</javac>
+	</target>
+
+	<target depends="emma.instrument.eventbenchconsole,build.eventbenchconsole-test"
+			name="junit.eventbenchconsole">
+			<junit fork="on" printsummary="yes" haltonfailure="no">
+				<classpath refid="EventBenchConsoleJUnitExecute.classpath" />
+				<test name="${test.eventbenchconsole.main-class}" haltonfailure="no"
+					outfile="${test.eventbenchconsole.results}">
+					<formatter type="xml" />
+				</test>
+				<jvmarg
+					value="-Demma.coverage.out.file=${coverage.location}/eventbenchconsole.emma" />
+				<jvmarg value="-Demma.coverage.out.merge=true" />
+			</junit>
+		</target>
+	<target depends="emma.instrument.eventbenchcore,build.eventbenchcore-test"
+		name="junit.eventbenchcore">
+		<junit fork="on" printsummary="yes" haltonfailure="no">
+			<classpath refid="EventBenchCoreJUnitExecute.classpath" />
+			<test name="${test.eventbenchcore.main-class}" haltonfailure="no"
+				outfile="${test.eventbenchcore.results}">
+				<formatter type="xml" />
+			</test>
+			<jvmarg
+				value="-Demma.coverage.out.file=${coverage.location}/eventbenchcore.emma" />
+			<jvmarg value="-Demma.coverage.out.merge=true" />
+		</junit>
+	</target>
+	<target depends="emma.instrument.javahelperlib,build.javahelperlib-test"
+		name="junit.javahelperlib">
+		<junit fork="on" printsummary="yes" haltonfailure="no">
+			<classpath refid="JavaHelperLibJUnitExecute.classpath" />
+			<test name="${test.javahelperlib.main-class}" haltonfailure="no"
+				outfile="${test.javahelperlib.results}">
+				<formatter type="xml" />
+			</test>
+			<jvmarg
+				value="-Demma.coverage.out.file=${coverage.location}/javahelperlib.emma" />
+			<jvmarg value="-Demma.coverage.out.merge=true" />
+		</junit>
+	</target>
+
+	<target depends="junit.javahelperlib,junit.eventbenchcore,junit.eventbenchconsole" name="junit" />
+
+	<!-- Emma Targets -->
+	<target depends="build.javahelperlib, init.emma" name="emma.instrument.javahelperlib">
+		<emma enabled="true">
+			<instr instrpath="${build.location.javahelperlib}" destdir="${coverage.instrumented.javahelperlib}"
+				metadatafile="${coverage.location}/javahelperlib.emma" merge="true" />
+		</emma>
+	</target>
+	<target depends="build.eventbenchcore, init.emma" name="emma.instrument.eventbenchcore">
+		<emma enabled="true">
+			<instr instrpath="${build.location.eventbenchcore}" destdir="${coverage.instrumented.eventbenchcore}"
+				metadatafile="${coverage.location}/eventbenchcore.emma" merge="true" />
+		</emma>
+	</target>
+	<target depends="build.eventbenchconsole, init.emma" name="emma.instrument.eventbenchconsole">
+			<emma enabled="true">
+				<instr instrpath="${build.location.eventbenchconsole}" destdir="${coverage.instrumented.eventbenchconsole}"
+					metadatafile="${coverage.location}/eventbenchconsole.emma" merge="true" />
+			</emma>
+		</target>
+	<target depends="junit" name="emma.report">
+		<emma enabled="true">
+			<report sourcepath="${JavaHelperLib.location}">
+				<fileset dir="${coverage.location}">
+					<include name="*.emma" />
+				</fileset>
+				<xml outfile="${coverage.location}/coverage.xml" depth="method" />
+			</report>
+		</emma>
+	</target>
+
+	<!-- FindBugs Targets -->
+	<target depends="dist" name="findbugs.javahelperlib">
+		<mkdir dir="${findbugs.results.location}" />
+		<findbugs home="lib-test" output="xml"
+			outputFile="${findbugs.results.location}/findbugs-javahelperlib.xml">
+			<auxClasspath refid="JavaHelperLib.classpath" />
+			<sourcePath path="${JavaHelperLib.location}" />
+			<class location="${dist.location.main}/${JavaHelperLib.jarname}" />
+		</findbugs>
+	</target>
+	<target depends="dist" name="findbugs.eventbenchcore">
+		<mkdir dir="${findbugs.results.location}" />
+		<findbugs home="lib-test" output="xml"
+			outputFile="${findbugs.results.location}/findbugs-eventbenchcore.xml">
+			<auxClasspath refid="EventBenchCore.classpath" />
+			<sourcePath path="${EventBenchCore.location}" />
+			<class location="${dist.location.main}/${EventBenchCore.jarname}" />
+		</findbugs>
+	</target>
+	<target depends="dist" name="findbugs.eventbenchconsole">
+		<mkdir dir="${findbugs.results.location}" />
+		<findbugs home="lib-test" output="xml"
+			outputFile="${findbugs.results.location}/findbugs-eventbenchconsole.xml">
+			<auxClasspath refid="EventBenchConsole.classpath" />
+			<sourcePath path="${EventBenchConsole.location}" />
+			<class location="${dist.location.main}/${EventBenchConsole.jarname}" />
+		</findbugs>
+	</target>
+	<target depends="dist" name="findbugs.jfcmonitor">
+		<mkdir dir="${findbugs.results.location}" />
+		<findbugs home="lib-test" output="xml"
+			outputFile="${findbugs.results.location}/findbugs-jfcmonitor.xml">
+			<auxClasspath refid="JFCMonitor.classpath" />
+			<sourcePath path="${JFCMonitor.location}" />
+			<class location="${dist.location.jfcmonitor}/${JFCMonitor.jarname}" />
+		</findbugs>
+	</target>
+	<target depends="findbugs.javahelperlib,findbugs.eventbenchcore,findbugs.eventbenchconsole,findbugs.jfcmonitor" name="findbugs" />
+</project>
Index: /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/ChildFrm.cpp
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/ChildFrm.cpp	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/ChildFrm.cpp	(revision 540)
@@ -0,0 +1,59 @@
+// ChildFrm.cpp : implementation of the CChildFrame class
+//
+#include "stdafx.h"
+#include "TestProg.h"
+
+#include "ChildFrm.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+// CChildFrame
+
+IMPLEMENT_DYNCREATE(CChildFrame, CMDIChildWnd)
+
+BEGIN_MESSAGE_MAP(CChildFrame, CMDIChildWnd)
+END_MESSAGE_MAP()
+
+
+// CChildFrame construction/destruction
+
+CChildFrame::CChildFrame()
+{
+	// TODO: add member initialization code here
+}
+
+CChildFrame::~CChildFrame()
+{
+}
+
+
+BOOL CChildFrame::PreCreateWindow(CREATESTRUCT& cs)
+{
+	// TODO: Modify the Window class or styles here by modifying the CREATESTRUCT cs
+	if( !CMDIChildWnd::PreCreateWindow(cs) )
+		return FALSE;
+
+	return TRUE;
+}
+
+
+// CChildFrame diagnostics
+
+#ifdef _DEBUG
+void CChildFrame::AssertValid() const
+{
+	CMDIChildWnd::AssertValid();
+}
+
+void CChildFrame::Dump(CDumpContext& dc) const
+{
+	CMDIChildWnd::Dump(dc);
+}
+
+#endif //_DEBUG
+
+
+// CChildFrame message handlers
Index: /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/ChildFrm.h
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/ChildFrm.h	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/ChildFrm.h	(revision 540)
@@ -0,0 +1,34 @@
+// ChildFrm.h : interface of the CChildFrame class
+//
+
+
+#pragma once
+
+
+class CChildFrame : public CMDIChildWnd
+{
+	DECLARE_DYNCREATE(CChildFrame)
+public:
+	CChildFrame();
+
+// Attributes
+public:
+
+// Operations
+public:
+
+// Overrides
+	virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
+
+// Implementation
+public:
+	virtual ~CChildFrame();
+#ifdef _DEBUG
+	virtual void AssertValid() const;
+	virtual void Dump(CDumpContext& dc) const;
+#endif
+
+// Generated message map functions
+protected:
+	DECLARE_MESSAGE_MAP()
+};
Index: /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/CntrItem.cpp
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/CntrItem.cpp	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/CntrItem.cpp	(revision 540)
@@ -0,0 +1,181 @@
+// CntrItem.cpp : implementation of the CTestProgCntrItem class
+//
+
+#include "stdafx.h"
+#include "TestProg.h"
+
+#include "TestProgDoc.h"
+#include "TestProgView.h"
+#include "CntrItem.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+// CTestProgCntrItem implementation
+
+IMPLEMENT_SERIAL(CTestProgCntrItem, COleClientItem, 0)
+
+CTestProgCntrItem::CTestProgCntrItem(CTestProgDoc* pContainer)
+	: COleClientItem(pContainer)
+{
+	// TODO: add one-time construction code here
+}
+
+CTestProgCntrItem::~CTestProgCntrItem()
+{
+	// TODO: add cleanup code here
+}
+
+void CTestProgCntrItem::OnChange(OLE_NOTIFICATION nCode, DWORD dwParam)
+{
+	ASSERT_VALID(this);
+
+	COleClientItem::OnChange(nCode, dwParam);
+
+	// When an item is being edited (either in-place or fully open)
+	//  it sends OnChange notifications for changes in the state of the
+	//  item or visual appearance of its content.
+
+	// TODO: invalidate the item by calling UpdateAllViews
+	//  (with hints appropriate to your application)
+
+	GetDocument()->UpdateAllViews(NULL);
+		// for now just update ALL views/no hints
+}
+
+BOOL CTestProgCntrItem::OnChangeItemPosition(const CRect& rectPos)
+{
+	ASSERT_VALID(this);
+
+	// During in-place activation CTestProgCntrItem::OnChangeItemPosition
+	//  is called by the server to change the position of the in-place
+	//  window.  Usually, this is a result of the data in the server
+	//  document changing such that the extent has changed or as a result
+	//  of in-place resizing.
+	//
+	// The default here is to call the base class, which will call
+	//  COleClientItem::SetItemRects to move the item
+	//  to the new position.
+
+	if (!COleClientItem::OnChangeItemPosition(rectPos))
+		return FALSE;
+
+	// TODO: update any cache you may have of the item's rectangle/extent
+
+	return TRUE;
+}
+
+void CTestProgCntrItem::OnGetItemPosition(CRect& rPosition)
+{
+	ASSERT_VALID(this);
+
+	// During in-place activation, CTestProgCntrItem::OnGetItemPosition
+	//  will be called to determine the location of this item.  Usually, this 
+	//  rectangle would reflect the current position of the item relative to the 
+	//  view used for activation.  You can obtain the view by calling 
+	//  CTestProgCntrItem::GetActiveView.
+
+	// TODO: return correct rectangle (in pixels) in rPosition
+
+	CSize size;
+	rPosition.SetRectEmpty();
+	if (GetExtent(&size, m_nDrawAspect))
+	{
+		CTestProgView* pView = GetActiveView();
+		ASSERT_VALID(pView);
+		if (!pView)
+			return;
+		CDC *pDC = pView->GetDC();
+		ASSERT(pDC);
+		if (!pDC)
+			return;
+		pDC->HIMETRICtoLP(&size);
+		rPosition.SetRect(10, 10, size.cx + 10, size.cy + 10);
+	}
+	else
+		rPosition.SetRect(10, 10, 210, 210);
+}
+
+void CTestProgCntrItem::OnActivate()
+{
+    // Allow only one inplace activate item per frame
+    CTestProgView* pView = GetActiveView();
+    ASSERT_VALID(pView);
+	if (!pView)
+		return;
+    COleClientItem* pItem = GetDocument()->GetInPlaceActiveItem(pView);
+    if (pItem != NULL && pItem != this)
+        pItem->Close();
+    
+    COleClientItem::OnActivate();
+}
+
+void CTestProgCntrItem::OnDeactivateUI(BOOL bUndoable)
+{
+	COleClientItem::OnDeactivateUI(bUndoable);
+
+    DWORD dwMisc = 0;
+    m_lpObject->GetMiscStatus(GetDrawAspect(), &dwMisc);
+    if (dwMisc & OLEMISC_INSIDEOUT)
+        DoVerb(OLEIVERB_HIDE, NULL);
+}
+
+void CTestProgCntrItem::Serialize(CArchive& ar)
+{
+	ASSERT_VALID(this);
+
+	// Call base class first to read in COleClientItem data.
+	// Since this sets up the m_pDocument pointer returned from
+	//  CTestProgCntrItem::GetDocument, it is a good idea to call
+	//  the base class Serialize first.
+	COleClientItem::Serialize(ar);
+
+	// now store/retrieve data specific to CTestProgCntrItem
+	if (ar.IsStoring())
+	{
+		// TODO: add storing code here
+	}
+	else
+	{
+		// TODO: add loading code here
+	}
+}
+
+BOOL CTestProgCntrItem::CanActivate()
+{
+	// Editing in-place while the server itself is being edited in-place
+	//  does not work and is not supported.  So, disable in-place
+	//  activation in this case.
+	CTestProgDoc* pDoc = GetDocument();
+	ASSERT_VALID(pDoc);
+	if (!pDoc)
+		return FALSE;
+	ASSERT_KINDOF(COleServerDoc, pDoc);
+	if (!pDoc->IsKindOf(RUNTIME_CLASS(COleServerDoc)))
+	{
+		return FALSE;
+	}
+	if (pDoc->IsInPlaceActive())
+		return FALSE;
+
+	// otherwise, rely on default behavior
+	return COleClientItem::CanActivate();
+}
+
+
+// CTestProgCntrItem diagnostics
+
+#ifdef _DEBUG
+void CTestProgCntrItem::AssertValid() const
+{
+	COleClientItem::AssertValid();
+}
+
+void CTestProgCntrItem::Dump(CDumpContext& dc) const
+{
+	COleClientItem::Dump(dc);
+}
+#endif
+
Index: /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/CntrItem.h
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/CntrItem.h	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/CntrItem.h	(revision 540)
@@ -0,0 +1,46 @@
+// CntrItem.h : interface of the CTestProgCntrItem class
+//
+
+#pragma once
+
+class CTestProgDoc;
+class CTestProgView;
+
+class CTestProgCntrItem : public COleClientItem
+{
+	DECLARE_SERIAL(CTestProgCntrItem)
+
+// Constructors
+public:
+	CTestProgCntrItem(CTestProgDoc* pContainer = NULL);
+		// Note: pContainer is allowed to be NULL to enable IMPLEMENT_SERIALIZE
+		//  IMPLEMENT_SERIALIZE requires the class have a constructor with
+		//  zero arguments.  Normally, OLE items are constructed with a
+		//  non-NULL document pointer
+
+// Attributes
+public:
+	CTestProgDoc* GetDocument()
+		{ return reinterpret_cast<CTestProgDoc*>(COleClientItem::GetDocument()); }
+	CTestProgView* GetActiveView()
+		{ return reinterpret_cast<CTestProgView*>(COleClientItem::GetActiveView()); }
+
+	public:
+	virtual void OnChange(OLE_NOTIFICATION wNotification, DWORD dwParam);
+	virtual void OnActivate();
+	protected:
+	virtual void OnGetItemPosition(CRect& rPosition);
+	virtual void OnDeactivateUI(BOOL bUndoable);
+	virtual BOOL OnChangeItemPosition(const CRect& rectPos);
+	virtual BOOL CanActivate();
+
+// Implementation
+public:
+	~CTestProgCntrItem();
+#ifdef _DEBUG
+	virtual void AssertValid() const;
+	virtual void Dump(CDumpContext& dc) const;
+#endif
+	virtual void Serialize(CArchive& ar);
+};
+
Index: /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/IpFrame.cpp
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/IpFrame.cpp	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/IpFrame.cpp	(revision 540)
@@ -0,0 +1,106 @@
+// IpFrame.cpp : implementation of the CInPlaceFrame class
+//
+
+#include "stdafx.h"
+#include "TestProg.h"
+
+#include "IpFrame.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+// CInPlaceFrame
+
+IMPLEMENT_DYNCREATE(CInPlaceFrame, COleIPFrameWnd)
+
+BEGIN_MESSAGE_MAP(CInPlaceFrame, COleIPFrameWnd)
+	ON_WM_CREATE()
+END_MESSAGE_MAP()
+
+
+// CInPlaceFrame construction/destruction
+
+CInPlaceFrame::CInPlaceFrame()
+{
+}
+
+CInPlaceFrame::~CInPlaceFrame()
+{
+}
+
+int CInPlaceFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
+{
+	if (COleIPFrameWnd::OnCreate(lpCreateStruct) == -1)
+		return -1;
+
+	// CResizeBar implements in-place resizing.
+	if (!m_wndResizeBar.Create(this))
+	{
+		TRACE0("Failed to create resize bar\n");
+		return -1;      // fail to create
+	}
+
+	// By default, it is a good idea to register a drop-target that does
+	//  nothing with your frame window.  This prevents drops from
+	//  "falling through" to a container that supports drag-drop.
+	m_dropTarget.Register(this);
+
+	return 0;
+}
+
+// OnCreateControlBars is called by the framework to create control bars on the
+//  container application's windows.  pWndFrame is the top level frame window of
+//  the container and is always non-NULL.  pWndDoc is the doc level frame window
+//  and will be NULL when the container is an SDI application.  A server
+//  application can place MFC control bars on either window.
+BOOL CInPlaceFrame::OnCreateControlBars(CFrameWnd* pWndFrame, CFrameWnd* pWndDoc)
+{
+	// Remove this if you use pWndDoc
+	UNREFERENCED_PARAMETER(pWndDoc);
+
+	// Set owner to this window, so messages are delivered to correct app
+	m_wndToolBar.SetOwner(this);
+
+	// Create toolbar on client's frame window
+	if (!m_wndToolBar.CreateEx(pWndFrame, TBSTYLE_FLAT,WS_CHILD | WS_VISIBLE | CBRS_TOP
+		| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
+		!m_wndToolBar.LoadToolBar(IDR_TestProgTYPE_SRVR_IP))
+	{
+		TRACE0("Failed to create toolbar\n");
+		return FALSE;
+	}
+
+	// TODO: Delete these three lines if you don't want the toolbar to be dockable
+	m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
+	pWndFrame->EnableDocking(CBRS_ALIGN_ANY);
+	pWndFrame->DockControlBar(&m_wndToolBar);
+
+	return TRUE;
+}
+
+BOOL CInPlaceFrame::PreCreateWindow(CREATESTRUCT& cs)
+{
+	// TODO: Modify the Window class or styles here by modifying the CREATESTRUCT cs
+
+	return COleIPFrameWnd::PreCreateWindow(cs);
+}
+
+
+// CInPlaceFrame diagnostics
+
+#ifdef _DEBUG
+void CInPlaceFrame::AssertValid() const
+{
+	COleIPFrameWnd::AssertValid();
+}
+
+void CInPlaceFrame::Dump(CDumpContext& dc) const
+{
+	COleIPFrameWnd::Dump(dc);
+}
+#endif //_DEBUG
+
+
+// CInPlaceFrame commands
Index: /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/IpFrame.h
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/IpFrame.h	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/IpFrame.h	(revision 540)
@@ -0,0 +1,41 @@
+// IpFrame.h : interface of the CInPlaceFrame class
+//
+
+#pragma once
+
+class CInPlaceFrame : public COleIPFrameWnd
+{
+	DECLARE_DYNCREATE(CInPlaceFrame)
+public:
+	CInPlaceFrame();
+
+// Attributes
+public:
+
+// Operations
+public:
+
+// Overrides
+	public:
+	virtual BOOL OnCreateControlBars(CFrameWnd* pWndFrame, CFrameWnd* pWndDoc);
+	virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
+
+// Implementation
+public:
+	virtual ~CInPlaceFrame();
+#ifdef _DEBUG
+	virtual void AssertValid() const;
+	virtual void Dump(CDumpContext& dc) const;
+#endif
+
+protected:
+	CToolBar    m_wndToolBar;
+	COleDropTarget	m_dropTarget;
+	COleResizeBar   m_wndResizeBar;
+
+// Generated message map functions
+protected:
+	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
+	DECLARE_MESSAGE_MAP()
+};
+
Index: /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/MainFrm.cpp
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/MainFrm.cpp	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/MainFrm.cpp	(revision 540)
@@ -0,0 +1,102 @@
+// MainFrm.cpp : implementation of the CMainFrame class
+//
+
+#include "stdafx.h"
+#include "TestProg.h"
+
+#include "MainFrm.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+// CMainFrame
+
+IMPLEMENT_DYNAMIC(CMainFrame, CMDIFrameWnd)
+
+BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
+	ON_WM_CREATE()
+END_MESSAGE_MAP()
+
+static UINT indicators[] =
+{
+	ID_SEPARATOR,           // status line indicator
+	ID_INDICATOR_CAPS,
+	ID_INDICATOR_NUM,
+	ID_INDICATOR_SCRL,
+};
+
+
+// CMainFrame construction/destruction
+
+CMainFrame::CMainFrame()
+{
+	// TODO: add member initialization code here
+}
+
+CMainFrame::~CMainFrame()
+{
+}
+
+
+int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
+{
+	if (CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
+		return -1;
+	
+	if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
+		| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
+		!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
+	{
+		TRACE0("Failed to create toolbar\n");
+		return -1;      // fail to create
+	}
+
+	if (!m_wndStatusBar.Create(this) ||
+		!m_wndStatusBar.SetIndicators(indicators,
+		  sizeof(indicators)/sizeof(UINT)))
+	{
+		TRACE0("Failed to create status bar\n");
+		return -1;      // fail to create
+	}
+
+	// TODO: Delete these three lines if you don't want the toolbar to be dockable
+	m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
+	EnableDocking(CBRS_ALIGN_ANY);
+	DockControlBar(&m_wndToolBar);
+
+	return 0;
+}
+
+BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
+{
+	if( !CMDIFrameWnd::PreCreateWindow(cs) )
+		return FALSE;
+	// TODO: Modify the Window class or styles here by modifying
+	//  the CREATESTRUCT cs
+
+	return TRUE;
+}
+
+
+// CMainFrame diagnostics
+
+#ifdef _DEBUG
+void CMainFrame::AssertValid() const
+{
+	CMDIFrameWnd::AssertValid();
+}
+
+void CMainFrame::Dump(CDumpContext& dc) const
+{
+	CMDIFrameWnd::Dump(dc);
+}
+
+#endif //_DEBUG
+
+
+// CMainFrame message handlers
+
+
+
Index: /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/MainFrm.h
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/MainFrm.h	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/MainFrm.h	(revision 540)
@@ -0,0 +1,41 @@
+// MainFrm.h : interface of the CMainFrame class
+//
+
+
+#pragma once
+
+class CMainFrame : public CMDIFrameWnd
+{
+	DECLARE_DYNAMIC(CMainFrame)
+public:
+	CMainFrame();
+
+// Attributes
+public:
+
+// Operations
+public:
+
+// Overrides
+public:
+	virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
+
+// Implementation
+public:
+	virtual ~CMainFrame();
+#ifdef _DEBUG
+	virtual void AssertValid() const;
+	virtual void Dump(CDumpContext& dc) const;
+#endif
+
+protected:  // control bar embedded members
+	CStatusBar  m_wndStatusBar;
+	CToolBar    m_wndToolBar;
+
+// Generated message map functions
+protected:
+	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
+	DECLARE_MESSAGE_MAP()
+};
+
+
Index: /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/ReadMe.txt
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/ReadMe.txt	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/ReadMe.txt	(revision 540)
@@ -0,0 +1,166 @@
+================================================================================
+    MICROSOFT FOUNDATION CLASS LIBRARY : TestProg Project Overview
+===============================================================================
+
+The application wizard has created this TestProg application for
+you.  This application not only demonstrates the basics of using the Microsoft
+Foundation Classes but is also a starting point for writing your application.
+
+This file contains a summary of what you will find in each of the files that
+make up your TestProg application.
+
+TestProg.vcproj
+    This is the main project file for VC++ projects generated using an application wizard.
+    It contains information about the version of Visual C++ that generated the file, and
+    information about the platforms, configurations, and project features selected with the
+    application wizard.
+
+TestProg.h
+    This is the main header file for the application.  It includes other
+    project specific headers (including Resource.h) and declares the
+    CTestProgApp application class.
+
+TestProg.cpp
+    This is the main application source file that contains the application
+    class CTestProgApp.
+
+TestProg.rc
+    This is a listing of all of the Microsoft Windows resources that the
+    program uses.  It includes the icons, bitmaps, and cursors that are stored
+    in the RES subdirectory.  This file can be directly edited in Microsoft
+    Visual C++. Your project resources are in 1033.
+
+res\TestProg.ico
+    This is an icon file, which is used as the application's icon.  This
+    icon is included by the main resource file TestProg.rc.
+
+res\TestProg.rc2
+    This file contains resources that are not edited by Microsoft
+    Visual C++. You should place all resources not editable by
+    the resource editor in this file.
+
+TestProg.reg
+    This is an example .reg file that shows you the kind of registration
+    settings the framework will set for you.  You can use this as a .reg
+    file to go along with your application or just delete it and rely
+    on the default RegisterShellFileTypes registration.
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+For the main frame window:
+    The project includes a standard MFC interface.
+
+MainFrm.h, MainFrm.cpp
+    These files contain the frame class CMainFrame, which is derived from
+    CMDIFrameWnd and controls all MDI frame features.
+
+res\Toolbar.bmp
+    This bitmap file is used to create tiled images for the toolbar.
+    The initial toolbar and status bar are constructed in the CMainFrame
+    class. Edit this toolbar bitmap using the resource editor, and
+    update the IDR_MAINFRAME TOOLBAR array in TestProg.rc to add
+    toolbar buttons.
+
+res\IToolbar.bmp
+    This bitmap file is used to create tiled images for the toolbar
+    when your server application is in-place activated inside another
+    container. This toolbar is constructed in the CInPlaceFrame
+    class. This bitmap is similar to the bitmap in res\Toolbar.bmp
+    except that it has many nonserver commands removed.
+
+/////////////////////////////////////////////////////////////////////////////
+
+For the child frame window:
+
+ChildFrm.h, ChildFrm.cpp
+    These files define and implement the CChildFrame class, which
+    supports the child windows in an MDI application.
+
+/////////////////////////////////////////////////////////////////////////////
+
+The application wizard creates one document type and one view:
+
+TestProgDoc.h, TestProgDoc.cpp - the document
+    These files contain your CTestProgDoc class.  Edit these files to
+    add your special document data and to implement file saving and loading
+    (via CTestProgDoc::Serialize).
+
+TestProgView.h, TestProgView.cpp - the view of the document
+    These files contain your CTestProgView class.
+    CTestProgView objects are used to view CTestProgDoc objects.
+
+res\TestProgDoc.ico
+    This is an icon file, which is used as the icon for MDI child windows
+    for the CTestProgDoc class.  This icon is included by the main
+    resource file TestProg.rc.
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+The application wizard has also created classes specific to OLE
+
+CntrItem.h, CntrItem.cpp
+    These files contain your CTestProgCntrItem class. This class is used to
+    manipulate OLE objects.  OLE objects are usually displayed by your
+    CTestProgView class and serialized as part of your CTestProgDoc class.
+
+SrvrItem.h, SrvrItem.cpp
+    These files contain your CTestProgSrvrItem. This class is used to
+    connect your CTestProgDoc class to the OLE system, and optionally
+    provide links to your document.
+
+IpFrame.h, IpFrame.cpp
+    These files contain your CInPlaceFrame. This class is derived
+    from COleIPFrameWnd and controls all frame features during in-place activation.
+
+    The project has support for Compound files. The Compound-file format stores a document
+    that contains one or more Automation objects to one file and still allows access to
+    the it for the individual objects.
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+Other Features:
+
+ActiveX Controls
+    The application includes support to use ActiveX controls.
+
+Printing and Print Preview support
+    The application wizard has generated code to handle the print, print setup, and print preview
+    commands by calling member functions in the CView class from the MFC library.
+
+/////////////////////////////////////////////////////////////////////////////
+
+Other standard files:
+
+StdAfx.h, StdAfx.cpp
+    These files are used to build a precompiled header (PCH) file
+    named TestProg.pch and a precompiled types file named StdAfx.obj.
+
+Resource.h
+    This is the standard header file, which defines new resource IDs.
+    Microsoft Visual C++ reads and updates this file.
+
+TestProg.manifest
+	Application manifest files are used by Windows XP to describe an applications
+	dependency on specific versions of Side-by-Side assemblies. The loader uses this
+	information to load the appropriate assembly from the assembly cache or private
+	from the application. The Application manifest  maybe included for redistribution
+	as an external .manifest file that is installed in the same folder as the application
+	executable or it may be included in the executable in the form of a resource.
+/////////////////////////////////////////////////////////////////////////////
+
+Other notes:
+
+The application wizard uses "TODO:" to indicate parts of the source code you
+should add to or customize.
+
+If your application uses MFC in a shared DLL, you will need
+to redistribute the MFC DLLs. If your application is in a language
+other than the operating system's locale, you will also have to
+redistribute the corresponding localized resources MFC90XXX.DLL.
+For more information on both of these topics, please see the section on
+redistributing Visual C++ applications in MSDN documentation.
+
+/////////////////////////////////////////////////////////////////////////////
Index: /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/SrvrItem.cpp
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/SrvrItem.cpp	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/SrvrItem.cpp	(revision 540)
@@ -0,0 +1,121 @@
+// SrvrItem.cpp : implementation of the CTestProgSrvrItem class
+//
+
+#include "stdafx.h"
+#include "TestProg.h"
+
+#include "TestProgDoc.h"
+#include "SrvrItem.h"
+#include "CntrItem.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+// CTestProgSrvrItem implementation
+
+IMPLEMENT_DYNAMIC(CTestProgSrvrItem, COleServerItem)
+
+CTestProgSrvrItem::CTestProgSrvrItem(CTestProgDoc* pContainerDoc)
+	: COleServerItem(pContainerDoc, TRUE)
+{
+	// TODO: add one-time construction code here
+	//  (eg, adding additional clipboard formats to the item's data source)
+}
+
+CTestProgSrvrItem::~CTestProgSrvrItem()
+{
+	// TODO: add cleanup code here
+}
+
+void CTestProgSrvrItem::Serialize(CArchive& ar)
+{
+	// CTestProgSrvrItem::Serialize will be called by the framework if
+	//  the item is copied to the clipboard.  This can happen automatically
+	//  through the OLE callback OnGetClipboardData.  A good default for
+	//  the embedded item is simply to delegate to the document's Serialize
+	//  function.  If you support links, then you will want to serialize
+	//  just a portion of the document.
+
+	if (!IsLinkedItem())
+	{
+		CTestProgDoc* pDoc = GetDocument();
+		ASSERT_VALID(pDoc);
+		if (pDoc)
+			pDoc->Serialize(ar);
+	}
+}
+
+BOOL CTestProgSrvrItem::OnGetExtent(DVASPECT dwDrawAspect, CSize& rSize)
+{
+	// Most applications, like this one, only handle drawing the content
+	//  aspect of the item.  If you wish to support other aspects, such
+	//  as DVASPECT_THUMBNAIL (by overriding OnDrawEx), then this
+	//  implementation of OnGetExtent should be modified to handle the
+	//  additional aspect(s).
+
+	if (dwDrawAspect != DVASPECT_CONTENT)
+		return COleServerItem::OnGetExtent(dwDrawAspect, rSize);
+
+	// CTestProgSrvrItem::OnGetExtent is called to get the extent in
+	//  HIMETRIC units of the entire item.  The default implementation
+	//  here simply returns a hard-coded number of units.
+
+	// TODO: replace this arbitrary size
+
+	rSize = CSize(3000, 3000);   // 3000 x 3000 HIMETRIC units
+
+	return TRUE;
+}
+
+BOOL CTestProgSrvrItem::OnDraw(CDC* pDC, CSize& rSize)
+{
+	if (!pDC)
+		return FALSE;
+
+	// Remove this if you use rSize
+	UNREFERENCED_PARAMETER(rSize);
+
+	// TODO: set mapping mode and extent
+	//  (The extent is usually the same as the size returned from OnGetExtent)
+	pDC->SetMapMode(MM_ANISOTROPIC);
+	pDC->SetWindowOrg(0,0);
+	pDC->SetWindowExt(3000, 3000);
+
+	// TODO: add drawing code here.  Optionally, fill in the HIMETRIC extent.
+	//  All drawing takes place in the metafile device context (pDC).
+
+	// TODO: also draw embedded CTestProgCntrItem objects.
+
+	// The following code draws the first item at an arbitrary position.
+
+	// TODO: remove this code when your real drawing code is complete
+
+	CTestProgDoc* pDoc = GetDocument();
+	ASSERT_VALID(pDoc);
+	if (!pDoc)
+		return FALSE;
+
+	POSITION pos = pDoc->GetStartPosition();
+	CTestProgCntrItem* pItem = DYNAMIC_DOWNCAST(CTestProgCntrItem, pDoc->GetNextClientItem(pos));
+	if (pItem != NULL)
+		pItem->Draw(pDC, CRect(10, 10, 1010, 1010));
+	return TRUE;
+}
+
+
+// CTestProgSrvrItem diagnostics
+
+#ifdef _DEBUG
+void CTestProgSrvrItem::AssertValid() const
+{
+	COleServerItem::AssertValid();
+}
+
+void CTestProgSrvrItem::Dump(CDumpContext& dc) const
+{
+	COleServerItem::Dump(dc);
+}
+#endif
+
Index: /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/SrvrItem.h
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/SrvrItem.h	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/SrvrItem.h	(revision 540)
@@ -0,0 +1,34 @@
+// SrvrItem.h : interface of the CTestProgSrvrItem class
+//
+
+#pragma once
+
+class CTestProgSrvrItem : public COleServerItem
+{
+	DECLARE_DYNAMIC(CTestProgSrvrItem)
+
+// Constructors
+public:
+	CTestProgSrvrItem(CTestProgDoc* pContainerDoc);
+
+// Attributes
+	CTestProgDoc* GetDocument() const
+		{ return reinterpret_cast<CTestProgDoc*>(COleServerItem::GetDocument()); }
+
+// Overrides
+	public:
+	virtual BOOL OnDraw(CDC* pDC, CSize& rSize);
+	virtual BOOL OnGetExtent(DVASPECT dwDrawAspect, CSize& rSize);
+
+// Implementation
+public:
+	~CTestProgSrvrItem();
+#ifdef _DEBUG
+	virtual void AssertValid() const;
+	virtual void Dump(CDumpContext& dc) const;
+#endif
+
+protected:
+	virtual void Serialize(CArchive& ar);   // overridden for document i/o
+};
+
Index: /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/TestProg.cpp
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/TestProg.cpp	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/TestProg.cpp	(revision 540)
@@ -0,0 +1,249 @@
+// TestProg.cpp : Defines the class behaviors for the application.
+//
+
+#include "stdafx.h"
+#include <iostream>
+#include "TestProg.h"
+#include "MainFrm.h"
+
+#include "ChildFrm.h"
+#include "IpFrame.h"
+#include "TestProgDoc.h"
+#include "TestProgView.h"
+#include "afxwin.h"
+#include "afxcmn.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+// CTestProgApp
+
+BEGIN_MESSAGE_MAP(CTestProgApp, CWinApp)
+	ON_COMMAND(ID_APP_ABOUT, &CTestProgApp::OnAppAbout)
+	// Standard file based document commands
+	ON_COMMAND(ID_FILE_NEW, &CWinApp::OnFileNew)
+	ON_COMMAND(ID_FILE_OPEN, &CWinApp::OnFileOpen)
+	// Standard print setup command
+	ON_COMMAND(ID_FILE_PRINT_SETUP, &CWinApp::OnFilePrintSetup)
+END_MESSAGE_MAP()
+
+
+// CTestProgApp construction
+
+CTestProgApp::CTestProgApp()
+{
+	// TODO: add construction code here,
+	// Place all significant initialization in InitInstance
+}
+
+
+// The one and only CTestProgApp object
+
+CTestProgApp theApp;
+// This identifier was generated to be statistically unique for your app
+// You may change it if you prefer to choose a specific identifier
+
+// {81A5B9DA-E0DC-4E02-9097-38F90D423C7B}
+static const CLSID clsid =
+{ 0x81A5B9DA, 0xE0DC, 0x4E02, { 0x90, 0x97, 0x38, 0xF9, 0xD, 0x42, 0x3C, 0x7B } };
+
+
+// CTestProgApp initialization
+
+BOOL CTestProgApp::InitInstance()
+{
+	// InitCommonControlsEx() is required on Windows XP if an application
+	// manifest specifies use of ComCtl32.dll version 6 or later to enable
+	// visual styles.  Otherwise, any window creation will fail.
+	INITCOMMONCONTROLSEX InitCtrls;
+	InitCtrls.dwSize = sizeof(InitCtrls);
+	// Set this to include all the common control classes you want to use
+	// in your application.
+	InitCtrls.dwICC = ICC_WIN95_CLASSES;
+	InitCommonControlsEx(&InitCtrls);
+
+	CWinApp::InitInstance();
+
+	void (__cdecl *InitUsagelogPtr)(void) = NULL;
+	
+	hinstDll = LoadLibrary(L"userlog.dll");
+	if( hinstDll==NULL ) {
+		MessageBox(0, L"Loading of DLL failed", L"Failure", MB_OK);
+	}
+	InitUsagelogPtr = (void (*)(void)) GetProcAddress(hinstDll, "InitUsagelog");
+	if( InitUsagelogPtr==NULL ) {
+		MessageBox(0, L"Loading of InitFuncPtr failed", L"Failure", MB_OK);
+	}
+	if( InitUsagelogPtr!=NULL ) {
+		InitUsagelogPtr();
+	}
+
+
+	// Initialize OLE libraries
+	if (!AfxOleInit())
+	{
+		AfxMessageBox(IDP_OLE_INIT_FAILED);
+		return FALSE;
+	}
+	AfxEnableControlContainer();
+	// Standard initialization
+	// If you are not using these features and wish to reduce the size
+	// of your final executable, you should remove from the following
+	// the specific initialization routines you do not need
+	// Change the registry key under which our settings are stored
+	// TODO: You should modify this string to be something appropriate
+	// such as the name of your company or organization
+	SetRegistryKey(_T("Local AppWizard-Generated Applications"));
+	LoadStdProfileSettings(4);  // Load standard INI file options (including MRU)
+	// Register the application's document templates.  Document templates
+	//  serve as the connection between documents, frame windows and views
+	CMultiDocTemplate* pDocTemplate;
+	pDocTemplate = new CMultiDocTemplate(IDR_TestProgTYPE,
+		RUNTIME_CLASS(CTestProgDoc),
+		RUNTIME_CLASS(CChildFrame), // custom MDI child frame
+		RUNTIME_CLASS(CTestProgView));
+	if (!pDocTemplate)
+		return FALSE;
+	pDocTemplate->SetContainerInfo(IDR_TestProgTYPE_CNTR_IP);
+	pDocTemplate->SetServerInfo(
+		IDR_TestProgTYPE_SRVR_EMB, IDR_TestProgTYPE_SRVR_IP,
+		RUNTIME_CLASS(CInPlaceFrame));
+	AddDocTemplate(pDocTemplate);
+	// Connect the COleTemplateServer to the document template
+	//  The COleTemplateServer creates new documents on behalf
+	//  of requesting OLE containers by using information
+	//  specified in the document template
+	m_server.ConnectTemplate(clsid, pDocTemplate, FALSE);
+	// Register all OLE server factories as running.  This enables the
+	//  OLE libraries to create objects from other applications
+	COleTemplateServer::RegisterAll();
+		// Note: MDI applications register all server objects without regard
+		//  to the /Embedding or /Automation on the command line
+
+	// create main MDI Frame window
+	CMainFrame* pMainFrame = new CMainFrame;
+	if (!pMainFrame || !pMainFrame->LoadFrame(IDR_MAINFRAME))
+	{
+		delete pMainFrame;
+		return FALSE;
+	}
+	m_pMainWnd = pMainFrame;
+	// call DragAcceptFiles only if there's a suffix
+	//  In an MDI app, this should occur immediately after setting m_pMainWnd
+
+
+	// Parse command line for standard shell commands, DDE, file open
+	CCommandLineInfo cmdInfo;
+	ParseCommandLine(cmdInfo);
+
+	// App was launched with /Embedding or /Automation switch.
+	// Run app as automation server.
+	if (cmdInfo.m_bRunEmbedded || cmdInfo.m_bRunAutomated)
+	{
+		// Don't show the main window
+		return TRUE;
+	}
+	// App was launched with /Unregserver or /Unregister switch.  Unregister
+	// typelibrary.  Other unregistration occurs in ProcessShellCommand().
+	else if (cmdInfo.m_nShellCommand == CCommandLineInfo::AppUnregister)
+	{
+		m_server.UpdateRegistry(OAT_INPLACE_SERVER, NULL, NULL, FALSE);
+	}
+	// App was launched standalone or with other switches (e.g. /Register
+	// or /Regserver).  Update registry entries, including typelibrary.
+	else
+	{
+		m_server.UpdateRegistry(OAT_INPLACE_SERVER);
+	}
+
+	// Dispatch commands specified on the command line.  Will return FALSE if
+	// app was launched with /RegServer, /Register, /Unregserver or /Unregister.
+	if (!ProcessShellCommand(cmdInfo))
+		return FALSE;
+	// The main window has been initialized, so show and update it
+	pMainFrame->ShowWindow(m_nCmdShow);
+	pMainFrame->UpdateWindow();
+
+	return TRUE;
+}
+
+
+int CTestProgApp::ExitInstance()
+{
+	//TODO: Zusätzliche Ressourcen behandeln, die Sie möglicherweise hinzugefügt haben
+	AfxOleTerm(FALSE);
+	
+	void (*ReleaseUsagelogPtr)(void) = NULL;
+		
+	ReleaseUsagelogPtr = (void (*)(void)) GetProcAddress(hinstDll, "ReleaseUsagelog");
+	if( ReleaseUsagelogPtr==NULL ) {
+		MessageBox(0, L"Loading of ReleaseFuncPtr failed", L"Failure", MB_OK);
+	}
+	if( ReleaseUsagelogPtr!=NULL ) {
+		ReleaseUsagelogPtr();
+	}
+
+	FreeLibrary(hinstDll);
+
+	return CWinApp::ExitInstance();
+}
+
+// CAboutDlg dialog used for App About
+
+class CAboutDlg : public CDialog
+{
+public:
+	CAboutDlg();
+
+// Dialog Data
+	enum { IDD = IDD_ABOUTBOX };
+
+protected:
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
+
+// Implementation
+protected:
+	DECLARE_MESSAGE_MAP()
+public:
+	CListBox listbox_test;
+	CTabCtrl tabControl_test;
+	afx_msg void OnBnClickedButton1();
+};
+
+CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
+{
+	
+}
+
+void CAboutDlg::DoDataExchange(CDataExchange* pDX)
+{
+	CDialog::DoDataExchange(pDX);
+
+	DDX_Control(pDX, IDC_LIST1, listbox_test);
+	for(int i=0; i<10; i++) {
+		wchar_t* entry = new wchar_t[8];
+		wsprintf(entry, L"Entry %i", i);
+		listbox_test.AddString(entry);
+	}
+
+	DDX_Control(pDX, IDC_TAB1, tabControl_test);
+	tabControl_test.InsertItem(0, L"Tab 1");
+	tabControl_test.InsertItem(1, L"Tab 2");
+	tabControl_test.InsertItem(2, L"Tab 3");
+}
+
+BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
+END_MESSAGE_MAP()
+
+// App command to run the dialog
+void CTestProgApp::OnAppAbout()
+{
+	CAboutDlg aboutDlg;
+	aboutDlg.DoModal();
+	
+}
+
+
+// CTestProgApp message handlers
Index: /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/TestProg.h
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/TestProg.h	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/TestProg.h	(revision 540)
@@ -0,0 +1,35 @@
+// TestProg.h : main header file for the TestProg application
+//
+#pragma once
+
+#ifndef __AFXWIN_H__
+	#error "include 'stdafx.h' before including this file for PCH"
+#endif
+
+#include "resource.h"       // main symbols
+
+
+// CTestProgApp:
+// See TestProg.cpp for the implementation of this class
+//
+
+class CTestProgApp : public CWinApp
+{
+public:
+	CTestProgApp();
+private:
+	HINSTANCE hinstDll;
+
+// Overrides
+public:
+	virtual BOOL InitInstance();
+	virtual BOOL ExitInstance();
+
+// Implementation
+	COleTemplateServer m_server;
+		// Server object for document creation
+	afx_msg void OnAppAbout();
+	DECLARE_MESSAGE_MAP()
+};
+
+extern CTestProgApp theApp;
Index: /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/TestProg.rc
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/TestProg.rc	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/TestProg.rc	(revision 540)
@@ -0,0 +1,644 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#ifndef APSTUDIO_INVOKED
+#include "targetver.h"
+#endif
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE 
+BEGIN
+    "resource.h\0"
+END
+
+2 TEXTINCLUDE 
+BEGIN
+    "#ifndef APSTUDIO_INVOKED\r\n"
+    "#include ""targetver.h""\r\n"
+    "#endif\r\n"
+    "#include ""afxres.h""\r\n"
+    "\0"
+END
+
+3 TEXTINCLUDE 
+BEGIN
+    "#define _AFX_NO_SPLITTER_RESOURCES\r\n"
+    "#define _AFX_NO_PROPERTY_RESOURCES\r\n"
+    "\r\n"
+    "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
+    "LANGUAGE 9, 1\r\n"
+    "#pragma code_page(1252)\r\n"
+    "#include ""res\\TestProg.rc2""  // non-Microsoft Visual C++ edited resources\r\n"
+    "#include ""afxres.rc""         // Standard components\r\n"
+    "#include ""afxprint.rc""       // printing/print preview resources\r\n"
+    "#include ""afxolecl.rc""       // OLE container resources\r\n"
+    "#include ""afxolesv.rc""       // OLE server resources\r\n"
+    "#endif\r\n"
+    "\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDR_MAINFRAME           ICON                    "res\\TestProg.ico"
+IDR_TestProgTYPE        ICON                    "res\\TestProgDoc.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Bitmap
+//
+
+IDR_MAINFRAME           BITMAP                  "res\\Toolbar.bmp"
+IDR_TestProgTYPE_SRVR_IP BITMAP                  "res\\IToolbar.bmp"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Toolbar
+//
+
+IDR_MAINFRAME TOOLBAR  16, 15
+BEGIN
+    BUTTON      ID_FILE_NEW
+    BUTTON      ID_FILE_OPEN
+    BUTTON      ID_FILE_SAVE
+    SEPARATOR
+    BUTTON      ID_EDIT_CUT
+    BUTTON      ID_EDIT_COPY
+    BUTTON      ID_EDIT_PASTE
+    SEPARATOR
+    BUTTON      ID_FILE_PRINT
+    BUTTON      ID_APP_ABOUT
+END
+
+IDR_TestProgTYPE_SRVR_IP TOOLBAR  16, 15
+BEGIN
+    BUTTON      ID_EDIT_CUT
+    BUTTON      ID_EDIT_COPY
+    BUTTON      ID_EDIT_PASTE
+    SEPARATOR
+    BUTTON      ID_APP_ABOUT
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+IDR_MAINFRAME MENU 
+BEGIN
+    POPUP "&File"
+    BEGIN
+        MENUITEM "&New\tCtrl+N",                ID_FILE_NEW
+        MENUITEM "&Open...\tCtrl+O",            ID_FILE_OPEN
+        MENUITEM SEPARATOR
+        MENUITEM "P&rint Setup...",             ID_FILE_PRINT_SETUP
+        MENUITEM SEPARATOR
+        MENUITEM "Recent File",                 ID_FILE_MRU_FILE1, GRAYED
+        MENUITEM SEPARATOR
+        MENUITEM "&Close",                      ID_FILE_CLOSE
+        MENUITEM "E&xit",                       ID_APP_EXIT
+    END
+    POPUP "&View"
+    BEGIN
+        MENUITEM "&Toolbar",                    ID_VIEW_TOOLBAR
+        MENUITEM "&Status Bar",                 ID_VIEW_STATUS_BAR
+    END
+    POPUP "&Help"
+    BEGIN
+        MENUITEM "&About TestProg...",          ID_APP_ABOUT
+    END
+END
+
+IDR_TestProgTYPE MENU 
+BEGIN
+    POPUP "&File"
+    BEGIN
+        MENUITEM "&New\tCtrl+N",                ID_FILE_NEW
+        MENUITEM "&Open...\tCtrl+O",            ID_FILE_OPEN
+        MENUITEM "&Close",                      ID_FILE_CLOSE
+        MENUITEM "&Save\tCtrl+S",               ID_FILE_SAVE
+        MENUITEM "Save &As...",                 ID_FILE_SAVE_AS
+        MENUITEM SEPARATOR
+        MENUITEM "&Print...\tCtrl+P",           ID_FILE_PRINT
+        MENUITEM "Print Pre&view",              ID_FILE_PRINT_PREVIEW
+        MENUITEM "P&rint Setup...",             ID_FILE_PRINT_SETUP
+        MENUITEM SEPARATOR
+        MENUITEM "Recent File",                 ID_FILE_MRU_FILE1, GRAYED
+        MENUITEM SEPARATOR
+        MENUITEM "E&xit",                       ID_APP_EXIT
+    END
+    POPUP "&Edit"
+    BEGIN
+        MENUITEM "&Undo\tCtrl+Z",               ID_EDIT_UNDO
+        MENUITEM SEPARATOR
+        MENUITEM "Cu&t\tCtrl+X",                ID_EDIT_CUT
+        MENUITEM "&Copy\tCtrl+C",               ID_EDIT_COPY
+        MENUITEM "&Paste\tCtrl+V",              ID_EDIT_PASTE
+        MENUITEM "Paste &Special...",           ID_EDIT_PASTE_SPECIAL
+        MENUITEM SEPARATOR
+        MENUITEM "Insert &New Object...",       ID_OLE_INSERT_NEW
+        MENUITEM "Lin&ks...",                   ID_OLE_EDIT_LINKS
+        MENUITEM "<<OLE VERBS GO HERE>>",       ID_OLE_VERB_FIRST
+    END
+    POPUP "&View"
+    BEGIN
+        MENUITEM "&Toolbar",                    ID_VIEW_TOOLBAR
+        MENUITEM "&Status Bar",                 ID_VIEW_STATUS_BAR
+    END
+    POPUP "&Window"
+    BEGIN
+        MENUITEM "&New Window",                 ID_WINDOW_NEW
+        MENUITEM "&Cascade",                    ID_WINDOW_CASCADE
+        MENUITEM "&Tile",                       ID_WINDOW_TILE_HORZ
+        MENUITEM "&Arrange Icons",              ID_WINDOW_ARRANGE
+    END
+    POPUP "&Help"
+    BEGIN
+        MENUITEM "&About TestProg...",          ID_APP_ABOUT
+    END
+END
+
+IDR_TestProgTYPE_CNTR_IP MENU 
+BEGIN
+    POPUP "&File"
+    BEGIN
+        MENUITEM "&New\tCtrl+N",                ID_FILE_NEW
+        MENUITEM "&Open...\tCtrl+O",            ID_FILE_OPEN
+        MENUITEM "&Close",                      ID_FILE_CLOSE
+        MENUITEM "&Save\tCtrl+S",               ID_FILE_SAVE
+        MENUITEM "Save &As...",                 ID_FILE_SAVE_AS
+        MENUITEM SEPARATOR
+        MENUITEM "&Print...\tCtrl+P",           ID_FILE_PRINT
+        MENUITEM "Print Pre&view",              ID_FILE_PRINT_PREVIEW
+        MENUITEM "P&rint Setup...",             ID_FILE_PRINT_SETUP
+        MENUITEM SEPARATOR
+        MENUITEM "Recent File",                 ID_FILE_MRU_FILE1, GRAYED
+        MENUITEM SEPARATOR
+        MENUITEM "E&xit",                       ID_APP_EXIT
+    END
+    MENUITEM SEPARATOR
+    MENUITEM SEPARATOR
+    POPUP "&Window"
+    BEGIN
+        MENUITEM "&New Window",                 ID_WINDOW_NEW
+        MENUITEM "&Cascade",                    ID_WINDOW_CASCADE
+        MENUITEM "&Tile",                       ID_WINDOW_TILE_HORZ
+        MENUITEM "&Arrange Icons",              ID_WINDOW_ARRANGE
+    END
+END
+
+IDR_TestProgTYPE_SRVR_EMB MENU 
+BEGIN
+    POPUP "&File"
+    BEGIN
+        MENUITEM "&New\tCtrl+N",                ID_FILE_NEW
+        MENUITEM "&Open...\tCtrl+O",            ID_FILE_OPEN
+        MENUITEM "&Close",                      ID_FILE_CLOSE
+        MENUITEM "&Update\tCtrl+S",             ID_FILE_UPDATE
+        MENUITEM "Save Copy &As...",            ID_FILE_SAVE_COPY_AS
+        MENUITEM SEPARATOR
+        MENUITEM "&Print...\tCtrl+P",           ID_FILE_PRINT
+        MENUITEM "Print Pre&view",              ID_FILE_PRINT_PREVIEW
+        MENUITEM "P&rint Setup...",             ID_FILE_PRINT_SETUP
+        MENUITEM SEPARATOR
+        MENUITEM "Recent File",                 ID_FILE_MRU_FILE1, GRAYED
+        MENUITEM SEPARATOR
+        MENUITEM "E&xit",                       ID_APP_EXIT
+    END
+    POPUP "&Edit"
+    BEGIN
+        MENUITEM "&Undo\tCtrl+Z",               ID_EDIT_UNDO
+        MENUITEM SEPARATOR
+        MENUITEM "Cu&t\tCtrl+X",                ID_EDIT_CUT
+        MENUITEM "&Copy\tCtrl+C",               ID_EDIT_COPY
+        MENUITEM "&Paste\tCtrl+V",              ID_EDIT_PASTE
+        MENUITEM "Paste &Special...",           ID_EDIT_PASTE_SPECIAL
+        MENUITEM SEPARATOR
+        MENUITEM "Insert &New Object...",       ID_OLE_INSERT_NEW
+        MENUITEM "Lin&ks...",                   ID_OLE_EDIT_LINKS
+        MENUITEM "<<OLE VERBS GO HERE>>",       ID_OLE_VERB_FIRST
+    END
+    POPUP "&View"
+    BEGIN
+        MENUITEM "&Toolbar",                    ID_VIEW_TOOLBAR
+        MENUITEM "&Status Bar",                 ID_VIEW_STATUS_BAR
+    END
+    POPUP "&Window"
+    BEGIN
+        MENUITEM "&New Window",                 ID_WINDOW_NEW
+        MENUITEM "&Cascade",                    ID_WINDOW_CASCADE
+        MENUITEM "&Tile",                       ID_WINDOW_TILE_HORZ
+        MENUITEM "&Arrange Icons",              ID_WINDOW_ARRANGE
+    END
+    POPUP "&Help"
+    BEGIN
+        MENUITEM "&About TestProg...",          ID_APP_ABOUT
+    END
+END
+
+IDR_TestProgTYPE_SRVR_IP MENU 
+BEGIN
+    POPUP "&Edit"
+    BEGIN
+        MENUITEM "&Undo\tCtrl+Z",               ID_EDIT_UNDO
+        MENUITEM SEPARATOR
+        MENUITEM "Cu&t\tCtrl+X",                ID_EDIT_CUT
+        MENUITEM "&Copy\tCtrl+C",               ID_EDIT_COPY
+        MENUITEM "&Paste\tCtrl+V",              ID_EDIT_PASTE
+        MENUITEM "Paste &Special...",           ID_EDIT_PASTE_SPECIAL
+        MENUITEM SEPARATOR
+        MENUITEM "Insert &New Object...",       ID_OLE_INSERT_NEW
+        MENUITEM "Lin&ks...",                   ID_OLE_EDIT_LINKS
+        MENUITEM "<<OLE VERBS GO HERE>>",       ID_OLE_VERB_FIRST
+    END
+    POPUP "&View"
+    BEGIN
+        MENUITEM "&Toolbar",                    ID_VIEW_TOOLBAR
+    END
+    MENUITEM SEPARATOR
+    MENUITEM SEPARATOR
+    POPUP "&Help"
+    BEGIN
+        MENUITEM "&About TestProg...",          ID_APP_ABOUT
+    END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Accelerator
+//
+
+IDR_MAINFRAME ACCELERATORS 
+BEGIN
+    "N",            ID_FILE_NEW,            VIRTKEY, CONTROL
+    "O",            ID_FILE_OPEN,           VIRTKEY, CONTROL
+    "S",            ID_FILE_SAVE,           VIRTKEY, CONTROL
+    "P",            ID_FILE_PRINT,          VIRTKEY, CONTROL
+    "Z",            ID_EDIT_UNDO,           VIRTKEY, CONTROL
+    "X",            ID_EDIT_CUT,            VIRTKEY, CONTROL
+    "C",            ID_EDIT_COPY,           VIRTKEY, CONTROL
+    "V",            ID_EDIT_PASTE,          VIRTKEY, CONTROL
+    VK_BACK,        ID_EDIT_UNDO,           VIRTKEY, ALT
+    VK_DELETE,      ID_EDIT_CUT,            VIRTKEY, SHIFT
+    VK_INSERT,      ID_EDIT_COPY,           VIRTKEY, CONTROL
+    VK_INSERT,      ID_EDIT_PASTE,          VIRTKEY, SHIFT
+    VK_F6,          ID_NEXT_PANE,           VIRTKEY 
+    VK_F6,          ID_PREV_PANE,           VIRTKEY, SHIFT
+    VK_ESCAPE,      ID_CANCEL_EDIT_CNTR,    VIRTKEY, NOINVERT
+END
+
+IDR_TestProgTYPE_CNTR_IP ACCELERATORS 
+BEGIN
+    "N",            ID_FILE_NEW,            VIRTKEY, CONTROL
+    "O",            ID_FILE_OPEN,           VIRTKEY, CONTROL
+    "S",            ID_FILE_SAVE,           VIRTKEY, CONTROL
+    "P",            ID_FILE_PRINT,          VIRTKEY, CONTROL
+    VK_F6,          ID_NEXT_PANE,           VIRTKEY 
+    VK_F6,          ID_PREV_PANE,           VIRTKEY, SHIFT
+    VK_ESCAPE,      ID_CANCEL_EDIT_CNTR,    VIRTKEY, NOINVERT
+END
+
+IDR_TestProgTYPE_SRVR_IP ACCELERATORS 
+BEGIN
+    "Z",            ID_EDIT_UNDO,           VIRTKEY, CONTROL
+    "X",            ID_EDIT_CUT,            VIRTKEY, CONTROL
+    "C",            ID_EDIT_COPY,           VIRTKEY, CONTROL
+    "V",            ID_EDIT_PASTE,          VIRTKEY, CONTROL
+    VK_BACK,        ID_EDIT_UNDO,           VIRTKEY, ALT
+    VK_DELETE,      ID_EDIT_CUT,            VIRTKEY, SHIFT
+    VK_INSERT,      ID_EDIT_COPY,           VIRTKEY, CONTROL
+    VK_INSERT,      ID_EDIT_PASTE,          VIRTKEY, SHIFT
+    VK_ESCAPE,      ID_CANCEL_EDIT_SRVR,    VIRTKEY, NOINVERT
+END
+
+IDR_TestProgTYPE_SRVR_EMB ACCELERATORS 
+BEGIN
+    "N",            ID_FILE_NEW,            VIRTKEY, CONTROL
+    "O",            ID_FILE_OPEN,           VIRTKEY, CONTROL
+    "S",            ID_FILE_UPDATE,         VIRTKEY, CONTROL
+    "P",            ID_FILE_PRINT,          VIRTKEY, CONTROL
+    "Z",            ID_EDIT_UNDO,           VIRTKEY, CONTROL
+    "X",            ID_EDIT_CUT,            VIRTKEY, CONTROL
+    "C",            ID_EDIT_COPY,           VIRTKEY, CONTROL
+    "V",            ID_EDIT_PASTE,          VIRTKEY, CONTROL
+    VK_BACK,        ID_EDIT_UNDO,           VIRTKEY, ALT
+    VK_DELETE,      ID_EDIT_CUT,            VIRTKEY, SHIFT
+    VK_INSERT,      ID_EDIT_COPY,           VIRTKEY, CONTROL
+    VK_INSERT,      ID_EDIT_PASTE,          VIRTKEY, SHIFT
+    VK_F6,          ID_NEXT_PANE,           VIRTKEY 
+    VK_F6,          ID_PREV_PANE,           VIRTKEY, SHIFT
+    VK_ESCAPE,      ID_CANCEL_EDIT_CNTR,    VIRTKEY, NOINVERT
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_ABOUTBOX DIALOGEX 0, 0, 271, 218
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "About TestProg"
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+    ICON            IDR_MAINFRAME,IDC_STATIC,14,14,21,20
+    LTEXT           "TestProg, Version 1.0",IDC_STATIC,42,14,114,8,SS_NOPREFIX
+    LTEXT           "Copyright (C) 2010",IDC_STATIC,42,26,114,8
+    DEFPUSHBUTTON   "OK",IDOK,200,188,50,14,WS_GROUP
+    EDITTEXT        IDC_EDIT1,17,57,86,16,ES_AUTOHSCROLL
+    CONTROL         "Check1",IDC_CHECK1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,79,39,10
+    COMBOBOX        IDC_COMBO1,18,92,48,16,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP
+    CONTROL         "Radio1",IDC_RADIO1,"Button",BS_AUTORADIOBUTTON,19,124,38,10
+    CONTROL         "Radio2",IDC_RADIO2,"Button",BS_AUTORADIOBUTTON,19,139,38,10
+    CONTROL         "Radio3",IDC_RADIO3,"Button",BS_AUTORADIOBUTTON,19,155,38,10
+    GROUPBOX        "Static",IDC_STATIC,15,114,68,63
+    CONTROL         "",IDC_SLIDER1,"msctls_trackbar32",TBS_VERT | TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,91,85,21,93
+    LISTBOX         IDC_LIST1,132,20,116,49,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
+    CONTROL         "",IDC_TAB1,"SysTabControl32",0x0,135,115,119,55
+    CONTROL         "",IDC_SLIDER2,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,17,182,98,16
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,1
+ PRODUCTVERSION 1,0,0,1
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "040904e4"
+        BEGIN
+            VALUE "CompanyName", "TODO: <Company name>"
+            VALUE "FileDescription", "TODO: <File description>"
+            VALUE "FileVersion", "1.0.0.1"
+            VALUE "InternalName", "TestProg.exe"
+            VALUE "LegalCopyright", "TODO: (c) <Company name>.  All rights reserved."
+            VALUE "OriginalFilename", "TestProg.exe"
+            VALUE "ProductName", "TODO: <Product name>"
+            VALUE "ProductVersion", "1.0.0.1"
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x409, 1252
+    END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO 
+BEGIN
+    IDD_ABOUTBOX, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 264
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 211
+    END
+END
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog Info
+//
+
+IDD_ABOUTBOX DLGINIT
+BEGIN
+    IDC_COMBO1, 0x403, 6, 0
+0x7449, 0x6d65, 0x0031, 
+    IDC_COMBO1, 0x403, 6, 0
+0x7449, 0x6d65, 0x0032, 
+    0
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE 
+BEGIN
+    IDP_OLE_INIT_FAILED     "OLE initialization failed.  Make sure that the OLE libraries are the correct version."
+    IDP_FAILED_TO_CREATE    "Failed to create object.  Make sure the object is entered in the system registry."
+END
+
+STRINGTABLE 
+BEGIN
+    IDR_MAINFRAME           "TestProg"
+    IDR_TestProgTYPE        "\nTestProg\nTestProg\n\n\nTestProg.Document\nTestProg.Document"
+END
+
+STRINGTABLE 
+BEGIN
+    AFX_IDS_APP_TITLE       "TestProg"
+    AFX_IDS_IDLEMESSAGE     "Ready"
+END
+
+STRINGTABLE 
+BEGIN
+    ID_INDICATOR_EXT        "EXT"
+    ID_INDICATOR_CAPS       "CAP"
+    ID_INDICATOR_NUM        "NUM"
+    ID_INDICATOR_SCRL       "SCRL"
+    ID_INDICATOR_OVR        "OVR"
+    ID_INDICATOR_REC        "REC"
+END
+
+STRINGTABLE 
+BEGIN
+    ID_FILE_NEW             "Create a new document\nNew"
+    ID_FILE_OPEN            "Open an existing document\nOpen"
+    ID_FILE_CLOSE           "Close the active document\nClose"
+    ID_FILE_SAVE            "Save the active document\nSave"
+    ID_FILE_SAVE_AS         "Save the active document with a new name\nSave As"
+    ID_FILE_PAGE_SETUP      "Change the printing options\nPage Setup"
+    ID_FILE_PRINT_SETUP     "Change the printer and printing options\nPrint Setup"
+    ID_FILE_PRINT           "Print the active document\nPrint"
+    ID_FILE_PRINT_PREVIEW   "Display full pages\nPrint Preview"
+    ID_FILE_UPDATE          "Update the container to show any changes\nUpdate"
+    ID_FILE_SAVE_COPY_AS    "Save a copy of the active document with a new name\nSave Copy"
+END
+
+STRINGTABLE 
+BEGIN
+    ID_APP_ABOUT            "Display program information, version number and copyright\nAbout"
+    ID_APP_EXIT             "Quit the application; prompts to save documents\nExit"
+END
+
+STRINGTABLE 
+BEGIN
+    ID_FILE_MRU_FILE1       "Open this document"
+    ID_FILE_MRU_FILE2       "Open this document"
+    ID_FILE_MRU_FILE3       "Open this document"
+    ID_FILE_MRU_FILE4       "Open this document"
+    ID_FILE_MRU_FILE5       "Open this document"
+    ID_FILE_MRU_FILE6       "Open this document"
+    ID_FILE_MRU_FILE7       "Open this document"
+    ID_FILE_MRU_FILE8       "Open this document"
+    ID_FILE_MRU_FILE9       "Open this document"
+    ID_FILE_MRU_FILE10      "Open this document"
+    ID_FILE_MRU_FILE11      "Open this document"
+    ID_FILE_MRU_FILE12      "Open this document"
+    ID_FILE_MRU_FILE13      "Open this document"
+    ID_FILE_MRU_FILE14      "Open this document"
+    ID_FILE_MRU_FILE15      "Open this document"
+    ID_FILE_MRU_FILE16      "Open this document"
+END
+
+STRINGTABLE 
+BEGIN
+    ID_NEXT_PANE            "Switch to the next window pane\nNext Pane"
+    ID_PREV_PANE            "Switch back to the previous window pane\nPrevious Pane"
+END
+
+STRINGTABLE 
+BEGIN
+    ID_WINDOW_NEW           "Open another window for the active document\nNew Window"
+    ID_WINDOW_ARRANGE       "Arrange icons at the bottom of the window\nArrange Icons"
+    ID_WINDOW_CASCADE       "Arrange windows so they overlap\nCascade Windows"
+    ID_WINDOW_TILE_HORZ     "Arrange windows as non-overlapping tiles\nTile Windows"
+    ID_WINDOW_TILE_VERT     "Arrange windows as non-overlapping tiles\nTile Windows"
+    ID_WINDOW_SPLIT         "Split the active window into panes\nSplit"
+END
+
+STRINGTABLE 
+BEGIN
+    ID_EDIT_CLEAR           "Erase the selection\nErase"
+    ID_EDIT_CLEAR_ALL       "Erase everything\nErase All"
+    ID_EDIT_COPY            "Copy the selection and put it on the Clipboard\nCopy"
+    ID_EDIT_CUT             "Cut the selection and put it on the Clipboard\nCut"
+    ID_EDIT_FIND            "Find the specified text\nFind"
+    ID_EDIT_PASTE           "Insert Clipboard contents\nPaste"
+    ID_EDIT_PASTE_LINK      "Insert Clipboard contents and a link to its source\nPaste Link"
+    ID_EDIT_PASTE_SPECIAL   "Insert Clipboard contents with options\nPaste Special"
+    ID_EDIT_REPEAT          "Repeat the last action\nRepeat"
+    ID_EDIT_REPLACE         "Replace specific text with different text\nReplace"
+    ID_EDIT_SELECT_ALL      "Select the entire document\nSelect All"
+    ID_EDIT_UNDO            "Undo the last action\nUndo"
+    ID_EDIT_REDO            "Redo the previously undone action\nRedo"
+END
+
+STRINGTABLE 
+BEGIN
+    ID_VIEW_TOOLBAR         "Show or hide the toolbar\nToggle ToolBar"
+    ID_VIEW_STATUS_BAR      "Show or hide the status bar\nToggle StatusBar"
+END
+
+STRINGTABLE 
+BEGIN
+    ID_OLE_INSERT_NEW       "Insert new embedded object\nNew Object"
+    ID_OLE_EDIT_LINKS       "Edit linked objects\nEdit Links"
+    ID_OLE_EDIT_CONVERT     "Convert object to different type\nConvert Object"
+END
+
+STRINGTABLE 
+BEGIN
+    ID_OLE_VERB_FIRST       "Activate embedded or linked object"
+    57873                   "Activate embedded or linked object"
+    57874                   "Activate embedded or linked object"
+    57875                   "Activate embedded or linked object"
+END
+
+STRINGTABLE 
+BEGIN
+    AFX_IDS_SCSIZE          "Change the window size"
+    AFX_IDS_SCMOVE          "Change the window position"
+    AFX_IDS_SCMINIMIZE      "Reduce the window to an icon"
+    AFX_IDS_SCMAXIMIZE      "Enlarge the window to full size"
+    AFX_IDS_SCNEXTWINDOW    "Switch to the next document window"
+    AFX_IDS_SCPREVWINDOW    "Switch to the previous document window"
+    AFX_IDS_SCCLOSE         "Close the active window and prompts to save the documents"
+END
+
+STRINGTABLE 
+BEGIN
+    AFX_IDS_SCRESTORE       "Restore the window to normal size"
+    AFX_IDS_SCTASKLIST      "Activate Task List"
+    AFX_IDS_MDICHILD        "Activate this window"
+END
+
+STRINGTABLE 
+BEGIN
+    AFX_IDS_PREVIEW_CLOSE   "Close print preview mode\nCancel Preview"
+END
+
+#endif    // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#define _AFX_NO_SPLITTER_RESOURCES
+#define _AFX_NO_PROPERTY_RESOURCES
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+LANGUAGE 9, 1
+#pragma code_page(1252)
+#include "res\TestProg.rc2"  // non-Microsoft Visual C++ edited resources
+#include "afxres.rc"         // Standard components
+#include "afxprint.rc"       // printing/print preview resources
+#include "afxolecl.rc"       // OLE container resources
+#include "afxolesv.rc"       // OLE server resources
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
+
Index: /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/TestProg.reg
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/TestProg.reg	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/TestProg.reg	(revision 540)
@@ -0,0 +1,27 @@
+REGEDIT
+; This .REG file may be used by your SETUP program.
+;   If a SETUP program is not available, the entries below will be
+;   registered in your InitInstance automatically with a call to
+;   CWinApp::RegisterShellFileTypes and COleObjectFactory::UpdateRegistryAll.
+
+
+HKEY_CLASSES_ROOT\TestProg.Document = TestProg.Document
+
+
+HKEY_CLASSES_ROOT\TestProg.Document\protocol\StdFileEditing\server = TestProg.EXE
+HKEY_CLASSES_ROOT\TestProg.Document\protocol\StdFileEditing\verb\0 = &Edit
+HKEY_CLASSES_ROOT\TestProg.Document\Insertable =
+HKEY_CLASSES_ROOT\TestProg.Document\CLSID = {81A5B9DA-E0DC-4E02-9097-38F90D423C7B}
+
+HKEY_CLASSES_ROOT\CLSID\{81A5B9DA-E0DC-4E02-9097-38F90D423C7B} = TestProg.Document
+HKEY_CLASSES_ROOT\CLSID\{81A5B9DA-E0DC-4E02-9097-38F90D423C7B}\DefaultIcon = TestProg.EXE,1
+HKEY_CLASSES_ROOT\CLSID\{81A5B9DA-E0DC-4E02-9097-38F90D423C7B}\LocalServer32 = TestProg.EXE
+HKEY_CLASSES_ROOT\CLSID\{81A5B9DA-E0DC-4E02-9097-38F90D423C7B}\ProgId = TestProg.Document
+HKEY_CLASSES_ROOT\CLSID\{81A5B9DA-E0DC-4E02-9097-38F90D423C7B}\MiscStatus = 32
+HKEY_CLASSES_ROOT\CLSID\{81A5B9DA-E0DC-4E02-9097-38F90D423C7B}\AuxUserType\3 = TestProg
+HKEY_CLASSES_ROOT\CLSID\{81A5B9DA-E0DC-4E02-9097-38F90D423C7B}\AuxUserType\2 = TestProg
+HKEY_CLASSES_ROOT\CLSID\{81A5B9DA-E0DC-4E02-9097-38F90D423C7B}\Insertable = 
+HKEY_CLASSES_ROOT\CLSID\{81A5B9DA-E0DC-4E02-9097-38F90D423C7B}\verb\1 = &Open,0,2
+HKEY_CLASSES_ROOT\CLSID\{81A5B9DA-E0DC-4E02-9097-38F90D423C7B}\verb\0 = &Edit,0,2
+HKEY_CLASSES_ROOT\CLSID\{81A5B9DA-E0DC-4E02-9097-38F90D423C7B}\InprocHandler32 = ole32.dll
+
Index: /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/TestProg.vcproj
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/TestProg.vcproj	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/TestProg.vcproj	(revision 540)
@@ -0,0 +1,344 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9,00"
+	Name="TestProg"
+	ProjectGUID="{98889796-F392-4C4F-A619-BD2C1509B392}"
+	RootNamespace="TestProg"
+	Keyword="MFCProj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			UseOfMFC="2"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				PreprocessorDefinitions="_DEBUG"
+				MkTypLibCompatible="false"
+				ValidateParameters="true"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories=""
+				PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="_DEBUG"
+				Culture="1033"
+				AdditionalIncludeDirectories="$(IntDir)"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				RegisterOutput="true"
+				LinkIncremental="2"
+				AdditionalLibraryDirectories=""
+				GenerateDebugInformation="true"
+				SubSystem="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				CommandLine="copy C:\Projects\MFCtooling\Debug\userlog.dll C:\Programme\Mahr\MarWin\userlog.dll /y"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			UseOfMFC="2"
+			CharacterSet="1"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				PreprocessorDefinitions="NDEBUG"
+				MkTypLibCompatible="false"
+				ValidateParameters="true"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				EnableIntrinsicFunctions="true"
+				AdditionalIncludeDirectories="C:\Projects"
+				PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+				MinimalRebuild="false"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"
+				AdditionalIncludeDirectories="$(IntDir)"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				RegisterOutput="true"
+				AdditionalDependencies="C:\Projects\msl\lib\win32\release\trace.lib"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="C:\Projects"
+				GenerateDebugInformation="true"
+				SubSystem="2"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath=".\ChildFrm.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\CntrItem.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\IpFrame.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\MainFrm.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\SrvrItem.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\stdafx.cpp"
+				>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						UsePrecompiledHeader="1"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						UsePrecompiledHeader="1"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\TestProg.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\TestProgDoc.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\TestProgView.cpp"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+			<File
+				RelativePath=".\ChildFrm.h"
+				>
+			</File>
+			<File
+				RelativePath=".\CntrItem.h"
+				>
+			</File>
+			<File
+				RelativePath=".\IpFrame.h"
+				>
+			</File>
+			<File
+				RelativePath=".\MainFrm.h"
+				>
+			</File>
+			<File
+				RelativePath=".\Resource.h"
+				>
+			</File>
+			<File
+				RelativePath=".\SrvrItem.h"
+				>
+			</File>
+			<File
+				RelativePath=".\stdafx.h"
+				>
+			</File>
+			<File
+				RelativePath=".\targetver.h"
+				>
+			</File>
+			<File
+				RelativePath=".\TestProg.h"
+				>
+			</File>
+			<File
+				RelativePath=".\TestProgDoc.h"
+				>
+			</File>
+			<File
+				RelativePath=".\TestProgView.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+			>
+			<File
+				RelativePath=".\res\IToolbar.bmp"
+				>
+			</File>
+			<File
+				RelativePath=".\res\TestProg.ico"
+				>
+			</File>
+			<File
+				RelativePath=".\TestProg.rc"
+				>
+			</File>
+			<File
+				RelativePath=".\res\TestProg.rc2"
+				>
+			</File>
+			<File
+				RelativePath=".\res\TestProgDoc.ico"
+				>
+			</File>
+			<File
+				RelativePath=".\res\Toolbar.bmp"
+				>
+			</File>
+		</Filter>
+		<File
+			RelativePath=".\ReadMe.txt"
+			>
+		</File>
+		<File
+			RelativePath=".\TestProg.reg"
+			>
+		</File>
+	</Files>
+	<Globals>
+		<Global
+			Name="RESOURCE_FILE"
+			Value="TestProg.rc"
+		/>
+	</Globals>
+</VisualStudioProject>
Index: /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/TestProgDoc.cpp
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/TestProgDoc.cpp	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/TestProgDoc.cpp	(revision 540)
@@ -0,0 +1,108 @@
+// TestProgDoc.cpp : implementation of the CTestProgDoc class
+//
+
+#include "stdafx.h"
+#include "TestProg.h"
+
+#include "TestProgDoc.h"
+#include "CntrItem.h"
+#include "SrvrItem.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+// CTestProgDoc
+
+IMPLEMENT_DYNCREATE(CTestProgDoc, COleServerDoc)
+
+BEGIN_MESSAGE_MAP(CTestProgDoc, COleServerDoc)
+	// Enable default OLE container implementation
+	ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE, &COleServerDoc::OnUpdatePasteMenu)
+	ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE_LINK, &COleServerDoc::OnUpdatePasteLinkMenu)
+	ON_UPDATE_COMMAND_UI(ID_OLE_EDIT_CONVERT, &COleServerDoc::OnUpdateObjectVerbMenu)
+	ON_COMMAND(ID_OLE_EDIT_CONVERT, &COleServerDoc::OnEditConvert)
+	ON_UPDATE_COMMAND_UI(ID_OLE_EDIT_LINKS, &COleServerDoc::OnUpdateEditLinksMenu)
+	ON_COMMAND(ID_OLE_EDIT_LINKS, &COleServerDoc::OnEditLinks)
+	ON_UPDATE_COMMAND_UI_RANGE(ID_OLE_VERB_FIRST, ID_OLE_VERB_LAST, &COleServerDoc::OnUpdateObjectVerbMenu)
+END_MESSAGE_MAP()
+
+
+// CTestProgDoc construction/destruction
+
+CTestProgDoc::CTestProgDoc()
+{
+	// Use OLE compound files
+	EnableCompoundFile();
+
+	// TODO: add one-time construction code here
+
+}
+
+CTestProgDoc::~CTestProgDoc()
+{
+}
+
+BOOL CTestProgDoc::OnNewDocument()
+{
+	if (!COleServerDoc::OnNewDocument())
+		return FALSE;
+
+	// TODO: add reinitialization code here
+	// (SDI documents will reuse this document)
+
+	return TRUE;
+}
+
+
+// CTestProgDoc server implementation
+
+COleServerItem* CTestProgDoc::OnGetEmbeddedItem()
+{
+	// OnGetEmbeddedItem is called by the framework to get the COleServerItem
+	//  that is associated with the document.  It is only called when necessary.
+
+	CTestProgSrvrItem* pItem = new CTestProgSrvrItem(this);
+	ASSERT_VALID(pItem);
+	return pItem;
+}
+
+
+
+
+// CTestProgDoc serialization
+
+void CTestProgDoc::Serialize(CArchive& ar)
+{
+	if (ar.IsStoring())
+	{
+		// TODO: add storing code here
+	}
+	else
+	{
+		// TODO: add loading code here
+	}
+
+	// Calling the base class COleServerDoc enables serialization
+	//  of the container document's COleClientItem objects.
+	COleServerDoc::Serialize(ar);
+}
+
+
+// CTestProgDoc diagnostics
+
+#ifdef _DEBUG
+void CTestProgDoc::AssertValid() const
+{
+	COleServerDoc::AssertValid();
+}
+
+void CTestProgDoc::Dump(CDumpContext& dc) const
+{
+	COleServerDoc::Dump(dc);
+}
+#endif //_DEBUG
+
+
+// CTestProgDoc commands
Index: /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/TestProgDoc.h
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/TestProgDoc.h	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/TestProgDoc.h	(revision 540)
@@ -0,0 +1,46 @@
+// TestProgDoc.h : interface of the CTestProgDoc class
+//
+
+
+#pragma once
+
+
+class CTestProgSrvrItem;
+
+class CTestProgDoc : public COleServerDoc
+{
+protected: // create from serialization only
+	CTestProgDoc();
+	DECLARE_DYNCREATE(CTestProgDoc)
+
+// Attributes
+public:
+	CTestProgSrvrItem* GetEmbeddedItem()
+		{ return reinterpret_cast<CTestProgSrvrItem*>(COleServerDoc::GetEmbeddedItem()); }
+
+// Operations
+public:
+
+// Overrides
+protected:
+	virtual COleServerItem* OnGetEmbeddedItem();
+public:
+	virtual BOOL OnNewDocument();
+	virtual void Serialize(CArchive& ar);
+
+// Implementation
+public:
+	virtual ~CTestProgDoc();
+#ifdef _DEBUG
+	virtual void AssertValid() const;
+	virtual void Dump(CDumpContext& dc) const;
+#endif
+
+protected:
+
+// Generated message map functions
+protected:
+	DECLARE_MESSAGE_MAP()
+};
+
+
Index: /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/TestProgView.cpp
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/TestProgView.cpp	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/TestProgView.cpp	(revision 540)
@@ -0,0 +1,287 @@
+// TestProgView.cpp : implementation of the CTestProgView class
+//
+
+#include "stdafx.h"
+#include "TestProg.h"
+
+#include "TestProgDoc.h"
+#include "CntrItem.h"
+#include "TestProgView.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+// CTestProgView
+
+IMPLEMENT_DYNCREATE(CTestProgView, CView)
+
+BEGIN_MESSAGE_MAP(CTestProgView, CView)
+	ON_WM_DESTROY()
+	ON_WM_SETFOCUS()
+	ON_WM_SIZE()
+	ON_COMMAND(ID_OLE_INSERT_NEW, &CTestProgView::OnInsertObject)
+	ON_COMMAND(ID_CANCEL_EDIT_CNTR, &CTestProgView::OnCancelEditCntr)
+	ON_COMMAND(ID_FILE_PRINT, &CTestProgView::OnFilePrint)
+	ON_COMMAND(ID_CANCEL_EDIT_SRVR, &CTestProgView::OnCancelEditSrvr)
+	ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
+	ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CView::OnFilePrintPreview)
+END_MESSAGE_MAP()
+
+// CTestProgView construction/destruction
+
+CTestProgView::CTestProgView()
+{
+	m_pSelection = NULL;
+	// TODO: add construction code here
+
+}
+
+CTestProgView::~CTestProgView()
+{
+}
+
+BOOL CTestProgView::PreCreateWindow(CREATESTRUCT& cs)
+{
+	// TODO: Modify the Window class or styles here by modifying
+	//  the CREATESTRUCT cs
+
+	return CView::PreCreateWindow(cs);
+}
+
+// CTestProgView drawing
+
+void CTestProgView::OnDraw(CDC* pDC)
+{
+	if (!pDC)
+		return;
+
+	CTestProgDoc* pDoc = GetDocument();
+	ASSERT_VALID(pDoc);
+	if (!pDoc)
+		return;
+
+	// TODO: add draw code for native data here
+	// TODO: also draw all OLE items in the document
+
+	// Draw the selection at an arbitrary position.  This code should be
+	//  removed once your real drawing code is implemented.  This position
+	//  corresponds exactly to the rectangle returned by CTestProgCntrItem,
+	//  to give the effect of in-place editing.
+
+	// TODO: remove this code when final draw code is complete.
+	if (m_pSelection != NULL)
+	{
+		CSize size;
+		CRect rect(10, 10, 210, 210);
+		
+		if (m_pSelection->GetExtent(&size, m_pSelection->m_nDrawAspect))
+		{
+			pDC->HIMETRICtoLP(&size);
+			rect.right = size.cx + 10;
+			rect.bottom = size.cy + 10;
+		}
+		m_pSelection->Draw(pDC, rect);
+	}
+}
+
+void CTestProgView::OnInitialUpdate()
+{
+	CView::OnInitialUpdate();
+
+
+	// TODO: remove this code when final selection model code is written
+	m_pSelection = NULL;    // initialize selection
+
+}
+
+
+// CTestProgView printing
+
+BOOL CTestProgView::OnPreparePrinting(CPrintInfo* pInfo)
+{
+	// default preparation
+	return DoPreparePrinting(pInfo);
+}
+
+void CTestProgView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
+{
+	// TODO: add extra initialization before printing
+}
+
+void CTestProgView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
+{
+	// TODO: add cleanup after printing
+}
+
+void CTestProgView::OnDestroy()
+{
+	// Deactivate the item on destruction; this is important
+	// when a splitter view is being used
+   COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
+   if (pActiveItem != NULL && pActiveItem->GetActiveView() == this)
+   {
+      pActiveItem->Deactivate();
+      ASSERT(GetDocument()->GetInPlaceActiveItem(this) == NULL);
+   }
+   CView::OnDestroy();
+}
+
+
+
+// OLE Client support and commands
+
+BOOL CTestProgView::IsSelected(const CObject* pDocItem) const
+{
+	// The implementation below is adequate if your selection consists of
+	//  only CTestProgCntrItem objects.  To handle different selection
+	//  mechanisms, the implementation here should be replaced
+
+	// TODO: implement this function that tests for a selected OLE client item
+
+	return pDocItem == m_pSelection;
+}
+
+void CTestProgView::OnInsertObject()
+{
+	// Invoke the standard Insert Object dialog box to obtain information
+	//  for new CTestProgCntrItem object
+	COleInsertDialog dlg;
+	if (dlg.DoModal() != IDOK)
+		return;
+
+	BeginWaitCursor();
+
+	CTestProgCntrItem* pItem = NULL;
+	TRY
+	{
+		// Create new item connected to this document
+		CTestProgDoc* pDoc = GetDocument();
+		ASSERT_VALID(pDoc);
+		pItem = new CTestProgCntrItem(pDoc);
+		ASSERT_VALID(pItem);
+
+		// Initialize the item from the dialog data
+		if (!dlg.CreateItem(pItem))
+			AfxThrowMemoryException();  // any exception will do
+		ASSERT_VALID(pItem);
+		
+        if (dlg.GetSelectionType() == COleInsertDialog::createNewItem)
+			pItem->DoVerb(OLEIVERB_SHOW, this);
+
+		ASSERT_VALID(pItem);
+		// As an arbitrary user interface design, this sets the selection
+		//  to the last item inserted
+
+		// TODO: reimplement selection as appropriate for your application
+		m_pSelection = pItem;   // set selection to last inserted item
+		pDoc->UpdateAllViews(NULL);
+	}
+	CATCH(CException, e)
+	{
+		if (pItem != NULL)
+		{
+			ASSERT_VALID(pItem);
+			pItem->Delete();
+		}
+		AfxMessageBox(IDP_FAILED_TO_CREATE);
+	}
+	END_CATCH
+
+	EndWaitCursor();
+}
+
+// The following command handler provides the standard keyboard
+//  user interface to cancel an in-place editing session.  Here,
+//  the container (not the server) causes the deactivation
+void CTestProgView::OnCancelEditCntr()
+{
+	// Close any in-place active item on this view.
+	COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
+	if (pActiveItem != NULL)
+	{
+		pActiveItem->Close();
+	}
+	ASSERT(GetDocument()->GetInPlaceActiveItem(this) == NULL);
+}
+
+// Special handling of OnSetFocus and OnSize are required for a container
+//  when an object is being edited in-place
+void CTestProgView::OnSetFocus(CWnd* pOldWnd)
+{
+	COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
+	if (pActiveItem != NULL &&
+		pActiveItem->GetItemState() == COleClientItem::activeUIState)
+	{
+		// need to set focus to this item if it is in the same view
+		CWnd* pWnd = pActiveItem->GetInPlaceWindow();
+		if (pWnd != NULL)
+		{
+			pWnd->SetFocus();   // don't call the base class
+			return;
+		}
+	}
+
+	CView::OnSetFocus(pOldWnd);
+}
+
+void CTestProgView::OnSize(UINT nType, int cx, int cy)
+{
+	CView::OnSize(nType, cx, cy);
+	COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
+	if (pActiveItem != NULL)
+		pActiveItem->SetItemRects();
+}
+
+void CTestProgView::OnFilePrint()
+{
+	//By default, we ask the Active document to print itself
+	//using IOleCommandTarget. If you don't want this behavior
+	//remove the call to COleDocObjectItem::DoDefaultPrinting.
+	//If the call fails for some reason, we will try printing
+	//the docobject using the IPrint interface.
+	CPrintInfo printInfo;
+	ASSERT(printInfo.m_pPD != NULL); 
+	if (S_OK == COleDocObjectItem::DoDefaultPrinting(this, &printInfo))
+		return;
+	
+	CView::OnFilePrint();
+
+}
+
+
+
+// OLE Server support
+
+// The following command handler provides the standard keyboard
+//  user interface to cancel an in-place editing session.  Here,
+//  the server (not the container) causes the deactivation
+void CTestProgView::OnCancelEditSrvr()
+{
+	GetDocument()->OnDeactivateUI(FALSE);
+}
+
+
+// CTestProgView diagnostics
+
+#ifdef _DEBUG
+void CTestProgView::AssertValid() const
+{
+	CView::AssertValid();
+}
+
+void CTestProgView::Dump(CDumpContext& dc) const
+{
+	CView::Dump(dc);
+}
+
+CTestProgDoc* CTestProgView::GetDocument() const // non-debug version is inline
+{
+	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CTestProgDoc)));
+	return (CTestProgDoc*)m_pDocument;
+}
+#endif //_DEBUG
+
+
+// CTestProgView message handlers
Index: /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/TestProgView.h
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/TestProgView.h	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/TestProgView.h	(revision 540)
@@ -0,0 +1,67 @@
+// TestProgView.h : interface of the CTestProgView class
+//
+
+
+#pragma once
+
+class CTestProgCntrItem;
+
+class CTestProgView : public CView
+{
+protected: // create from serialization only
+	CTestProgView();
+	DECLARE_DYNCREATE(CTestProgView)
+
+// Attributes
+public:
+	CTestProgDoc* GetDocument() const;
+	// m_pSelection holds the selection to the current CTestProgCntrItem.
+	// For many applications, such a member variable isn't adequate to
+	//  represent a selection, such as a multiple selection or a selection
+	//  of objects that are not CTestProgCntrItem objects.  This selection
+	//  mechanism is provided just to help you get started
+
+	// TODO: replace this selection mechanism with one appropriate to your app
+	CTestProgCntrItem* m_pSelection;
+
+// Operations
+public:
+
+// Overrides
+public:
+	virtual void OnDraw(CDC* pDC);  // overridden to draw this view
+	virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
+protected:
+	virtual void OnInitialUpdate(); // called first time after construct
+	virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
+	virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
+	virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
+	virtual BOOL IsSelected(const CObject* pDocItem) const;// Container support
+
+// Implementation
+public:
+	virtual ~CTestProgView();
+#ifdef _DEBUG
+	virtual void AssertValid() const;
+	virtual void Dump(CDumpContext& dc) const;
+#endif
+
+protected:
+
+// Generated message map functions
+protected:
+	afx_msg void OnDestroy();
+	afx_msg void OnSetFocus(CWnd* pOldWnd);
+	afx_msg void OnSize(UINT nType, int cx, int cy);
+	afx_msg void OnInsertObject();
+	afx_msg void OnCancelEditCntr();
+	afx_msg void OnFilePrint();
+	afx_msg void OnCancelEditSrvr();
+	DECLARE_MESSAGE_MAP()
+};
+
+#ifndef _DEBUG  // debug version in TestProgView.cpp
+inline CTestProgDoc* CTestProgView::GetDocument() const
+   { return reinterpret_cast<CTestProgDoc*>(m_pDocument); }
+#endif
+
Index: /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/res/TestProg.rc2
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/res/TestProg.rc2	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/res/TestProg.rc2	(revision 540)
@@ -0,0 +1,13 @@
+//
+// TestProg.RC2 - resources Microsoft Visual C++ does not edit directly
+//
+
+#ifdef APSTUDIO_INVOKED
+#error this file is not editable by Microsoft Visual C++
+#endif //APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Add manually edited resources here...
+
+/////////////////////////////////////////////////////////////////////////////
Index: /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/resource.h
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/resource.h	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/resource.h	(revision 540)
@@ -0,0 +1,37 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by TestProg.rc
+//
+#define IDR_TestProgTYPE_SRVR_IP        4
+#define IDR_TestProgTYPE_SRVR_EMB       5
+#define IDR_TestProgTYPE_CNTR_IP        6
+#define IDD_ABOUTBOX                    100
+#define IDP_OLE_INIT_FAILED             100
+#define IDP_FAILED_TO_CREATE            102
+#define IDR_MAINFRAME                   128
+#define IDR_TestProgTYPE                129
+#define IDC_EDIT1                       1000
+#define IDC_CHECK1                      1001
+#define IDC_COMBO1                      1002
+#define IDC_RADIO1                      1003
+#define IDC_RADIO2                      1004
+#define IDC_RADIO3                      1005
+#define IDC_SLIDER1                     1006
+#define IDC_SPIN1                       1007
+#define IDC_SLIDER2                     1007
+#define IDC_LIST1                       1008
+#define IDC_TAB1                        1010
+#define IDC_TREE1                       1013
+#define ID_CANCEL_EDIT_CNTR             32768
+#define ID_CANCEL_EDIT_SRVR             32769
+
+// Next default values for new objects
+// 
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE        131
+#define _APS_NEXT_COMMAND_VALUE         32771
+#define _APS_NEXT_CONTROL_VALUE         1014
+#define _APS_NEXT_SYMED_VALUE           101
+#endif
+#endif
Index: /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/stdafx.cpp
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/stdafx.cpp	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/stdafx.cpp	(revision 540)
@@ -0,0 +1,7 @@
+// stdafx.cpp : source file that includes just the standard includes
+// TestProg.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+
Index: /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/stdafx.h
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/stdafx.h	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/stdafx.h	(revision 540)
@@ -0,0 +1,59 @@
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently,
+// but are changed infrequently
+
+#pragma once
+
+#ifndef _SECURE_ATL
+#define _SECURE_ATL 1
+#endif
+
+#ifndef VC_EXTRALEAN
+#define VC_EXTRALEAN            // Exclude rarely-used stuff from Windows headers
+#endif
+
+#include "targetver.h"
+
+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS      // some CString constructors will be explicit
+
+// turns off MFC's hiding of some common and often safely ignored warning messages
+#define _AFX_ALL_WARNINGS
+
+#include <afxwin.h>         // MFC core and standard components
+#include <afxext.h>         // MFC extensions
+
+#include <afxole.h>         // MFC OLE classes
+#include <afxodlgs.h>       // MFC OLE dialog classes
+
+#include <afxdisp.h>        // MFC Automation classes
+
+
+
+#ifndef _AFX_NO_OLE_SUPPORT
+#include <afxdtctl.h>           // MFC support for Internet Explorer 4 Common Controls
+#endif
+#ifndef _AFX_NO_AFXCMN_SUPPORT
+#include <afxcmn.h>                     // MFC support for Windows Common Controls
+#endif // _AFX_NO_AFXCMN_SUPPORT
+
+
+
+
+
+
+
+
+
+#ifdef _UNICODE
+#if defined _M_IX86
+#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
+#elif defined _M_IA64
+#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='ia64' publicKeyToken='6595b64144ccf1df' language='*'\"")
+#elif defined _M_X64
+#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
+#else
+#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
+#endif
+#endif
+
+
Index: /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/targetver.h
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/targetver.h	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/TestProg/targetver.h	(revision 540)
@@ -0,0 +1,26 @@
+
+#pragma once
+
+// The following macros define the minimum required platform.  The minimum required platform
+// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run 
+// your application.  The macros work by enabling all features available on platform versions up to and 
+// including the version specified.
+
+// Modify the following defines if you have to target a platform prior to the ones specified below.
+// Refer to MSDN for the latest info on corresponding values for different platforms.
+#ifndef WINVER                          // Specifies that the minimum required platform is Windows Vista.
+#define WINVER 0x0600           // Change this to the appropriate value to target other versions of Windows.
+#endif
+
+#ifndef _WIN32_WINNT            // Specifies that the minimum required platform is Windows Vista.
+#define _WIN32_WINNT 0x0600     // Change this to the appropriate value to target other versions of Windows.
+#endif
+
+#ifndef _WIN32_WINDOWS          // Specifies that the minimum required platform is Windows 98.
+#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.
+#endif
+
+#ifndef _WIN32_IE                       // Specifies that the minimum required platform is Internet Explorer 7.0.
+#define _WIN32_IE 0x0700        // Change this to the appropriate value to target other versions of IE.
+#endif
+
Index: /tags/quest-pre-eventrefactoring/MFCtooling/mfctooling.sln
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/mfctooling.sln	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/mfctooling.sln	(revision 540)
@@ -0,0 +1,70 @@
+﻿
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "userlog", "userlog\userlog.vcproj", "{A881CC90-25D4-4D76-A30D-C8CA09A3434D}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestProg", "TestProg\TestProg.vcproj", "{98889796-F392-4C4F-A619-BD2C1509B392}"
+	ProjectSection(ProjectDependencies) = postProject
+		{A881CC90-25D4-4D76-A30D-C8CA09A3434D} = {A881CC90-25D4-4D76-A30D-C8CA09A3434D}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "replay", "replay\replay.vcproj", "{6CDC762E-2D22-4B0F-B6CD-7F8AB432ED42}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug_Costumlog|Win32 = Debug_Costumlog|Win32
+		Debug_MTrace|Win32 = Debug_MTrace|Win32
+		Debug|Win32 = Debug|Win32
+		Release_Costumlog|Win32 = Release_Costumlog|Win32
+		Release_MTrace|Win32 = Release_MTrace|Win32
+		Release_ReplayOld|Win32 = Release_ReplayOld|Win32
+		Release|Win32 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{A881CC90-25D4-4D76-A30D-C8CA09A3434D}.Debug_Costumlog|Win32.ActiveCfg = Debug_Costumlog|Win32
+		{A881CC90-25D4-4D76-A30D-C8CA09A3434D}.Debug_Costumlog|Win32.Build.0 = Debug_Costumlog|Win32
+		{A881CC90-25D4-4D76-A30D-C8CA09A3434D}.Debug_MTrace|Win32.ActiveCfg = Debug_MTrace|Win32
+		{A881CC90-25D4-4D76-A30D-C8CA09A3434D}.Debug_MTrace|Win32.Build.0 = Debug_MTrace|Win32
+		{A881CC90-25D4-4D76-A30D-C8CA09A3434D}.Debug|Win32.ActiveCfg = Debug_MTrace|Win32
+		{A881CC90-25D4-4D76-A30D-C8CA09A3434D}.Debug|Win32.Build.0 = Debug_MTrace|Win32
+		{A881CC90-25D4-4D76-A30D-C8CA09A3434D}.Release_Costumlog|Win32.ActiveCfg = Release_Costumlog|Win32
+		{A881CC90-25D4-4D76-A30D-C8CA09A3434D}.Release_Costumlog|Win32.Build.0 = Release_Costumlog|Win32
+		{A881CC90-25D4-4D76-A30D-C8CA09A3434D}.Release_MTrace|Win32.ActiveCfg = Release_MTrace|Win32
+		{A881CC90-25D4-4D76-A30D-C8CA09A3434D}.Release_MTrace|Win32.Build.0 = Release_MTrace|Win32
+		{A881CC90-25D4-4D76-A30D-C8CA09A3434D}.Release_ReplayOld|Win32.ActiveCfg = Release_Costumlog|Win32
+		{A881CC90-25D4-4D76-A30D-C8CA09A3434D}.Release_ReplayOld|Win32.Build.0 = Release_Costumlog|Win32
+		{A881CC90-25D4-4D76-A30D-C8CA09A3434D}.Release|Win32.ActiveCfg = Release_MTrace|Win32
+		{A881CC90-25D4-4D76-A30D-C8CA09A3434D}.Release|Win32.Build.0 = Release_MTrace|Win32
+		{98889796-F392-4C4F-A619-BD2C1509B392}.Debug_Costumlog|Win32.ActiveCfg = Debug|Win32
+		{98889796-F392-4C4F-A619-BD2C1509B392}.Debug_Costumlog|Win32.Build.0 = Debug|Win32
+		{98889796-F392-4C4F-A619-BD2C1509B392}.Debug_MTrace|Win32.ActiveCfg = Debug|Win32
+		{98889796-F392-4C4F-A619-BD2C1509B392}.Debug_MTrace|Win32.Build.0 = Debug|Win32
+		{98889796-F392-4C4F-A619-BD2C1509B392}.Debug|Win32.ActiveCfg = Debug|Win32
+		{98889796-F392-4C4F-A619-BD2C1509B392}.Debug|Win32.Build.0 = Debug|Win32
+		{98889796-F392-4C4F-A619-BD2C1509B392}.Release_Costumlog|Win32.ActiveCfg = Release|Win32
+		{98889796-F392-4C4F-A619-BD2C1509B392}.Release_Costumlog|Win32.Build.0 = Release|Win32
+		{98889796-F392-4C4F-A619-BD2C1509B392}.Release_MTrace|Win32.ActiveCfg = Release|Win32
+		{98889796-F392-4C4F-A619-BD2C1509B392}.Release_MTrace|Win32.Build.0 = Release|Win32
+		{98889796-F392-4C4F-A619-BD2C1509B392}.Release_ReplayOld|Win32.ActiveCfg = Release|Win32
+		{98889796-F392-4C4F-A619-BD2C1509B392}.Release_ReplayOld|Win32.Build.0 = Release|Win32
+		{98889796-F392-4C4F-A619-BD2C1509B392}.Release|Win32.ActiveCfg = Release|Win32
+		{98889796-F392-4C4F-A619-BD2C1509B392}.Release|Win32.Build.0 = Release|Win32
+		{6CDC762E-2D22-4B0F-B6CD-7F8AB432ED42}.Debug_Costumlog|Win32.ActiveCfg = Debug|Win32
+		{6CDC762E-2D22-4B0F-B6CD-7F8AB432ED42}.Debug_Costumlog|Win32.Build.0 = Debug|Win32
+		{6CDC762E-2D22-4B0F-B6CD-7F8AB432ED42}.Debug_MTrace|Win32.ActiveCfg = Debug|Win32
+		{6CDC762E-2D22-4B0F-B6CD-7F8AB432ED42}.Debug_MTrace|Win32.Build.0 = Debug|Win32
+		{6CDC762E-2D22-4B0F-B6CD-7F8AB432ED42}.Debug|Win32.ActiveCfg = Debug|Win32
+		{6CDC762E-2D22-4B0F-B6CD-7F8AB432ED42}.Debug|Win32.Build.0 = Debug|Win32
+		{6CDC762E-2D22-4B0F-B6CD-7F8AB432ED42}.Release_Costumlog|Win32.ActiveCfg = Release|Win32
+		{6CDC762E-2D22-4B0F-B6CD-7F8AB432ED42}.Release_Costumlog|Win32.Build.0 = Release|Win32
+		{6CDC762E-2D22-4B0F-B6CD-7F8AB432ED42}.Release_MTrace|Win32.ActiveCfg = Release|Win32
+		{6CDC762E-2D22-4B0F-B6CD-7F8AB432ED42}.Release_MTrace|Win32.Build.0 = Release|Win32
+		{6CDC762E-2D22-4B0F-B6CD-7F8AB432ED42}.Release_ReplayOld|Win32.ActiveCfg = Release_ReplayOld|Win32
+		{6CDC762E-2D22-4B0F-B6CD-7F8AB432ED42}.Release_ReplayOld|Win32.Build.0 = Release_ReplayOld|Win32
+		{6CDC762E-2D22-4B0F-B6CD-7F8AB432ED42}.Release|Win32.ActiveCfg = Release|Win32
+		{6CDC762E-2D22-4B0F-B6CD-7F8AB432ED42}.Release|Win32.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
Index: /tags/quest-pre-eventrefactoring/MFCtooling/replay/LogParser.cpp
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/replay/LogParser.cpp	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/replay/LogParser.cpp	(revision 540)
@@ -0,0 +1,255 @@
+#include "StdAfx.h"
+#include "LogParser.h"
+
+#include <iostream>
+
+#include "WindowFinder.h"
+
+LogParser::LogParser(_TCHAR* runCommand, unsigned int startupTime, TestResults * results, bool useDefaultDelay) : runCommand(runCommand), startupTime(startupTime), results(results), useDefaultDelay(useDefaultDelay)
+{
+	workingPath = NULL;
+}
+
+LogParser::~LogParser(void)
+{
+	
+}
+
+
+
+HRESULT STDMETHODCALLTYPE LogParser::startElement( 
+			wchar_t __RPC_FAR *pwchNamespaceUri,
+			int cchNamespaceUri,
+			wchar_t __RPC_FAR *pwchLocalName,
+			int cchLocalName,
+			wchar_t __RPC_FAR *pwchRawName,
+			int cchRawName,
+			MSXML2::ISAXAttributes __RPC_FAR *pAttributes)
+{
+	std::wstring localName(pwchLocalName);
+	if( localName.compare(L"session")==0 ) {
+		sessionId = GetAttributeValue(pAttributes, L"id", L"");
+		std::wcout << L"================================================" << std::endl;
+		std::wcout << L"starting session " << sessionId << std::endl;
+		result.sessionPass = true;
+		result.errorMessage = L"";
+		result.msgNumber = 0;
+		currentMessage = 0;
+		std::wcout << L"executing " << runCommand << std::endl;
+		PROCESS_INFORMATION pi;
+		STARTUPINFO si;
+		ZeroMemory(&pi, sizeof(pi));
+		ZeroMemory(&si, sizeof(si));
+
+		CreateProcess(NULL, runCommand, NULL, NULL, FALSE, 0, NULL, workingPath, &si, &pi);
+
+		hProcess = pi.hProcess;
+		CloseHandle(pi.hThread);
+		
+		std::wcout << L"waiting " << startupTime << L" ms for application under test to intialize" << std::endl;
+		Sleep(startupTime);
+		std::wcout << L"replay starting..." << std::endl;
+	}
+	else if( localName.compare(L"msg")==0 ) {
+		std::wstring type = GetAttributeValue(pAttributes, L"type", L"");
+		msgType = _wtoi(type.c_str());
+		std::wstring lParamStr = GetAttributeValue(pAttributes, L"LPARAM", L"");
+		lParam = _wtoi(lParamStr.c_str());
+		std::wstring wParamStr = GetAttributeValue(pAttributes, L"WPARAM", L"");
+		wParam = _wtoi(wParamStr.c_str());
+		std::wstring delayStr = GetAttributeValue(pAttributes, L"delay", L"");
+		delay = _wtoi(delayStr.c_str());
+		currentWindow = NULL;
+		currentParent = NULL;
+	}
+	else if( localName.compare(L"window")==0 ) {
+		WindowData * winData = new WindowData;
+		winData->name = GetAttributeValue(pAttributes, L"name", L"");
+		winData->className = GetAttributeValue(pAttributes, L"class", L"");
+		std::wstring resourceIdStr = GetAttributeValue(pAttributes, L"resourceId", L"");
+		winData->resourceId = _wtoi(resourceIdStr.c_str());
+		std::wstring isModalStr = GetAttributeValue(pAttributes, L"isModal", L"");
+		if( isModalStr.compare(L"true")==0 ) {
+			winData->isModal = true;
+		} else {
+			winData->isModal = false;
+		}
+		winData->child = NULL;
+		if( currentWindow==NULL ) {
+			currentWindow = winData;
+		} else {
+			currentParent->child = winData;
+		}
+		currentParent = winData;
+	}
+	else if( localName.compare(L"textEquals")==0 ) {
+		expectedValue = GetAttributeValue(pAttributes, L"expectedValue", L"");
+	}
+	else if( localName.compare(L"fileEquals")==0) {
+		actualFile = GetAttributeValue(pAttributes, L"actualFile", L"");
+		expectedFile = GetAttributeValue(pAttributes, L"expectedFile", L"");
+	}
+
+	return S_OK;
+}
+
+
+HRESULT STDMETHODCALLTYPE LogParser::endElement( 
+			wchar_t __RPC_FAR *pwchNamespaceUri,
+			int cchNamespaceUri,
+			wchar_t __RPC_FAR *pwchLocalName,
+			int cchLocalName,
+			wchar_t __RPC_FAR *pwchRawName,
+			int cchRawName)
+{
+	std::wstring localName(pwchLocalName);
+	if( localName.compare(L"session")==0 ) {
+		std::wcout << L"session completed" << std::endl;
+		results->addResult(sessionId, result);
+		BOOL retVal = TerminateProcess(hProcess, 0);
+		if( retVal!=0 ) {
+			std::wcout << L"application terminated" << std::endl;
+		}
+		CloseHandle(hProcess);
+	} 
+	else if( localName.compare(L"msg")==0 ) {
+		currentMessage++;
+		WindowFinder finder;
+		HWND hwnd = finder.find(currentWindow);
+		// check if window was found, if not test has failed
+		if( result.sessionPass ) {
+			result.sessionPass = false;
+			result.errorMessage = finder.getErrorMessage();
+			result.msgNumber = currentMessage;
+		}
+
+		sendMessage(hwnd);
+		deleteWindowData(currentWindow);
+		currentWindow = NULL;
+	} 
+	else if( localName.compare(L"LPARAM")==0 ) {
+		WindowFinder finder;
+		HWND hwnd = finder.find(currentWindow);
+		lParam = (LPARAM) hwnd;
+		deleteWindowData(currentWindow);
+		currentWindow = NULL;
+	}
+	else if( localName.compare(L"WPARAM")==0 ) {
+		WindowFinder finder;
+		HWND hwnd = finder.find(currentWindow);
+		wParam = (WPARAM) hwnd;
+		deleteWindowData(currentWindow);
+		currentWindow = NULL;
+	}
+	else if( localName.compare(L"textEquals")==0 ) {
+		WindowFinder finder;
+		HWND hwnd = finder.find(currentWindow);
+
+		wchar_t* wstr = new wchar_t[256];
+		wstr[0] = '\0';
+		
+		//GetWindowText is not working properly for EditControls in other applications -> send WM_GETTEXT instead
+		SendMessage(hwnd, WM_GETTEXT, 255, (LPARAM)wstr);
+		std::wstring windowText = wstr;
+
+		if(expectedValue == windowText) std::wcout << std::endl << L"textEquals passed (expected value: " << expectedValue.c_str() << ")" << std::endl << std::endl;
+		else std::wcout << std::endl << L"textEquals failed (expected value: " << expectedValue.c_str() << ", windowText: " << windowText << ")" << std::endl << std::endl;
+		deleteWindowData(currentWindow);
+		currentWindow = NULL;
+	}
+	else if( localName.compare(L"fileEquals")==0) {
+		std::ifstream f1(actualFile.c_str(), std::ios_base::in | std::ios_base::binary);
+		if(f1 == NULL) {
+
+			std::wcout << std::endl << L"fileEquals failed because " << actualFile << " is not available!"<< std::endl << std::endl;
+			return S_OK;
+		}
+
+		std::ifstream f2(expectedFile.c_str(), std::ios_base::in | std::ios_base::binary);
+		if(f2 == NULL) {
+			std::wcout << std::endl << L"fileEquals failed because " << expectedFile << " is not available!" << std::endl << std::endl;
+			return S_OK;
+		}
+
+		f1.seekg(0, std::ios_base::end);
+		f2.seekg(0, std::ios_base::end);
+		std::streamsize length1 = f1.tellg();
+		std::streamsize length2 = f2.tellg();
+
+		bool passed = true;
+
+		if (length1 != length2) { // Non equal length -> files differ
+			passed = false;
+		}
+		else {
+			f1.seekg(0);
+			f2.seekg(0);
+
+			const std::streamsize blocksize = 4096;
+			char block1[blocksize], block2[blocksize];
+
+			for (std::streamsize counter=length1; counter > 0; counter -= blocksize)
+			{				
+				f1.read(block1, blocksize);
+				f2.read(block2, blocksize);
+
+				if(memcmp(block1, block2, blocksize) != 0) { //block are non equal -> files differ
+					passed = false;
+					break;
+				}
+			}
+		}
+
+		if(passed) {
+			std::wcout << std::endl << L"FileEquals passed" << std::endl << std::endl;
+		}
+		else {
+			std::wcout << std::endl << L"fileEquals failed (expectedFile: " << expectedFile.c_str() << ", actualFile: " << actualFile << ")" << std::endl << std::endl;
+		}
+		
+		f1.close();
+		f2.close();
+	}
+
+	return S_OK;
+}
+
+std::wstring LogParser::GetAttributeValue(MSXML2::ISAXAttributes __RPC_FAR *pAttributes,
+							   std::wstring name, std::wstring defvalue)
+{
+	// get the number of attributes
+	int length = 0;
+	pAttributes->getLength(&length);
+
+	// enumerate over all attributes
+	for ( int i=0; i<length; i++ ) 
+	{
+		wchar_t *attrname = NULL, * attrvalue = NULL;
+		int namelen = 0, valuelen = 0;
+
+		// get the local name of the current attribute
+		pAttributes->getLocalName(i,&attrname,&namelen);
+		// get the value of the current attribute
+		pAttributes->getValue(i,&attrvalue,&valuelen);
+		// if current attribute is the one needed return its value
+		if(name.compare(std::wstring(attrname,namelen)) == 0)
+			return std::wstring(attrvalue, valuelen);
+	}
+
+	// attribute not found; return the default value
+	return defvalue;
+}
+
+void LogParser::sendMessage(HWND hwnd) {
+	std::wcout << L"  Sending " << msgType << L" to " << hwnd << "L - LPARAM: " << lParam << L" - WPARAM: " << wParam << std::endl;
+	PostMessage(hwnd, msgType, wParam, lParam);
+	if( useDefaultDelay ) {
+		Sleep(defaultMsgDelay);
+	} else {
+		Sleep(delay);
+	}
+}
+
+void LogParser::setWorkingPath(TCHAR * workingPath) {
+	this->workingPath = workingPath;
+}
Index: /tags/quest-pre-eventrefactoring/MFCtooling/replay/LogParser.h
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/replay/LogParser.h	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/replay/LogParser.h	(revision 540)
@@ -0,0 +1,68 @@
+#pragma once
+
+#include "SAXContentHandlerImpl.h"
+#include <string>
+
+#include "WindowData.h"
+#include "TestResults.h"
+
+class LogParser : public SAXContentHandlerImpl
+{
+private:
+	static const int defaultMsgDelay = 500;
+	WindowData * currentWindow;
+	WindowData * currentParent;
+
+	int msgType;
+	LPARAM lParam;
+	WPARAM wParam;
+
+	boolean useDefaultDelay;
+	int delay;
+
+	void sendMessage(HWND hwnd);
+
+	_TCHAR * runCommand;
+	_TCHAR * workingPath;
+	unsigned int startupTime;
+	HANDLE hProcess;
+
+	std::wstring sessionId;
+	RESULT result;
+	unsigned int currentMessage;
+
+	TestResults * results;
+
+	std::wstring expectedValue;
+	std::wstring actualFile;
+	std::wstring expectedFile;
+
+public:
+	LogParser(_TCHAR * runCommand, unsigned int startupChar, TestResults * results, bool useDefaultDelay = false);
+	~LogParser(void);
+
+	virtual HRESULT STDMETHODCALLTYPE startElement( 
+			wchar_t __RPC_FAR *pwchNamespaceUri,
+			int cchNamespaceUri,
+			wchar_t __RPC_FAR *pwchLocalName,
+			int cchLocalName,
+			wchar_t __RPC_FAR *pwchRawName,
+			int cchRawName,
+			MSXML2::ISAXAttributes __RPC_FAR *pAttributes);
+
+	virtual HRESULT STDMETHODCALLTYPE endElement( 
+			wchar_t __RPC_FAR *pwchNamespaceUri,
+			int cchNamespaceUri,
+			wchar_t __RPC_FAR *pwchLocalName,
+			int cchLocalName,
+			wchar_t __RPC_FAR *pwchRawName,
+			int cchRawName);
+
+	std::wstring GetAttributeValue(MSXML2::ISAXAttributes __RPC_FAR *pAttributes,
+							   std::wstring name, std::wstring defvalue);
+
+
+	int getDefaultMsgDelay();
+
+	void setWorkingPath(TCHAR * workingPath);
+};
Index: /tags/quest-pre-eventrefactoring/MFCtooling/replay/SAXContentHandlerImpl.h
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/replay/SAXContentHandlerImpl.h	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/replay/SAXContentHandlerImpl.h	(revision 540)
@@ -0,0 +1,104 @@
+#pragma once
+
+
+class SAXContentHandlerImpl : public MSXML2::ISAXContentHandler  
+{
+	long m_RefCount;
+public:
+	SAXContentHandlerImpl():m_RefCount(0) {}
+	virtual ~SAXContentHandlerImpl() {}
+
+	long __stdcall QueryInterface(const struct _GUID &riid, void ** ppObj)
+		{ 
+			if (riid == IID_IUnknown)
+			{
+				*ppObj = static_cast<IUnknown*>(this);
+			}
+			if (riid == __uuidof(ISAXContentHandler))
+			{
+				*ppObj = static_cast<ISAXContentHandler*>(this);
+			}
+			else
+			{
+				*ppObj = NULL ;
+				return E_NOINTERFACE ;
+			}
+
+			AddRef() ;
+			return S_OK;
+		}
+	unsigned long __stdcall AddRef(void)
+		{
+			return InterlockedIncrement(&m_RefCount);
+		}
+	unsigned long __stdcall Release(void)
+		{
+			long nRefCount=0;
+			nRefCount=InterlockedDecrement(&m_RefCount) ;
+			if (nRefCount == 0) delete this;
+			return nRefCount;
+		}
+
+	virtual HRESULT STDMETHODCALLTYPE putDocumentLocator( 
+		MSXML2::ISAXLocator __RPC_FAR *pLocator)
+		{return S_OK;}
+
+	virtual HRESULT STDMETHODCALLTYPE startDocument( void)
+		{return S_OK;}
+        
+	virtual HRESULT STDMETHODCALLTYPE endDocument( void)
+		{return S_OK;}
+        
+	virtual HRESULT STDMETHODCALLTYPE startPrefixMapping( 
+			wchar_t __RPC_FAR *pwchPrefix,
+			int cchPrefix,
+			wchar_t __RPC_FAR *pwchUri,
+			int cchUri)
+		{return S_OK;}
+        
+	virtual HRESULT STDMETHODCALLTYPE endPrefixMapping( 
+			wchar_t __RPC_FAR *pwchPrefix,
+			int cchPrefix)
+		{return S_OK;}
+        
+	virtual HRESULT STDMETHODCALLTYPE startElement( 
+			wchar_t __RPC_FAR *pwchNamespaceUri,
+			int cchNamespaceUri,
+			wchar_t __RPC_FAR *pwchLocalName,
+			int cchLocalName,
+			wchar_t __RPC_FAR *pwchRawName,
+			int cchRawName,
+			MSXML2::ISAXAttributes __RPC_FAR *pAttributes)
+		{return S_OK;}
+        
+	virtual HRESULT STDMETHODCALLTYPE endElement( 
+			wchar_t __RPC_FAR *pwchNamespaceUri,
+			int cchNamespaceUri,
+			wchar_t __RPC_FAR *pwchLocalName,
+			int cchLocalName,
+			wchar_t __RPC_FAR *pwchRawName,
+			int cchRawName)
+		{return S_OK;}
+        
+	virtual HRESULT STDMETHODCALLTYPE characters( 
+			wchar_t __RPC_FAR *pwchChars,
+			int cchChars)
+		{return S_OK;}
+        
+	virtual HRESULT STDMETHODCALLTYPE ignorableWhitespace( 
+			wchar_t __RPC_FAR *pwchChars,
+			int cchChars)
+		{return S_OK;}
+        
+	virtual HRESULT STDMETHODCALLTYPE processingInstruction( 
+			wchar_t __RPC_FAR *pwchTarget,
+			int cchTarget,
+			wchar_t __RPC_FAR *pwchData,
+			int cchData)
+		{return S_OK;}
+        
+	virtual HRESULT STDMETHODCALLTYPE skippedEntity( 
+			wchar_t __RPC_FAR *pwchName,
+			int cchName)
+		{return S_OK;}
+};
Index: /tags/quest-pre-eventrefactoring/MFCtooling/replay/TestResults.cpp
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/replay/TestResults.cpp	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/replay/TestResults.cpp	(revision 540)
@@ -0,0 +1,38 @@
+#include "StdAfx.h"
+#include "TestResults.h"
+
+TestResults::TestResults(_TCHAR * replayFile) : replayFile(replayFile)
+{
+}
+
+TestResults::~TestResults(void)
+{
+}
+
+
+void TestResults::addResult(std::wstring sessionId, RESULT result)
+{
+	results.push_back(std::pair<std::wstring, RESULT>(sessionId, result));
+}
+
+
+void TestResults::write(_TCHAR * resultFile) {
+	std::wofstream file(resultFile, std::ios_base::trunc);
+
+	file << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl; // TODO check encoding
+	file << "<results file=\"" << replayFile << "\">" << std::endl;
+	for( size_t i=0; i<results.size() ; i++ ) {
+		RESULT & result = results[i].second;
+		file << "  <session id=\"" << results[i].first << "\" verdict=\"";
+		if( result.sessionPass==true ) {
+			file << "pass\"/>" << std::endl;
+		} else {
+			file << "fail\">"; // TODO
+			file << "    <details msgNo=\"" << result.msgNumber << "\" errMsg=\"" << result.errorMessage << "\"/>" << std::endl;
+			file << "  </session>" << std::endl;
+		}
+	}
+	file << "</results>" << std::endl;
+	file.flush();
+	file.close();
+}
Index: /tags/quest-pre-eventrefactoring/MFCtooling/replay/TestResults.h
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/replay/TestResults.h	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/replay/TestResults.h	(revision 540)
@@ -0,0 +1,24 @@
+#pragma once
+
+#include <string>
+#include <vector>
+#include <fstream>
+
+typedef struct _RESULT {
+	bool sessionPass;
+	std::wstring errorMessage;
+	int msgNumber;
+} RESULT;
+
+class TestResults
+{
+private:
+	std::vector<std::pair<std::wstring, RESULT>> results;	
+	_TCHAR * replayFile;
+public:
+	TestResults(_TCHAR * replayFile);
+	~TestResults(void);
+
+	void addResult(std::wstring sessionId, RESULT result);
+	void write(_TCHAR * resultFile);
+};
Index: /tags/quest-pre-eventrefactoring/MFCtooling/replay/WindowData.cpp
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/replay/WindowData.cpp	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/replay/WindowData.cpp	(revision 540)
@@ -0,0 +1,9 @@
+#include "StdAfx.h"
+#include "WindowData.h"
+
+void deleteWindowData(WindowData * winData) {
+	if( winData!=NULL ) {
+		deleteWindowData(winData->child);
+		delete winData;
+	}
+}
Index: /tags/quest-pre-eventrefactoring/MFCtooling/replay/WindowData.h
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/replay/WindowData.h	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/replay/WindowData.h	(revision 540)
@@ -0,0 +1,20 @@
+#pragma once
+
+#include <string>
+
+typedef struct WindowDataStruct {
+	std::wstring name;
+	std::wstring className;
+	int resourceId;
+	bool isModal;
+	WindowDataStruct * child;
+
+	/*void deleteChildren() {
+		if( child!=NULL ) {
+			child.deleteChilren();
+			delete child;
+		}
+	}*/
+} WindowData;
+
+void deleteWindowData(WindowData * winData);
Index: /tags/quest-pre-eventrefactoring/MFCtooling/replay/WindowFinder.cpp
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/replay/WindowFinder.cpp	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/replay/WindowFinder.cpp	(revision 540)
@@ -0,0 +1,143 @@
+#include "StdAfx.h"
+#include "WindowFinder.h"
+
+#include <algorithm>
+#include <iostream>
+
+BOOL CALLBACK EnumChildren(HWND hwnd, LPARAM lParam) {
+	int resourceId = 0;
+	int windowTextLen = 128;
+	wchar_t * windowText = new wchar_t[128];
+	int classNameLen = 128;
+	wchar_t * className = new wchar_t[128];
+
+	WindowFinder * finder = (WindowFinder*) lParam;
+
+	resourceId = GetDlgCtrlID(hwnd);
+	windowTextLen = GetWindowText(hwnd, windowText, windowTextLen);
+	classNameLen = GetClassName(hwnd, className, classNameLen);
+
+	finder->setEqualityScore(hwnd,resourceId, windowText, className);
+	
+	return TRUE;
+}
+
+WindowFinder::WindowFinder()
+{
+	evalPopup = false;
+	parentHandles = NULL;
+	success = true;
+}
+
+WindowFinder::~WindowFinder(void)
+{
+}
+
+HWND WindowFinder::find(WindowData * winData) {
+	currentWindow = winData;
+	maxScore = 0;
+	scores = new std::vector<std::pair<HWND, int>>();
+
+	if( parentHandles==NULL ) {
+		EnumWindows(EnumChildren, (LPARAM) this);
+	} else {
+		if( winData->isModal ) {
+			evalPopup = true;
+			EnumWindows(EnumChildren, (LPARAM) this);
+			evalPopup = false;
+		} else {
+			for( size_t i=0 ; i<parentHandles->size() ; i++ ) {
+				EnumChildWindows((*parentHandles)[i], EnumChildren, (LPARAM) this);
+			}
+		}
+		delete parentHandles;
+	}
+	parentHandles = new std::vector<HWND>();
+	for( size_t i=0 ; i<scores->size() ; i++ ) {
+		if( (*scores)[i].second==maxScore ) {
+			parentHandles->push_back((*scores)[i].first);
+		}
+	}
+	delete scores;
+	
+	HWND result = NULL;
+
+	if( winData->child!=NULL ) {
+		if( maxScore==0 ) {
+			std::wcerr << L"Warning: Score is zero." << std::endl;
+			errorMessage = L"score zero";
+			success = false;
+		}
+		result = find(winData->child);
+	} else {
+		if( parentHandles->size()==0 ) {
+			std::wcerr << L"Error: handle not found." << std::endl;
+			errorMessage = L"handle not found";
+			result = NULL;
+			success = false;
+		}
+		else {
+			if( parentHandles->size()!=1 ) {
+				std::wcerr << L"Warning: more than one fitting window found." << std::endl;
+				errorMessage = L"multiple matches";
+				success = false;
+			}
+			if( maxScore==0 ) {
+				std::wcerr << L"Warning: Score is zero." << std::endl;
+				errorMessage = L"score zero";
+				success = false;
+			}
+			result = (*parentHandles)[0];
+			delete parentHandles;
+		}
+	}
+	return result;
+}
+
+
+void WindowFinder::setEqualityScore(HWND hwnd, int resourceId, wchar_t * windowName, wchar_t * className) {
+	int score = 0;
+
+	if( resourceId!=0 && currentWindow->resourceId==resourceId && currentWindow->name.compare(windowName)==0 && currentWindow->className.compare(className)==0 ) {
+		score = 6;
+	}
+	else if( resourceId!=0 && currentWindow->resourceId==resourceId && currentWindow->name.compare(windowName)==0 ) {
+		score = 5;
+	}
+	else if( resourceId!=0 && currentWindow->resourceId==resourceId ) {
+		score = 4;
+	}
+	else if( currentWindow->name.compare(windowName)==0 && currentWindow->className.compare(className)==0 ) {
+		score = 3;
+	}
+	else if( currentWindow->name.compare(windowName)==0 ) {
+		score = 2;
+	}
+	else if( currentWindow->className.compare(className)==0 ) {
+		score = 1;
+	}
+	if( evalPopup ) {
+		HWND parent = GetParent(hwnd);
+		if( std::find(parentHandles->begin(), parentHandles->end(), parent)==parentHandles->end() ) {
+			score = 0;
+		}
+	}
+
+	scores->push_back(std::make_pair(hwnd, score));
+
+	if( score>maxScore ) {
+		maxScore = score;
+	}
+}
+
+bool WindowFinder::isCurrentPopup() {
+	return evalPopup;
+}
+
+bool WindowFinder::successfull() {
+	return success;
+}
+
+std::wstring WindowFinder::getErrorMessage() {
+	return errorMessage;
+}
Index: /tags/quest-pre-eventrefactoring/MFCtooling/replay/WindowFinder.h
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/replay/WindowFinder.h	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/replay/WindowFinder.h	(revision 540)
@@ -0,0 +1,40 @@
+#pragma once
+
+#include "WindowData.h"
+#include <map>
+#include <vector>
+
+BOOL CALLBACK EnumChildren(HWND hwnd, LPARAM lParam);
+
+class WindowFinder
+{
+private:
+	WindowData * currentWindow;
+
+	std::vector<std::pair<HWND,int>> * scores;
+
+	std::vector<HWND> * parentHandles;
+
+	int maxScore;
+
+	bool evalPopup;
+
+	bool success;
+
+	std::wstring errorMessage;
+
+public:
+	WindowFinder(void);
+	~WindowFinder(void);
+
+	HWND find(WindowData * winData);
+
+	void setEqualityScore(HWND hwnd, int resourceId, wchar_t * windowName, wchar_t * className);
+
+	bool isCurrentPopup();
+
+	bool successfull();
+
+	std::wstring getErrorMessage();
+
+};
Index: /tags/quest-pre-eventrefactoring/MFCtooling/replay/options.cpp
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/replay/options.cpp	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/replay/options.cpp	(revision 540)
@@ -0,0 +1,1147 @@
+// ****************************************************************************
+// ^FILE: options.c - implement the functions defined in <options.h>
+//
+// ^HISTORY:
+//    01/16/92	Brad Appleton	<bradapp@enteract.com>	Created
+//
+//    03/23/93	Brad Appleton	<bradapp@enteract.com>
+//    - Added OptIstreamIter class
+//
+//    10/08/93	Brad Appleton	<bradapp@enteract.com>
+//    - Added "hidden" options
+//
+//    02/08/94	Brad Appleton	<bradapp@enteract.com>
+//    - Added "OptionSpec" class
+//    - Permitted use of stdio instead of iostreams via #ifdef USE_STDIO
+//
+//    03/08/94	Brad Appleton	<bradapp@enteract.com>
+//    - completed support for USE_STDIO
+//    - added #ifdef NO_USAGE for people who always want to print their own
+//    - Fixed stupid NULL pointer error in OptionsSpec class
+//
+//    07/31/97	Brad Appleton	<bradapp@enteract.com>
+//    - Added PARSE_POS control flag and POSITIONAL return value.
+// ^^**************************************************************************
+
+#include "StdAfx.h"
+#ifdef USE_STDIO
+# include <stdio.h>
+#else
+# include <iostream>
+#endif
+
+using namespace std;
+
+// #include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+
+#include "options.h"
+
+extern "C" {
+   void  exit(int);
+}
+
+static const char ident[] = "@(#)Options  1.05" ;
+
+   // I need a portable version of "tolower" that does NOT modify
+   // non-uppercase characters.
+   //
+#define  TOLOWER(c)  (isupper(c) ? tolower(c) : c)
+
+   // Use this to shut the compiler up about NULL strings
+#define  NULLSTR  (char *)NULL
+
+// ******************************************************** insertion operators
+
+  // If you are using <stdio.h> then you need this stuff!
+  // If you are using <iostream.h> then #ifdef this stuff out
+  //
+
+
+#ifdef  USE_STDIO
+
+   // Implement just enough of ostream to get this file to compile
+   //
+
+static const char endl = '\n' ;
+
+class  ostream {
+public:
+   ostream(FILE * fileptr) : fp(fileptr) {}
+
+   ostream &
+   operator<<(char ch);
+
+   ostream &
+   operator<<(const char * str);
+
+   ostream &
+   write(const char * buf, unsigned bufsize);
+
+private:
+   FILE * fp;
+} ;
+
+ostream &
+ostream::operator<<(char ch) {
+   fputc(ch, fp);
+   return *this;
+}
+
+ostream &
+ostream::operator<<(const char * str) {
+   fputs(str, fp);
+   return *this;
+}
+
+ostream &
+ostream::write(const char * buf, unsigned ) {
+   fputs(buf, fp);
+   return *this;
+}
+
+static  ostream  cerr(stderr);
+static  ostream  cout(stdout);
+
+#endif  /* USE_STDIO */
+
+// ************************************************************** OptIter
+
+OptIter::~OptIter(void) {}
+
+const char *
+OptIter::operator()(void)  {
+   const char * elt = curr();
+   (void) next();
+   return  elt;
+}
+
+// ************************************************************** OptIterRwd
+
+OptIterRwd::OptIterRwd(void) {}
+
+OptIterRwd::~OptIterRwd(void) {}
+
+// ************************************************************** OptArgvIter
+
+OptArgvIter::~OptArgvIter(void) {}
+
+const char *
+OptArgvIter::curr(void) {
+   return ((ndx == ac) || (av[ndx] == NULL)) ? NULLSTR : av[ndx];
+}
+
+void
+OptArgvIter::next(void) {
+   if ((ndx != ac) && av[ndx]) ++ndx;
+}
+
+const char *
+OptArgvIter::operator()(void) {
+   return ((ndx == ac) || (av[ndx] == NULL)) ? NULLSTR : av[ndx++];
+}
+
+void
+OptArgvIter::rewind(void) { ndx = 0; }
+
+// ************************************************************** OptStrTokIter
+
+static const char WHITESPACE[] = " \t\n\r\v\f" ;
+const char * OptStrTokIter::default_delims = WHITESPACE ;
+
+OptStrTokIter::OptStrTokIter(const char * tokens, const char * delimiters)
+   : len(unsigned(strlen(tokens))), str(tokens), seps(delimiters),
+     cur(NULLSTR), tokstr(NULLSTR)
+{
+   if (seps == NULL)  seps = default_delims;
+   tokstr = new char[len + 1];
+   (void) ::strcpy(tokstr, str);
+   cur = ::strtok(tokstr, seps);
+}
+
+
+OptStrTokIter::~OptStrTokIter(void) { delete [] tokstr; }
+
+const char *
+OptStrTokIter::curr(void) { return cur; }
+
+void
+OptStrTokIter::next(void) { if (cur) cur = ::strtok(NULL, seps); }
+
+const char *
+OptStrTokIter::operator()(void) {
+   const char * elt = cur;
+   if (cur) cur = ::strtok(NULL, seps);
+   return  elt;
+}
+
+void
+OptStrTokIter::rewind(void) {
+   (void) ::strcpy(tokstr, str);
+   cur = ::strtok(tokstr, seps);
+}
+
+// ************************************************************* OptIstreamIter
+
+#ifdef vms
+   enum { c_COMMENT = '!' } ;
+#else
+   enum { c_COMMENT = '#' } ;
+#endif
+
+const unsigned  OptIstreamIter::MAX_LINE_LEN = 1024 ;
+
+   // Constructor
+OptIstreamIter::OptIstreamIter(istream & input) : is(input), tok_iter(NULL)
+{
+#ifdef  USE_STDIO
+   fprintf(stderr, "%s: Can't use OptIstreamIter class:\n",
+                   "OptIstreamIter::OptIstreamIter");
+   fprintf(stderr, "\tOptions(3C++) was compiled with USE_STDIO #defined.\n");
+   exit(-1);
+#endif  /* USE_STDIO */
+}
+
+   // Destructor
+OptIstreamIter::~OptIstreamIter(void) {
+   delete  tok_iter;
+}
+
+const char *
+OptIstreamIter::curr(void) {
+#ifdef  USE_STDIO
+   return  NULLSTR;
+#else
+   const char * result = NULLSTR;
+   if (tok_iter)  result = tok_iter->curr();
+   if (result)  return  result;
+   fill();
+   return (! is) ? NULLSTR : tok_iter->curr();
+#endif  /* USE_STDIO */
+}
+
+void
+OptIstreamIter::next(void) {
+#ifdef  USE_STDIO
+   return;
+#else
+   const char * result = NULLSTR;
+   if (tok_iter)  result = tok_iter->operator()();
+   if (result)  return;
+   fill();
+   if (! is) tok_iter->next();
+#endif  /* USE_STDIO */
+}
+
+const char *
+OptIstreamIter::operator()(void) {
+#ifdef  USE_STDIO
+   return  NULLSTR;
+#else
+   const char * result = NULLSTR;
+   if (tok_iter)  result = tok_iter->operator()();
+   if (result)  return  result;
+   fill();
+   return (! is) ? NULLSTR : tok_iter->operator()();
+#endif  /* USE_STDIO */
+}
+
+   // What we do is this: for each line of text in the istream, we use
+   // a OptStrTokIter to iterate over each token on the line.
+   //
+   // If the first non-white character on a line is c_COMMENT, then we
+   // consider the line to be a comment and we ignore it.
+   //
+void
+OptIstreamIter::fill(void) {
+#ifdef USE_STDIO
+   return;
+#else
+   char buf[OptIstreamIter::MAX_LINE_LEN];
+   do {
+      *buf = '\0';
+      is.getline(buf, sizeof(buf));
+      char * ptr = buf;
+      while (isspace(*ptr)) ++ptr;
+      if (*ptr && (*ptr != c_COMMENT)) {
+         delete  tok_iter;
+         tok_iter = new OptStrTokIter(ptr);
+         return;
+      }
+   } while (is);
+#endif  /* USE_STDIO */
+}
+
+// **************************************************** Options class utilities
+
+   // Is this option-char null?
+inline static int
+isNullOpt(char optchar) {
+   return  ((! optchar) || isspace(optchar) || (! isprint(optchar)));
+}
+   
+   // Check for explicit "end-of-options"
+inline static int
+isEndOpts(const char * token) {
+   return ((token == NULL) || (! ::strcmp(token, "--"))) ;
+}
+
+   // See if an argument is an option
+inline static int
+isOption(unsigned  flags, const char * arg) {
+   return  (((*arg != '\0') || (arg[1] != '\0')) &&
+            ((*arg == '-')  || ((flags & Options::PLUS) && (*arg == '+')))) ;
+}
+
+   // See if we should be parsing only options or if we also need to
+   // parse positional arguments
+inline static int
+isOptsOnly(unsigned  flags) {
+   return  (flags & Options::PARSE_POS) ? 0 : 1;
+}
+
+   // return values for a keyword matching function
+enum kwdmatch_t { NO_MATCH, PARTIAL_MATCH, EXACT_MATCH } ;
+
+// ---------------------------------------------------------------------------
+// ^FUNCTION: kwdmatch - match a keyword
+//
+// ^SYNOPSIS:
+//    static kwdmatch_t kwdmatch(src, attempt, len)
+//
+// ^PARAMETERS:
+//    char * src -- the actual keyword to match
+//    char * attempt -- the possible keyword to compare against "src"
+//    int len -- number of character of "attempt" to consider
+//               (if 0 then we should use all of "attempt")
+//
+// ^DESCRIPTION:
+//    See if "attempt" matches some prefix of "src" (case insensitive).
+//
+// ^REQUIREMENTS:
+//    - attempt should be non-NULL and non-empty
+//
+// ^SIDE-EFFECTS:
+//    None.
+//
+// ^RETURN-VALUE:
+//    An enumeration value of type kwdmatch_t corresponding to whether
+//    We had an exact match, a partial match, or no match.
+//
+// ^ALGORITHM:
+//    Trivial
+// ^^-------------------------------------------------------------------------
+static kwdmatch_t
+kwdmatch(const char * src, const char * attempt, int len =0) {
+   int  i;
+
+   if (src == attempt)  return  EXACT_MATCH ;
+   if ((src == NULL) || (attempt == NULL))  return  NO_MATCH ;
+   if ((! *src) && (! *attempt))  return  EXACT_MATCH ;
+   if ((! *src) || (! *attempt))  return  NO_MATCH ;
+
+   for (i = 0 ; ((i < len) || (len == 0)) &&
+                (attempt[i]) && (attempt[i] != ' ') ; i++) {
+      if (TOLOWER(src[i]) != TOLOWER(attempt[i]))  return  NO_MATCH ;
+   }
+
+   return  (src[i]) ? PARTIAL_MATCH : EXACT_MATCH ;
+}
+
+// **************************************************************** OptionSpec
+
+   // Class that represents an option-specification
+   //    *NOTE*:: Assumes that the char-ptr given to the constructor points
+   //             to storage that will NOT be modified and whose lifetime will
+   //             be as least as long as the OptionSpec object we construct.
+   //
+class OptionSpec {
+public:
+   OptionSpec(const char * decl =NULLSTR)
+      : hidden(0), spec(decl)
+   {
+      if (spec == NULL)  spec = NULL_spec;
+      CheckHidden();
+   }
+
+   OptionSpec(const OptionSpec & cp) : hidden(cp.hidden), spec(cp.spec) {}
+
+   // NOTE: use default destructor!
+
+      // Assign to another OptionSpec
+   OptionSpec &
+   operator=(const OptionSpec & cp) {
+      if (this != &cp) {
+         spec = cp.spec;
+         hidden = cp.hidden;
+      }
+      return *this;
+   }
+
+      // Assign to a string
+   OptionSpec &
+   operator=(const char * decl) {
+      if (spec != decl) {
+         spec = decl;
+         hidden = 0;
+         CheckHidden();
+      }
+      return *this;
+   }
+
+      // Convert to char-ptr by returning the original declaration-string
+   operator const char*() { return  isHiddenOpt() ? (spec - 1) : spec; }
+
+      // Is this option NULL?
+   int
+   isNULL(void) const { return ((spec == NULL) || (spec == NULL_spec)); }
+
+      // Is this options incorrectly specified?
+   int
+   isSyntaxError(const char * name) const;
+
+      // See if this is a Hidden option
+   int
+   isHiddenOpt(void) const { return  hidden; }
+
+      // Get the corresponding option-character
+   char
+   OptChar(void) const { return  *spec; }
+
+      // Get the corresponding long-option string
+   const char *
+   LongOpt(void) const {
+       return  (spec[1] && spec[2] && (! isspace(spec[2]))) ? (spec + 2) : NULLSTR;
+   }
+
+      // Does this option require an argument?
+   int
+   isValRequired(void) const {
+      return  ((spec[1] == ':') || (spec[1] == '+'));
+   }
+
+      // Does this option take an optional argument?
+   int
+   isValOptional(void) const {
+      return  ((spec[1] == '?') || (spec[1] == '*'));
+   }
+
+      // Does this option take no arguments?
+   int
+   isNoArg(void) const {
+      return  ((spec[1] == '|') || (! spec[1]));
+   }
+
+      // Can this option take more than one argument?
+   int
+   isList(void) const {
+      return  ((spec[1] == '+') || (spec[1] == '*'));
+   }
+
+      // Does this option take any arguments?
+   int
+   isValTaken(void) const {
+      return  (isValRequired() || isValOptional()) ;
+   }
+
+      // Format this option in the given buffer
+   unsigned
+   Format(char * buf, unsigned optctrls) const;
+
+private:
+   void
+   CheckHidden(void) {
+      if ((! hidden) && (*spec == '-')) {
+         ++hidden;
+         ++spec;
+      }
+   }
+
+   unsigned     hidden : 1;  // hidden-flag
+   const char * spec;        // string specification
+
+   static const char NULL_spec[];
+} ;
+
+const char OptionSpec::NULL_spec[] = "\0\0\0" ;
+
+int
+OptionSpec::isSyntaxError(const char * name) const {
+   int  error = 0;
+   if ((! spec) || (! *spec)) {
+      cerr << name << ": empty option specifier." << endl;
+      cerr << "\tmust be at least 1 character long." << endl;
+      ++error;
+   } else if (spec[1] && (strchr("|?:*+", spec[1]) == NULL)) {
+      cerr << name << ": bad option specifier \"" << spec << "\"." << endl;
+      cerr << "\t2nd character must be in the set \"|?:*+\"." << endl;
+      ++error;
+   }
+   return  error;
+}
+
+// ---------------------------------------------------------------------------
+// ^FUNCTION: OptionSpec::Format - format an option-spec for a usage message
+//
+// ^SYNOPSIS:
+//    unsigned OptionSpec::Format(buf, optctrls) const
+//
+// ^PARAMETERS:
+//    char * buf -- where to print the formatted option
+//    unsigned  optctrls -- option-parsing configuration flags
+//
+// ^DESCRIPTION:
+//    Self-explanatory.
+//
+// ^REQUIREMENTS:
+//    - buf must be large enough to hold the result
+//
+// ^SIDE-EFFECTS:
+//    - writes to buf.
+//
+// ^RETURN-VALUE:
+//    Number of characters written to buf.
+//
+// ^ALGORITHM:
+//    Follow along in the source - it's not hard but it is tedious!
+// ^^-------------------------------------------------------------------------
+unsigned
+OptionSpec::Format(char * buf, unsigned optctrls) const {
+#ifdef NO_USAGE
+   return  (*buf = '\0');
+#else
+   static  char default_value[] = "<value>";
+   if (isHiddenOpt())  return (unsigned)(*buf = '\0');
+   char optchar = OptChar();
+   const char * longopt = LongOpt();
+   char * p = buf ;
+
+   const char * value = NULLSTR;
+   int    longopt_len = 0;
+   int    value_len = 0;
+
+   if (longopt) {
+      value = ::strchr(longopt, ' ');
+      longopt_len = (value) ? (value - longopt) : ::strlen(longopt);
+   } else {
+      value = ::strchr(spec + 1, ' ');
+   }
+   while (value && (*value == ' '))  ++value;
+   if (value && *value) {
+      value_len = ::strlen(value);
+   } else {
+      value = default_value;
+      value_len = sizeof(default_value) - 1;
+   }
+
+   if ((optctrls & Options::SHORT_ONLY) &&
+       ((! isNullOpt(optchar)) || (optctrls & Options::NOGUESSING))) {
+      longopt = NULLSTR;
+   }
+   if ((optctrls & Options::LONG_ONLY) &&
+       (longopt || (optctrls & Options::NOGUESSING))) {
+      optchar = '\0';
+   }
+   if (isNullOpt(optchar) && (longopt == NULL)) {
+      *buf = '\0';
+      return  0;
+   }
+
+   *(p++) = '[';
+
+   // print the single character option
+   if (! isNullOpt(optchar)) {
+      *(p++) = '-';
+      *(p++) = optchar;
+   }
+
+   if ((! isNullOpt(optchar)) && (longopt))  *(p++) = '|';
+
+   // print the long option
+   if (longopt) {
+      *(p++) = '-';
+      if (! (optctrls & (Options::LONG_ONLY | Options::SHORT_ONLY))) {
+         *(p++) = '-';
+      }
+      strncpy(p, longopt, longopt_len);
+      p += longopt_len;
+   }
+
+   // print any argument the option takes
+   if (isValTaken()) {
+      *(p++) = ' ' ;
+      if (isValOptional())  *(p++) = '[' ;
+      strcpy(p, value);
+      p += value_len;
+      if (isList()) {
+         strcpy(p, " ...");
+         p += 4;
+      }
+      if (isValOptional())  *(p++) = ']' ;
+   }
+
+   *(p++) = ']';
+   *p = '\0';
+
+   return  (unsigned) strlen(buf);
+#endif  /* USE_STDIO */
+}
+
+// ******************************************************************* Options
+
+#if (defined(MSWIN) || defined(OS2) || defined(MSDOS))
+# define DIR_SEP_CHAR '\\'
+#else
+# define DIR_SEP_CHAR '/'
+#endif
+
+Options::Options(const char * name, const char * const optv[])
+   : cmdname(name), optvec(optv), explicit_end(0), optctrls(DEFAULT),
+     nextchar(NULLSTR), listopt(NULLSTR)
+{
+   const char * basename = ::strrchr(cmdname, DIR_SEP_CHAR);
+   if (basename)  cmdname = basename + 1;
+   check_syntax();
+}
+
+Options::~Options(void) {}
+
+   // Make sure each option-specifier has correct syntax.
+   //
+   // If there is even one invalid specifier, then exit ungracefully!
+   //
+void
+Options::check_syntax(void) const {
+   int  errors = 0;
+   if ((optvec == NULL) || (! *optvec))  return;
+
+   for (const char * const * optv = optvec ; *optv ; optv++) {
+      OptionSpec  optspec = *optv;
+      errors += optspec.isSyntaxError(cmdname);
+   }
+   if (errors)  exit(127);
+}
+
+// ---------------------------------------------------------------------------
+// ^FUNCTION: Options::match_opt - match an option
+//
+// ^SYNOPSIS:
+//    const char * match_opt(opt, int  ignore_case) const
+//
+// ^PARAMETERS:
+//    char opt -- the option-character to match
+//    int  ignore_case -- should we ignore character-case?
+//
+// ^DESCRIPTION:
+//    See if "opt" is found in "optvec"
+//
+// ^REQUIREMENTS:
+//    - optvec should be non-NULL and terminated by a NULL pointer.
+//
+// ^SIDE-EFFECTS:
+//    None.
+//
+// ^RETURN-VALUE:
+//    NULL if no match is found,
+//    otherwise a pointer to the matching option-spec.
+//
+// ^ALGORITHM:
+//    foreach option-spec
+//       - see if "opt" is a match, if so return option-spec
+//    end-for
+// ^^-------------------------------------------------------------------------
+const char *
+Options::match_opt(char opt, int ignore_case) const {
+   if ((optvec == NULL) || (! *optvec))  return  NULLSTR;
+
+   for (const char * const * optv = optvec ; *optv ; optv++) {
+      OptionSpec  optspec = *optv;
+      char optchar = optspec.OptChar();
+      if (isNullOpt(optchar))  continue;
+      if (opt == optchar) {
+         return  optspec;
+      } else if (ignore_case && (TOLOWER(opt) == TOLOWER(optchar))) {
+         return  optspec;
+      }
+   }
+
+   return  NULLSTR;  // not found
+}
+
+// ---------------------------------------------------------------------------
+// ^FUNCTION: Options::match_longopt - match a long-option
+//
+// ^SYNOPSIS:
+//   const char * Options::match_longopt(opt, len, ambiguous)
+//
+// ^PARAMETERS:
+//    char * opt -- the long-option to match
+//    int len -- the number of character of "opt" to match
+//    int & ambiguous -- set by this routine before returning.
+//
+// ^DESCRIPTION:
+//    Try to match "opt" against some unique prefix of a long-option
+//    (case insensitive).
+//
+// ^REQUIREMENTS:
+//    - optvec should be non-NULL and terminated by a NULL pointer.
+//
+// ^SIDE-EFFECTS:
+//    - *ambiguous is set to '1' if "opt" matches >1 long-option
+//      (otherwise it is set to 0).
+//
+// ^RETURN-VALUE:
+//    NULL if no match is found,
+//    otherwise a pointer to the matching option-spec.
+//
+// ^ALGORITHM:
+//    ambiguous is FALSE
+//    foreach option-spec
+//       if we have an EXACT-MATCH, return the option-spec
+//       if we have a partial-match then
+//          if we already had a previous partial match then
+//             set ambiguous = TRUE and return NULL
+//          else
+//             remember this options spec and continue matching
+//          end-if
+//       end-if
+//    end-for
+//    if we had exactly 1 partial match return it, else return NULL
+// ^^-------------------------------------------------------------------------
+const char *
+Options::match_longopt(const char * opt, int  len, int & ambiguous) const {
+   kwdmatch_t  result;
+   const char * matched = NULLSTR ;
+
+   ambiguous = 0;
+   if ((optvec == NULL) || (! *optvec))  return  NULLSTR;
+
+   for (const char * const * optv = optvec ; *optv ; optv++) {
+      OptionSpec  optspec = *optv;
+      const char * longopt = optspec.LongOpt();
+      if (longopt == NULL)  continue;
+      result = kwdmatch(longopt, opt, len);
+      if (result == EXACT_MATCH) {
+         return  optspec;
+      } else if (result == PARTIAL_MATCH) {
+         if (matched) {
+            ++ambiguous;
+            return  NULLSTR;
+         } else {
+            matched = optspec;
+         }
+      }
+   }//for
+
+   return  matched;
+}
+
+// ---------------------------------------------------------------------------
+// ^FUNCTION: Options::parse_opt - parse an option
+//
+// ^SYNOPSIS:
+//    int Options::parse_opt(iter, optarg)
+//
+// ^PARAMETERS:
+//    OptIter & iter -- option iterator
+//    const char * & optarg -- where to store any option-argument
+//
+// ^DESCRIPTION:
+//    Parse the next option in iter (advancing as necessary).
+//    Make sure we update the nextchar pointer along the way. Any option
+//    we find should be returned and optarg should point to its argument.
+//
+// ^REQUIREMENTS:
+//    - nextchar must point to the prospective option character
+//
+// ^SIDE-EFFECTS:
+//    - iter is advanced when an argument completely parsed
+//    - optarg is modified to point to any option argument
+//    - if Options::QUIET is not set, error messages are printed on cerr
+//
+// ^RETURN-VALUE:
+//    'c' if the -c option was matched (optarg points to its argument)
+//    BADCHAR if the option is invalid (optarg points to the bad
+//                                                   option-character).
+//
+// ^ALGORITHM:
+//    It gets complicated -- follow the comments in the source.
+// ^^-------------------------------------------------------------------------
+int
+Options::parse_opt(OptIter & iter, const char * & optarg) {
+   listopt = NULLSTR;  // reset the list pointer
+
+   if ((optvec == NULL) || (! *optvec))  return  Options::ENDOPTS;
+
+      // Try to match a known option
+   OptionSpec optspec = match_opt(*(nextchar++), (optctrls & Options::ANYCASE));
+
+      // Check for an unknown option
+   if (optspec.isNULL()) {
+      // See if this was a long-option in disguise
+      if (! (optctrls & Options::NOGUESSING)) {
+         unsigned  save_ctrls = optctrls;
+         const char * save_nextchar = nextchar;
+         nextchar -= 1;
+         optctrls |= (Options::QUIET | Options::NOGUESSING);
+         int  optchar = parse_longopt(iter, optarg);
+         optctrls = save_ctrls;
+         if (optchar > 0) {
+            return  optchar;
+         } else {
+            nextchar = save_nextchar;
+         }
+      }
+      if (! (optctrls & Options::QUIET)) {
+         cerr << cmdname << ": unknown option -"
+              << *(nextchar - 1) << "." << endl ;
+      }
+      optarg = (nextchar - 1);  // record the bad option in optarg
+      return  Options::BADCHAR;
+   }
+
+      // If no argument is taken, then leave now
+   if (optspec.isNoArg()) {
+      optarg = NULLSTR;
+      return  optspec.OptChar();
+   }
+
+      // Check for argument in this arg
+   if (*nextchar) {
+      optarg = nextchar; // the argument is right here
+      nextchar = NULLSTR;   // we've exhausted this arg
+      if (optspec.isList())  listopt = optspec ;  // save the list-spec
+      return  optspec.OptChar();
+   }
+
+      // Check for argument in next arg
+   const char * nextarg = iter.curr();
+   if ((nextarg != NULL)  &&
+       (optspec.isValRequired() || (! isOption(optctrls, nextarg)))) {
+      optarg = nextarg;    // the argument is here
+      iter.next();         // end of arg - advance
+      if (optspec.isList())  listopt = optspec ;  // save the list-spec
+      return  optspec.OptChar();
+   }
+
+     // No argument given - if its required, thats an error
+   optarg = NULLSTR;
+   if (optspec.isValRequired() &&  !(optctrls & Options::QUIET)) {
+      cerr << cmdname << ": argument required for -" << optspec.OptChar()
+           << " option." << endl ;
+   }
+   return  optspec.OptChar();
+}
+
+// ---------------------------------------------------------------------------
+// ^FUNCTION: Options::parse_longopt - parse a long-option
+//
+// ^SYNOPSIS:
+//    int Options::parse_longopt(iter, optarg)
+//
+// ^PARAMETERS:
+//    OptIter & iter -- option iterator
+//    const char * & optarg -- where to store any option-argument
+//
+// ^DESCRIPTION:
+//    Parse the next long-option in iter (advancing as necessary).
+//    Make sure we update the nextchar pointer along the way. Any option
+//    we find should be returned and optarg should point to its argument.
+//
+// ^REQUIREMENTS:
+//    - nextchar must point to the prospective option character
+//
+// ^SIDE-EFFECTS:
+//    - iter is advanced when an argument completely parsed
+//    - optarg is modified to point to any option argument
+//    - if Options::QUIET is not set, error messages are printed on cerr
+//
+// ^RETURN-VALUE:
+//    'c' if the the long-option corresponding to the -c option was matched
+//         (optarg points to its argument)
+//    BADKWD if the option is invalid (optarg points to the bad long-option
+//                                                                     name).
+//
+// ^ALGORITHM:
+//    It gets complicated -- follow the comments in the source.
+// ^^-------------------------------------------------------------------------
+int
+Options::parse_longopt(OptIter & iter, const char * & optarg) {
+   int  len = 0, ambiguous = 0;
+
+   listopt = NULLSTR ;  // reset the list-spec
+
+   if ((optvec == NULL) || (! *optvec))  return  Options::ENDOPTS;
+
+      // if a value is supplied in this argv element, get it now
+   const char * val = strpbrk(nextchar, ":=") ;
+   if (val) {
+      len = val - nextchar ;
+      ++val ;
+   }
+
+      // Try to match a known long-option
+   OptionSpec  optspec = match_longopt(nextchar, len, ambiguous);
+
+      // Check for an unknown long-option
+   if (optspec.isNULL()) {
+      // See if this was a short-option in disguise
+      if ((! ambiguous) && (! (optctrls & Options::NOGUESSING))) {
+         unsigned  save_ctrls = optctrls;
+         const char * save_nextchar = nextchar;
+         optctrls |= (Options::QUIET | Options::NOGUESSING);
+         int  optchar = parse_opt(iter, optarg);
+         optctrls = save_ctrls;
+         if (optchar > 0) {
+            return  optchar;
+         } else {
+            nextchar = save_nextchar;
+         }
+      }
+      if (! (optctrls & Options::QUIET)) {
+         cerr << cmdname << ": " << ((ambiguous) ? "ambiguous" : "unknown")
+              << " option "
+              << ((optctrls & Options::LONG_ONLY) ? "-" : "--")
+              << nextchar << "." << endl ;
+      }
+      optarg = nextchar;  // record the bad option in optarg
+      nextchar = NULLSTR;    // we've exhausted this argument
+      return  (ambiguous) ? Options::AMBIGUOUS : Options::BADKWD;
+   }
+
+      // If no argument is taken, then leave now
+   if (optspec.isNoArg()) {
+      if ((val) && ! (optctrls & Options::QUIET)) {
+         cerr << cmdname << ": option "
+              << ((optctrls & Options::LONG_ONLY) ? "-" : "--")
+              << optspec.LongOpt() << " does NOT take an argument." << endl ;
+      }
+      optarg = val;     // record the unexpected argument
+      nextchar = NULLSTR;  // we've exhausted this argument
+      return  optspec.OptChar();
+   }
+
+      // Check for argument in this arg
+   if (val) {
+      optarg = val;      // the argument is right here
+      nextchar = NULLSTR;   // we exhausted the rest of this arg
+      if (optspec.isList())  listopt = optspec ;  // save the list-spec
+      return  optspec.OptChar();
+   }
+
+      // Check for argument in next arg
+   const char * nextarg = iter.curr();  // find the next argument to parse
+   if ((nextarg != NULL)  &&
+       (optspec.isValRequired() || (! isOption(optctrls, nextarg)))) {
+      optarg = nextarg;        // the argument is right here
+      iter.next();             // end of arg - advance
+      nextchar = NULLSTR;         // we exhausted the rest of this arg
+      if (optspec.isList())  listopt = optspec ;  // save the list-spec
+      return  optspec.OptChar();
+   }
+
+     // No argument given - if its required, thats an error
+   optarg = NULLSTR;
+   if (optspec.isValRequired() &&  !(optctrls & Options::QUIET)) {
+      const char * longopt = optspec.LongOpt();
+      const char * spc = ::strchr(longopt, ' ');
+      int  longopt_len;
+      if (spc) {
+         longopt_len = spc - longopt;
+      } else {
+         longopt_len = ::strlen(longopt);
+      }
+      cerr << cmdname << ": argument required for "
+           << ((optctrls & Options::LONG_ONLY) ? "-" : "--");
+      cerr.write(longopt, longopt_len) << " option." << endl ;
+   }
+   nextchar = NULLSTR;           // we exhausted the rest of this arg
+   return  optspec.OptChar();
+}
+
+// ---------------------------------------------------------------------------
+// ^FUNCTION: Options::usage - print usage
+//
+// ^SYNOPSIS:
+//    void Options::usage(os, positionals)
+//
+// ^PARAMETERS:
+//    ostream & os -- where to print the usage
+//    char * positionals -- command-line syntax for any positional args
+//
+// ^DESCRIPTION:
+//    Print command-usage (using either option or long-option syntax) on os.
+//
+// ^REQUIREMENTS:
+//    os should correspond to an open output file.
+//
+// ^SIDE-EFFECTS:
+//    Prints on os
+//
+// ^RETURN-VALUE:
+//    None.
+//
+// ^ALGORITHM:
+//    Print usage on os, wrapping long lines where necessary.
+// ^^-------------------------------------------------------------------------
+void
+Options::usage(ostream & os, const char * positionals) const {
+#ifdef NO_USAGE
+   return;
+#else
+   const char * const * optv = optvec;
+   unsigned  cols = 79;
+   int  first, nloop;
+   char  buf[256] ;
+
+   if ((optv == NULL) || (! *optv))  return;
+
+      // print first portion "usage: progname"
+   os << "usage: " << cmdname ;
+   unsigned  ll = strlen(cmdname) + 7;
+
+      // save the current length so we know how much space to skip for
+      // subsequent lines.
+      //
+   unsigned  margin = ll + 1;
+
+      // print the options and the positional arguments
+   for (nloop = 0, first = 1 ; !nloop ; optv++, first = 0) {
+      unsigned  len;
+      OptionSpec   optspec = *optv;
+
+         // figure out how wide this parameter is (for printing)
+      if (! *optv) {
+         len = strlen(positionals);
+         ++nloop;  // terminate this loop
+      } else {
+         if (optspec.isHiddenOpt())  continue;
+         len = optspec.Format(buf, optctrls);
+      }
+
+      //  Will this fit?
+      if ((ll + len + 1) > (cols - first)) {
+         os << '\n' ;  // No - start a new line;
+#ifdef USE_STDIO
+         for (int _i_ = 0; _i_ < margin; ++_i_)  os << " ";
+#else
+         os.width(margin); os << "" ;
+#endif
+         ll = margin;
+      } else {
+         os << ' ' ;  // Yes - just throw in a space
+         ++ll;
+      }
+      ll += len;
+      os << ((nloop) ? positionals : buf) ;
+   }// for each ad
+
+   os << endl ;
+#endif  /* NO_USAGE */
+}
+
+
+// ---------------------------------------------------------------------------
+// ^FUNCTION: Options::operator() - get options from the command-line
+//
+// ^SYNOPSIS:
+//   int Options::operator()(iter, optarg)
+//
+// ^PARAMETERS:
+//    OptIter & iter -- option iterator
+//    const char * & optarg -- where to store any option-argument
+//
+// ^DESCRIPTION:
+//    Parse the next option in iter (advancing as necessary).
+//    Make sure we update the nextchar pointer along the way. Any option
+//    we find should be returned and optarg should point to its argument.
+//
+// ^REQUIREMENTS:
+//    None.
+//
+// ^SIDE-EFFECTS:
+//    - iter is advanced when an argument is completely parsed
+//    - optarg is modified to point to any option argument
+//    - if Options::QUIET is not set, error messages are printed on cerr
+//
+// ^RETURN-VALUE:
+//     0 if all options have been parsed.
+//    'c' if the the option or long-option corresponding to the -c option was
+//         matched (optarg points to its argument).
+//    BADCHAR if the option is invalid (optarg points to the bad option char).
+//    BADKWD if the option is invalid (optarg points to the bad long-opt name).
+//    AMBIGUOUS if an ambiguous keyword name was given (optarg points to the
+//         ambiguous keyword name).
+//    POSITIONAL if PARSE_POS was set and the current argument is a positional
+//         parameter (in which case optarg points to the positional argument).
+//
+// ^ALGORITHM:
+//    It gets complicated -- follow the comments in the source.
+// ^^-------------------------------------------------------------------------
+int
+Options::operator()(OptIter & iter, const char * & optarg) {
+   int parse_opts_only = isOptsOnly(optctrls);
+   if (parse_opts_only)  explicit_end = 0;
+
+      // See if we have an option left over from before ...
+   if ((nextchar) && *nextchar) {
+      return  parse_opt(iter, optarg);
+   }
+
+      // Check for end-of-options ...
+   const char * arg = NULLSTR;
+   int get_next_arg = 0;
+   do {
+      arg = iter.curr();
+      get_next_arg = 0;
+      if (arg == NULL) {
+         listopt = NULLSTR;
+         return  Options::ENDOPTS;
+      } else if ((! explicit_end) && isEndOpts(arg)) {
+         iter.next();   // advance past end-of-options arg
+         listopt = NULLSTR;
+         explicit_end = 1;
+         if (parse_opts_only)  return  Options::ENDOPTS;
+         get_next_arg = 1;  // make sure we look at the next argument.
+      }
+   } while (get_next_arg);
+
+      // Do we have a positional arg?
+   if ( explicit_end || (! isOption(optctrls, arg)) ) {
+      if (parse_opts_only) {
+         return  Options::ENDOPTS;
+      } else {
+         optarg = arg;  // set optarg to the positional argument
+         iter.next();   // advance iterator to the next argument
+         return  Options::POSITIONAL;
+      }
+   }
+
+   iter.next();  // pass the argument that arg already points to
+
+      // See if we have a long option ...
+   if (! (optctrls & Options::SHORT_ONLY)) {
+      if ((*arg == '-') && (arg[1] == '-')) {
+         nextchar = arg + 2;
+         return  parse_longopt(iter, optarg);
+      } else if ((optctrls & Options::PLUS) && (*arg == '+')) {
+         nextchar = arg + 1;
+         return  parse_longopt(iter, optarg);
+      }
+   }
+   if (*arg == '-') {
+      nextchar = arg + 1;
+      if (optctrls & Options::LONG_ONLY) {
+         return  parse_longopt(iter, optarg);
+      } else {
+         return  parse_opt(iter, optarg);
+      }
+   }
+
+      // If we get here - it is because we have a list value
+   OptionSpec  optspec = listopt;
+   optarg = arg ;        // record the list value
+   return  optspec.OptChar() ;
+}
+
Index: /tags/quest-pre-eventrefactoring/MFCtooling/replay/options.h
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/replay/options.h	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/replay/options.h	(revision 540)
@@ -0,0 +1,488 @@
+// ****************************************************************************
+// ^FILE: options.h - option parsing classes
+//
+// ^DESCRIPTION:
+//    This file defines classes used to parse command-line options.
+//    Options may be parsed from an array of strings, or from any structure
+//    for which a corresponding option-iterator exists.
+//
+// ^HISTORY:
+//    03/06/92  Brad Appleton   <bradapp@enteract.com>   Created
+//
+//    03/23/93	Brad Appleton	<bradapp@enteract.com>
+//    - Added OptIstreamIter class
+//
+//    03/08/94	Brad Appleton	<bradapp@enteract.com>
+//    - Added Options::reset() member function
+//
+//    07/31/97	Brad Appleton	<bradapp@enteract.com>
+//    - Added PARSE_POS control flag and POSITIONAL return value
+// ^^**************************************************************************
+
+#ifndef _options_h
+#define _options_h
+
+#include <iostream>
+
+// Abstract class to iterate through options/arguments
+//
+class OptIter {
+public:
+   OptIter(void) {}
+   virtual ~OptIter(void);
+
+      // curr() returns the current item in the iterator without
+      // advancing on to the next item. If we are at the end of items
+      // then NULL is returned.
+   virtual const char *
+   curr(void) = 0;
+
+      // next() advances to the next item.
+   virtual void
+   next(void) = 0;
+
+      // operator() returns the current item in the iterator and then
+      // advances on to the next item. If we are at the end of items
+      // then NULL is returned.
+   virtual const char *
+   operator()(void);
+} ;
+
+// Abstract class for a rewindable OptIter
+//
+class OptIterRwd : public OptIter {
+public:
+   OptIterRwd(void);
+
+   virtual ~OptIterRwd(void);
+
+   virtual const char *
+   curr(void) = 0;
+
+   virtual void
+   next(void) = 0;
+
+   virtual const char *
+   operator()(void) = 0;
+
+      // rewind() resets the "current-element" to the first one in the "list"
+   virtual void
+   rewind(void) = 0;
+} ;
+
+// Class to iterate through an array of tokens. The array may be terminated
+// by NULL or a count containing the number of tokens may be given.
+//
+class OptArgvIter : public OptIterRwd {
+private:
+   int            ndx;   // index of current arg
+   int            ac;    // arg count
+   const char * const * av;  // arg vector
+
+public:
+   OptArgvIter(const char * const argv[])
+      : av(argv), ac(-1), ndx(0) {}
+
+   OptArgvIter(int argc, const char * const argv[])
+      : av(argv), ac(argc), ndx(0) {}
+
+   virtual
+   ~OptArgvIter(void);
+
+   virtual const char *
+   curr(void);
+
+   virtual void
+   next(void);
+
+   virtual const char *
+   operator()(void);
+
+   virtual void
+   rewind(void);
+
+      // index returns the current index to use for argv[]
+   int index(void)  { return  ndx; }
+} ;
+
+
+// Class to iterate through a string containing delimiter-separated tokens
+//
+class OptStrTokIter : public OptIterRwd {
+private:
+   unsigned     len;        // length of token-string
+   const char * str;        // the token-string
+   const char * seps;       // delimiter-set (separator-characters)
+   const char * cur;        // current token
+   char       * tokstr;     // our copy of the token-string
+
+   static const char * default_delims;  // default delimiters = whitespace
+
+public:
+   OptStrTokIter(const char * tokens, const char * delimiters =0);
+
+   virtual
+   ~OptStrTokIter(void);
+
+   virtual const char *
+   curr(void);
+
+   virtual void
+   next(void);
+
+   virtual const char *
+   operator()(void);
+
+   virtual void
+   rewind(void);
+
+      // delimiters() with NO arguments returns the current set of delimiters,
+      // If an argument is given then it is used as the new set of delimiters.
+   const char *
+   delimiters(void)  { return  seps; }
+
+   void
+   delimiters(const char * delims) {
+      seps = (delims) ? delims : default_delims ;
+   }
+} ;
+
+
+   // OptIstreamIter is a class for iterating over arguments that come
+   // from an input stream. Each line of the input stream is considered
+   // to be a set of white-space separated tokens. If the the first
+   // non-white character on a line is '#' ('!' for VMS systems) then
+   // the line is considered a comment and is ignored.
+   //
+   // *Note:: If a line is more than 1022 characters in length then we
+   // treat it as if it were several lines of length 1022 or less.
+   //
+   // *Note:: The string tokens returned by this iterator are pointers
+   //         to temporary buffers which may not necessarily stick around
+   //         for too long after the call to curr() or operator(), hence
+   //         if you need the string value to persist - you will need to
+   //         make a copy.
+   //
+class OptIstreamIter : public OptIter {
+private:
+	std::istream & is ;
+   OptStrTokIter * tok_iter ;
+
+   void
+   fill(void);
+
+public:
+   static const unsigned  MAX_LINE_LEN ;
+
+   OptIstreamIter(std::istream & input);
+
+   virtual
+   ~OptIstreamIter(void);
+
+   virtual const char *
+   curr(void);
+
+   virtual void
+   next(void);
+
+   virtual const char *
+   operator()(void);
+} ;
+
+
+// Now we are ready to define a class to declare and parse command-options
+//
+//
+// CLASS
+// =====
+// Options  -- parse command-line options
+//
+// SYNOPSIS
+// ========
+//   #include <options.h>
+//
+//   Options opts(cmdname, optv);
+//   char cmdname[], *optv[];
+//
+// DESCRIPTION
+// ===========
+// The Options constructor expects a command-name (usually argv[0]) and
+// a pointer to an array of strings.  The last element in this array MUST
+// be NULL. Each non-NULL string in the array must have the following format:
+//
+//   The 1st character must be the option-name ('c' for a -c option).
+//
+//   The 2nd character must be one of '|', '?', ':', '*', or '+'.
+//      '|' -- indicates that the option takes NO argument;
+//      '?' -- indicates that the option takes an OPTIONAL argument;
+//      ':' -- indicates that the option takes a REQUIRED argument;
+//      '*' -- indicates that the option takes 0 or more arguments;
+//      '+' -- indicates that the option takes 1 or more arguments;
+//
+//   The remainder of the string must be the long-option name.
+//
+//   If desired, the long-option name may be followed by one or more
+//   spaces and then by the name of the option value. This name will
+//   be used when printing usage messages. If the option-value-name
+//   is not given then the string "<value>" will be used in usage
+//   messages.
+//
+//   One may use a space to indicate that a particular option does not
+//   have a corresponding long-option.  For example, "c: " (or "c:")
+//   means the -c option takes a value & has NO corresponding long-option.
+//
+//   To specify a long-option that has no corresponding single-character
+//   option is a bit trickier: Options::operator() still needs an "option-
+//   character" to return when that option is matched. One may use a whitespace
+//   character or a non-printable character as the single-character option
+//   in such a case. (hence " |hello" would only match "--hello").
+//
+//   EXCEPTIONS TO THE ABOVE:
+//   ------------------------ 
+//   If the 1st character of the string is '-', then the rest of the
+//   string must correspond to the above format, and the option is
+//   considered to be a hidden-option. This means it will be parsed
+//   when actually matching options from the command-line, but will
+//   NOT show-up if a usage message is printed using the usage() member
+//   function. Such an example might be "-h|hidden". If you want to
+//   use any "dummy" options (options that are not parsed, but that
+//   to show up in the usage message), you can specify them along with
+//   any positional parameters to the usage() member function.
+//
+//   If the 2nd character of the string is '\0' then it is assumed
+//   that there is no corresponding long-option and that the option
+//   takes no argument (hence "f", and "f| " are equivalent).
+//
+//   Examples:
+//      const char * optv[] = {
+//          "c:count   <number>",
+//          "s?str     <string>",
+//          "x",
+//          " |hello",
+//          "g+groups  <newsgroup>",
+//          NULL
+//      } ;
+//
+//      optv[] now corresponds to the following:
+//
+//            usage: cmdname [-c|--count <number>] [-s|--str [<string>]]
+//                           [-x] [--hello] [-g|--groups <newsgroup> ...]
+//
+// Long-option names are matched case-insensitive and only a unique prefix
+// of the name needs to be specified.
+//
+// Option-name characters are case-sensitive!
+//
+// CAVEAT
+// ======
+// Because of the way in which multi-valued options and options with optional
+// values are handled, it is NOT possible to supply a value to an option in
+// a separate argument (different argv[] element) if the value is OPTIONAL
+// and begins with a '-'. What this means is that if an option "-s" takes an
+// optional value value and you wish to supply a value of "-foo" then you must
+// specify this on the command-line as "-s-foo" instead of "-s -foo" because
+// "-s -foo" will be considered to be two separate sets of options.
+//
+// A multi-valued option is terminated by another option or by the end-of
+// options. The following are all equivalent (if "-l" is a multi-valued
+// option and "-x" is an option that takes no value):
+//
+//    cmdname -x -l item1 item2 item3 -- arg1 arg2 arg3
+//    cmdname -x -litem1 -litem2 -litem3 -- arg1 arg2 arg3
+//    cmdname -l item1 item2 item3 -x arg1 arg2 arg3
+//
+//
+// EXAMPLE
+// =======
+//    #include <options.h>
+//
+//    static const char * optv[] = {
+//       "H|help",
+//       "c:count   <number>",
+//       "s?str     <string>",
+//       "x",
+//       " |hello",
+//       "g+groups  <newsgroup>",
+//       NULL
+//    } ;
+//
+//    main(int argc, char * argv[]) {
+//       int  optchar;
+//       const char * optarg;
+//       const char * str = "default_string";
+//       int  count = 0, xflag = 0, hello = 0;
+//       int  errors = 0, ngroups = 0;
+//    
+//       Options  opts(*argv, optv);
+//       OptArgvIter  iter(--argc, ++argv);
+//    
+//       while( optchar = opts(iter, optarg) ) {
+//          switch (optchar) {
+//          case 'H' :
+//             opts.usage(cout, "files ...");
+//             exit(0);
+//             break;
+//          case 'g' :
+//             ++ngroups; break;  // the groupname is in "optarg"
+//          case 's' :
+//             str = optarg; break;
+//          case 'x' :
+//             ++xflag; break;
+//          case ' ' :
+//             ++hello; break;
+//          case 'c' :
+//             if (optarg == NULL)  ++errors;
+//             else  count = (int) atol(optarg);
+//             break;
+//          default :  ++errors; break;
+//          } //switch
+//       }
+//    
+//       if (errors || (iter.index() == argc)) {
+//          if (! errors) {
+//             cerr << opts.name() << ": no filenames given." << endl ;
+//          }
+//          opts.usage(cerr, "files ...");
+//          exit(1);
+//       }
+//    
+//       cout << "xflag=" << ((xflag) ? "ON"  : "OFF") << endl
+//            << "hello=" << ((hello) ? "YES" : "NO") << endl
+//            << "count=" << count << endl
+//            << "str=\"" << ((str) ? str : "No value given!") << "\"" << endl
+//            << "ngroups=" << ngroups << endl ;
+//    
+//       if (iter.index() < argc) {
+//          cout << "files=" ;
+//          for (int i = iter.index() ; i < argc ; i++) {
+//             cout << "\"" << argv[i] << "\" " ;
+//          }
+//          cout << endl ;
+//       }
+//    }
+//
+class Options {
+private:
+   unsigned       explicit_end : 1;  // were we terminated because of "--"?
+   unsigned       optctrls : 7;  // control settings (a set of OptCtrl masks)
+   const char  * const * optvec; // vector of option-specifications (last=NULL)
+   const char   * nextchar;      // next option-character to process
+   const char   * listopt;       // last list-option we matched
+   const char   * cmdname;       // name of the command
+
+   void
+   check_syntax(void) const;
+
+   const char *
+   match_opt(char opt, int ignore_case =0) const;
+
+   const char *
+   match_longopt(const char * opt, int  len, int & ambiguous) const;
+
+   int
+   parse_opt(OptIter & iter, const char * & optarg);
+
+   int
+   parse_longopt(OptIter & iter, const char * & optarg);
+
+public:
+   enum OptCtrl {
+      DEFAULT    = 0x00,  // Default setting
+      ANYCASE    = 0x01,  // Ignore case when matching short-options
+      QUIET      = 0x02,  // Dont print error messages
+      PLUS       = 0x04,  // Allow "+" as a long-option prefix
+      SHORT_ONLY = 0x08,  // Dont accept long-options
+      LONG_ONLY  = 0x10,  // Dont accept short-options
+                            // (also allows "-" as a long-option prefix).
+      NOGUESSING = 0x20,  // Normally, when we see a short (long) option
+                            // on the command line that doesnt match any
+                            // known short (long) options, then we try to
+                            // "guess" by seeing if it will match any known
+                            // long (short) option. Setting this mask prevents
+                            // this "guessing" from occurring.
+      PARSE_POS = 0x40    // By default, Options will not present positional
+                            // command-line arguments to the user and will
+                            // instead stop parsing when the first positonal
+                            // argument has been encountered. If this flag
+                            // is given, Options will present positional
+                            // arguments to the user with a return code of
+                            // POSITIONAL; ENDOPTS will be returned only
+                            // when the end of the argument list is reached.
+   } ;
+
+      // Error return values for operator()
+      //
+   enum OptRC {
+      ENDOPTS    =  0,
+      BADCHAR    = -1,
+      BADKWD     = -2,
+      AMBIGUOUS  = -3,
+      POSITIONAL = -4
+   } ;
+
+   Options(const char * name, const char * const optv[]);
+
+   virtual
+   ~Options(void);
+
+      // name() returns the command name
+   const char *
+   name(void) const { return  cmdname; }
+
+      // ctrls() (with no arguments) returns the existing control settings
+   unsigned
+   ctrls(void) const { return  optctrls; }
+
+      // ctrls() (with 1 argument) sets new control settings
+   void
+   ctrls(unsigned newctrls) { optctrls = newctrls; }
+
+      // reset for another pass to parse for options
+   void
+   reset(void) { nextchar = listopt = NULL; }
+  
+      // usage() prints options usage (followed by any positional arguments
+      // listed in the parameter "positionals") on the given outstream
+   void
+	   usage(std::ostream & os, const char * positionals) const ;
+
+      // operator() iterates through the arguments as necessary (using the
+      // given iterator) and returns the character value of the option
+      // (or long-option) that it matched. If the option has a value
+      // then the value given may be found in optarg (otherwise optarg
+      // will be NULL).
+      //
+      // 0 is returned upon end-of-options. At this point, "iter" may
+      // be used to process any remaining positional parameters. If the
+      // PARSE_POS control-flag is set then 0 is returned only when all
+      // arguments in "iter" have been exhausted.
+      //
+      // If an invalid option is found then BADCHAR is returned and *optarg
+      // is the unrecognized option character.
+      //
+      // If an invalid long-option is found then BADKWD is returned and optarg
+      // points to the bad long-option.
+      //
+      // If an ambiguous long-option is found then AMBIGUOUS is returned and
+      // optarg points to the ambiguous long-option.
+      //
+      // If the PARSE_POS control-flag is set then POSITIONAL is returned
+      // when a positional argument is encountered and optarg points to
+      // the positonal argument (and "iter" is advanced to the next argument
+      // in the iterator).
+      //
+      // Unless Options::QUIET is used, missing option-arguments and
+      // invalid options (and the like) will automatically cause error
+      // messages to be issued to cerr.
+   int
+   operator()(OptIter & iter, const char * & optarg) ;
+
+      // Call this member function after operator() has returned 0
+      // if you want to know whether or not options were explicitly
+      // terminated because "--" appeared on the command-line.
+      //
+   int
+   explicit_endopts() const { return  explicit_end; }
+} ;
+
+#endif /* _options_h */
Index: /tags/quest-pre-eventrefactoring/MFCtooling/replay/replay.cpp
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/replay/replay.cpp	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/replay/replay.cpp	(revision 540)
@@ -0,0 +1,150 @@
+// replay.cpp : Defines the entry point for the console application.
+//
+
+#include "stdafx.h"
+
+#include "LogParser.h"
+#include "SAXContentHandlerImpl.h"
+#include <iostream>
+
+#include "options.h"
+
+const char * optv[] = {
+	"r:resultfile <string>",
+	"d:msgdelay <number>",
+	"w:wait <number>",
+	"s:startdelay <number>",
+	"p:path <string>"
+};
+
+void convertTCharToChar(const TCHAR * source, char ** dest) {
+#ifdef UNICODE
+	std::wstring wstr(source);
+    int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL);
+    std::string strTo( size_needed, 0 );
+    WideCharToMultiByte                  (CP_UTF8, 0, &wstr[0], (int)wstr.size(), &strTo[0], size_needed, NULL, NULL);
+	*dest = new char[strTo.size()+1];
+	memcpy((void*)*dest, strTo.c_str(), strTo.size()+1);
+#else
+	std::string str(source);
+	*dest = new char[strTo.size()+1];
+	memcpy(*dest, strTo.c_str(), strTo.size()+1);
+#endif
+}
+
+void convertCharToTChar(const char * source, TCHAR ** dest) {
+#ifdef UNICODE
+	std::string str(source);
+	int size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0);
+	std::wstring wstrTo( size_needed, 0 );
+	MultiByteToWideChar                  (CP_UTF8, 0, &str[0], (int)str.size(), &wstrTo[0], size_needed);
+	*dest = new TCHAR[wstrTo.size()+1];
+	memcpy((void*)*dest, wstrTo.c_str(), (wstrTo.size()+1)*sizeof(TCHAR));
+#else
+	std::string str(source);
+	*dest = new char[strTo.size()+1];
+	memcpy(*dest, strTo.c_str(), strTo.size()+1);
+#endif
+}
+
+int _tmain(int argc, _TCHAR* argv[])
+{
+	if( argc < 3 ) {
+		std::wcout << L"Usage: " << argv[0] << L"<replayfile> <applicationundertest> [-r <resultfile>] [-d <useDefaultDelay>] [-w <waitAfterFinish>] [-p <workingPath>] [-s <startupDelay>]" << std::endl;
+		return 1;
+	}
+
+	int optchar = 0;
+	const char * optarg;
+	// set default values
+	TCHAR * resultfile = NULL;
+	int msgdelay = 0;
+	int startdelay = 5000;
+	int wait = 1;
+	TCHAR * workingPath = NULL;
+
+	int argc_char = argc-2;
+	char ** argv_char = new char*[argc_char];
+
+	// convert argv to char*[]
+	convertTCharToChar(argv[0], &argv_char[0]);
+	for( int i=3; i<argc; i++ ) {
+		convertTCharToChar(argv[i], &argv_char[i-2]);
+	}
+
+	// parse options
+	Options opts(*argv_char, optv);
+	OptArgvIter iter(--argc_char, ++argv_char);
+	while( optchar = opts(iter, optarg) ) {
+		switch(optchar) {
+			case 'r':
+				convertCharToTChar(optarg, &resultfile);
+				break;
+			case 'd':
+				msgdelay = atoi(optarg);
+				break;
+			case 'w':
+				wait = atoi(optarg);
+				break;
+			case 'p':
+				convertCharToTChar(optarg, &workingPath);
+				break;
+			case 's':
+				startdelay = atoi(optarg);
+				break;
+			default:
+				break;
+		}
+	}
+	for( int i=0; i<argc_char; i++ ) {
+		delete[] argv_char[i];
+	}
+	//delete[] argv_char; //TODO does not work?!
+
+	TCHAR * replayfile = argv[1];
+	TCHAR * appUnderTest = argv[2];
+
+	// initialize COM library for the current thread
+	CoInitialize(NULL); 
+	MSXML2::ISAXXMLReader* pXMLReader = NULL;
+
+	// create an instance of the XML reader
+	HRESULT hr = CoCreateInstance(
+		__uuidof(MSXML2::SAXXMLReader), 
+		NULL, 
+		CLSCTX_ALL, 
+		__uuidof(MSXML2::ISAXXMLReader), 
+		(void **)&pXMLReader);
+
+	if( !FAILED(hr) ) {
+		TestResults results(replayfile);
+		std::wcout << L"replaying sessions in " << argv[1] << std::endl;
+		LogParser * parser = new LogParser(appUnderTest, startdelay, &results, (bool) msgdelay);
+		parser->setWorkingPath(workingPath);
+		pXMLReader->putContentHandler(parser);
+		hr = pXMLReader->parseURL(replayfile);
+		if( hr!=S_OK ) {
+			std::wcout << L"failure parsing XML file" << std::endl;
+			return 1;
+		}
+		pXMLReader->Release();
+		std::wcout << L"================================================" << std::endl;
+		std::wcout << L"replay completed" << std::endl;
+		if( resultfile!=NULL ) {
+			results.write(resultfile);
+			std::wcout << L"results written to " << resultfile << std::endl;
+		}
+	}
+
+	CoUninitialize();
+	
+	if( wait!=0 ) {
+		std::wcout << L"press enter to exit ...";
+		getchar();
+	}
+
+	delete resultfile;
+
+	return 0;
+}
+
Index: /tags/quest-pre-eventrefactoring/MFCtooling/replay/replay.vcproj
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/replay/replay.vcproj	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/replay/replay.vcproj	(revision 540)
@@ -0,0 +1,352 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9,00"
+	Name="replay"
+	ProjectGUID="{6CDC762E-2D22-4B0F-B6CD-7F8AB432ED42}"
+	RootNamespace="replay"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				TreatWChar_tAsBuiltInType="false"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="2"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				TreatWChar_tAsBuiltInType="false"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="2"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release_ReplayOld|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="1"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				EnableIntrinsicFunctions="true"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				TreatWChar_tAsBuiltInType="false"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="1"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				CommandLine="copy C:\Projects\MFCtooling\Release\replay.exe C:\replay\tools\replay.exe /y"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath=".\LogParser.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\options.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\replay.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\stdafx.cpp"
+				>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						UsePrecompiledHeader="1"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						UsePrecompiledHeader="1"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release_ReplayOld|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						UsePrecompiledHeader="1"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\TestResults.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\WindowData.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\WindowFinder.cpp"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+			<File
+				RelativePath=".\LogParser.h"
+				>
+			</File>
+			<File
+				RelativePath=".\options.h"
+				>
+			</File>
+			<File
+				RelativePath=".\SAXContentHandlerImpl.h"
+				>
+			</File>
+			<File
+				RelativePath=".\stdafx.h"
+				>
+			</File>
+			<File
+				RelativePath=".\targetver.h"
+				>
+			</File>
+			<File
+				RelativePath=".\TestResults.h"
+				>
+			</File>
+			<File
+				RelativePath=".\WindowData.h"
+				>
+			</File>
+			<File
+				RelativePath=".\WindowFinder.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+			>
+		</Filter>
+		<File
+			RelativePath=".\ReadMe.txt"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
Index: /tags/quest-pre-eventrefactoring/MFCtooling/replay/stdafx.cpp
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/replay/stdafx.cpp	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/replay/stdafx.cpp	(revision 540)
@@ -0,0 +1,8 @@
+// stdafx.cpp : source file that includes just the standard includes
+// replay2.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+// TODO: reference any additional headers you need in STDAFX.H
+// and not in this file
Index: /tags/quest-pre-eventrefactoring/MFCtooling/replay/stdafx.h
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/replay/stdafx.h	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/replay/stdafx.h	(revision 540)
@@ -0,0 +1,16 @@
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#pragma once
+
+#include "targetver.h"
+
+#include <stdio.h>
+#include <tchar.h>
+#include <windows.h>
+
+#import <msxml3.dll> raw_interfaces_only
+
+// TODO: reference additional headers your program requires here
Index: /tags/quest-pre-eventrefactoring/MFCtooling/replay/targetver.h
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/replay/targetver.h	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/replay/targetver.h	(revision 540)
@@ -0,0 +1,13 @@
+#pragma once
+
+// The following macros define the minimum required platform.  The minimum required platform
+// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run 
+// your application.  The macros work by enabling all features available on platform versions up to and 
+// including the version specified.
+
+// Modify the following defines if you have to target a platform prior to the ones specified below.
+// Refer to MSDN for the latest info on corresponding values for different platforms.
+#ifndef _WIN32_WINNT            // Specifies that the minimum required platform is Windows Vista.
+#define _WIN32_WINNT 0x0600     // Change this to the appropriate value to target other versions of Windows.
+#endif
+
Index: /tags/quest-pre-eventrefactoring/MFCtooling/userlog/ClassDiagram1.cd
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/userlog/ClassDiagram1.cd	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/userlog/ClassDiagram1.cd	(revision 540)
@@ -0,0 +1,1 @@
+ 
Index: /tags/quest-pre-eventrefactoring/MFCtooling/userlog/ReadMe.txt
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/userlog/ReadMe.txt	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/userlog/ReadMe.txt	(revision 540)
@@ -0,0 +1,33 @@
+========================================================================
+    DYNAMIC LINK LIBRARY : userlog Project Overview
+========================================================================
+
+AppWizard has created this userlog DLL for you.
+
+This file contains a summary of what you will find in each of the files that
+make up your userlog application.
+
+
+userlog.vcproj
+    This is the main project file for VC++ projects generated using an Application Wizard.
+    It contains information about the version of Visual C++ that generated the file, and
+    information about the platforms, configurations, and project features selected with the
+    Application Wizard.
+
+userlog.cpp
+    This is the main DLL source file.
+
+/////////////////////////////////////////////////////////////////////////////
+Other standard files:
+
+StdAfx.h, StdAfx.cpp
+    These files are used to build a precompiled header (PCH) file
+    named userlog.pch and a precompiled types file named StdAfx.obj.
+
+/////////////////////////////////////////////////////////////////////////////
+Other notes:
+
+AppWizard uses "TODO:" comments to indicate parts of the source code you
+should add to or customize.
+
+/////////////////////////////////////////////////////////////////////////////
Index: /tags/quest-pre-eventrefactoring/MFCtooling/userlog/cencode.cpp
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/userlog/cencode.cpp	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/userlog/cencode.cpp	(revision 540)
@@ -0,0 +1,104 @@
+#include "stdafx.h"
+
+#include "encode.h"
+
+const int CHARS_PER_LINE = 1950;
+
+void base64_init_encodestate(base64_encodestate* state_in)
+{
+	state_in->step = step_A;
+	state_in->result = 0;
+	state_in->stepcount = 0;
+}
+
+char base64_encode_value(char value_in)
+{
+	static const char* encoding = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+	if (value_in > 63) return '=';
+	return encoding[(int)value_in];
+}
+
+int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in)
+{
+	const char* plainchar = plaintext_in;
+	const char* const plaintextend = plaintext_in + length_in;
+	char* codechar = code_out;
+	char result;
+	char fragment;
+	
+	result = state_in->result;
+	
+	switch (state_in->step)
+	{
+		while (1)
+		{
+	case step_A:
+			if (plainchar == plaintextend)
+			{
+				state_in->result = result;
+				state_in->step = step_A;
+				return codechar - code_out;
+			}
+			fragment = *plainchar++;
+			result = (fragment & 0x0fc) >> 2;
+			*codechar++ = base64_encode_value(result);
+			result = (fragment & 0x003) << 4;
+	case step_B:
+			if (plainchar == plaintextend)
+			{
+				state_in->result = result;
+				state_in->step = step_B;
+				return codechar - code_out;
+			}
+			fragment = *plainchar++;
+			result |= (fragment & 0x0f0) >> 4;
+			*codechar++ = base64_encode_value(result);
+			result = (fragment & 0x00f) << 2;
+	case step_C:
+			if (plainchar == plaintextend)
+			{
+				state_in->result = result;
+				state_in->step = step_C;
+				return codechar - code_out;
+			}
+			fragment = *plainchar++;
+			result |= (fragment & 0x0c0) >> 6;
+			*codechar++ = base64_encode_value(result);
+			result  = (fragment & 0x03f) >> 0;
+			*codechar++ = base64_encode_value(result);
+			
+			++(state_in->stepcount);
+			if (state_in->stepcount == CHARS_PER_LINE/4)
+			{
+				*codechar++ = '\n';
+				state_in->stepcount = 0;
+			}
+		}
+	}
+	/* control should not reach here */
+	return codechar - code_out;
+}
+
+int base64_encode_blockend(char* code_out, base64_encodestate* state_in)
+{
+	char* codechar = code_out;
+	
+	switch (state_in->step)
+	{
+	case step_B:
+		*codechar++ = base64_encode_value(state_in->result);
+		*codechar++ = '=';
+		*codechar++ = '=';
+		break;
+	case step_C:
+		*codechar++ = base64_encode_value(state_in->result);
+		*codechar++ = '=';
+		break;
+	case step_A:
+		break;
+	}
+	*codechar++ = '\n';
+	
+	return codechar - code_out;
+}
+
Index: /tags/quest-pre-eventrefactoring/MFCtooling/userlog/cencode.h
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/userlog/cencode.h	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/userlog/cencode.h	(revision 540)
@@ -0,0 +1,31 @@
+/*
+cencode.h - c header for a base64 encoding algorithm
+
+This is part of the libb64 project, and has been placed in the public domain.
+For details, see http://sourceforge.net/projects/libb64
+*/
+
+#ifndef BASE64_CENCODE_H
+#define BASE64_CENCODE_H
+
+typedef enum
+{
+	step_A, step_B, step_C
+} base64_encodestep;
+
+typedef struct
+{
+	base64_encodestep step;
+	char result;
+	int stepcount;
+} base64_encodestate;
+
+void base64_init_encodestate(base64_encodestate* state_in);
+
+char base64_encode_value(char value_in);
+
+int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in);
+
+int base64_encode_blockend(char* code_out, base64_encodestate* state_in);
+
+#endif /* BASE64_CENCODE_H */
Index: /tags/quest-pre-eventrefactoring/MFCtooling/userlog/dllmain.cpp
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/userlog/dllmain.cpp	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/userlog/dllmain.cpp	(revision 540)
@@ -0,0 +1,19 @@
+// dllmain.cpp : Defines the entry point for the DLL application.
+#include "stdafx.h"
+
+BOOL APIENTRY DllMain( HMODULE hModule,
+                       DWORD  ul_reason_for_call,
+                       LPVOID lpReserved
+					 )
+{
+	switch (ul_reason_for_call)
+	{
+	case DLL_PROCESS_ATTACH:
+	case DLL_THREAD_ATTACH:
+	case DLL_THREAD_DETACH:
+	case DLL_PROCESS_DETACH:
+		break;
+	}
+	return TRUE;
+}
+
Index: /tags/quest-pre-eventrefactoring/MFCtooling/userlog/encode.h
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/userlog/encode.h	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/userlog/encode.h	(revision 540)
@@ -0,0 +1,80 @@
+// :mode=c++:
+/*
+encode.h - c++ wrapper for a base64 encoding algorithm
+
+This is part of the libb64 project, and has been placed in the public domain.
+For details, see http://sourceforge.net/projects/libb64
+*/
+#ifndef BASE64_ENCODE_H
+#define BASE64_ENCODE_H
+
+#include <iostream>
+
+#define BUFFERSIZE 5000
+
+namespace base64
+{
+	extern "C" 
+	{
+		#include "cencode.h"
+	}
+
+	struct encoder
+	{
+		base64_encodestate _state;
+		int _buffersize;
+
+		encoder(int buffersize_in = BUFFERSIZE)
+		: _buffersize(buffersize_in)
+		{}
+
+		int encode(char value_in)
+		{
+			return base64_encode_value(value_in);
+		}
+
+		int encode(const char* code_in, const int length_in, char* plaintext_out)
+		{
+			base64_init_encodestate(&_state);
+			return base64_encode_block(code_in, length_in, plaintext_out, &_state);
+		}
+
+		int encode_end(char* plaintext_out)
+		{
+			return base64_encode_blockend(plaintext_out, &_state);
+		}
+
+		void encode(std::istream& istream_in, std::ostream& ostream_in)
+		{
+			base64_init_encodestate(&_state);
+			//
+			const int N = _buffersize;
+			char* plaintext = new char[N];
+			char* code = new char[2*N];
+			int plainlength;
+			int codelength;
+
+			do
+			{
+				istream_in.read(plaintext, N);
+				plainlength = istream_in.gcount();
+				//
+				codelength = encode(plaintext, plainlength, code);
+				ostream_in.write(code, codelength);
+			}
+			while (istream_in.good() && plainlength > 0);
+
+			codelength = encode_end(code);
+			ostream_in.write(code, codelength);
+			//
+			base64_init_encodestate(&_state);
+
+			delete [] code;
+			delete [] plaintext;
+		}
+	};
+
+} // namespace base64
+
+#endif // BASE64_ENCODE_H
+
Index: /tags/quest-pre-eventrefactoring/MFCtooling/userlog/filters.txt
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/userlog/filters.txt	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/userlog/filters.txt	(revision 540)
@@ -0,0 +1,106 @@
+Code for an inverse filter:
+
+	// inverse filter: defined messages will be filtered, all else just passes through
+	// may be replaced with a lookup-table to improve perfomance
+	// upon completion of the rules, i.e., when it is clear which messages are required,
+	// this should be changed to a "normal" filter.
+	switch(msg->message) {
+		case WM_NULL:
+		case WM_MOVE:
+		case WM_SIZE:
+		case WM_GETTEXT:
+		case WM_GETTEXTLENGTH:
+		case WM_PAINT:
+		case WM_ERASEBKGND:
+		case WM_SHOWWINDOW:
+		case WM_CANCELMODE:
+		case WM_SETCURSOR:
+		case WM_GETMINMAXINFO:
+		case WM_GETFONT:
+		case WM_WINDOWPOSCHANGING:
+		case WM_WINDOWPOSCHANGED:
+		case WM_NOTIFY:
+		case WM_STYLECHANGING:
+		case WM_STYLECHANGED:
+		case WM_GETICON:
+		case WM_NCCREATE:
+		case WM_NCDESTROY:
+		case WM_NCCALCSIZE:
+		case WM_NCHITTEST:
+		case WM_NCPAINT:
+		case WM_GETDLGCODE:
+		case 0x0090: // WM_UAHDESTROYWINDOW
+		case 0x0091: // WM_UAHDRAWMENU
+		case 0x0092: // WM_UADRAWMENUITEM
+		case 0x0093: // WM_UAHINITMENU
+		case 0x0094: // WM_UAHMEASUREMENUITEM
+		case 0x0095: // WM_UAHNCPAINTMENUPOPUP
+		case WM_NCMOUSEMOVE:
+		case WM_TIMER:
+		case WM_ENTERIDLE:
+		case WM_CTLCOLORMSGBOX:
+		case WM_CTLCOLOREDIT:
+		case WM_CTLCOLORLISTBOX:
+		case WM_CTLCOLORBTN:
+		case WM_CTLCOLORDLG:
+		case WM_CTLCOLORSCROLLBAR:
+		case WM_CTLCOLORSTATIC:
+		case WM_MOUSEMOVE:
+		case WM_PARENTNOTIFY:
+		case WM_MDIGETACTIVE:
+		case WM_IME_NOTIFY:
+		case WM_IME_SETCONTEXT:
+		case WM_AFXFIRST:
+		case WM_AFXFIRST+1:
+		case WM_AFXFIRST+2:
+		case WM_AFXFIRST+3:
+		case WM_AFXFIRST+4:
+		case WM_AFXFIRST+5:
+		case WM_AFXFIRST+6:
+		case WM_AFXFIRST+7:
+		case WM_AFXFIRST+8:
+		case WM_AFXFIRST+9:
+		case WM_AFXFIRST+10:
+		case WM_AFXFIRST+11:
+		case WM_AFXFIRST+12:
+		case WM_AFXFIRST+13:
+		case WM_AFXFIRST+14:
+		case WM_AFXFIRST+15:
+		case WM_AFXFIRST+16:
+		case WM_AFXFIRST+17:
+		case WM_AFXFIRST+18:
+		case WM_AFXFIRST+19:
+		case WM_AFXFIRST+20:
+		case WM_AFXFIRST+21:
+		case WM_AFXFIRST+22:
+		case WM_AFXFIRST+23:
+		case WM_AFXFIRST+24:
+		case WM_AFXFIRST+25:
+		case WM_AFXFIRST+26:
+		case WM_AFXFIRST+27:
+		case WM_AFXFIRST+28:
+		case WM_AFXFIRST+29:
+		case WM_AFXFIRST+30:
+		case WM_AFXLAST:
+		case 1025:
+		case 1031:
+		case 1142:
+		case 2024:
+		case 4100:
+		case 4101:
+		case 4103:
+		case 4352:
+		case 4362:
+		case 4363:
+		case 4364:
+		case 4365:
+		case 4372:
+		case 4613:
+			break;
+		default:
+			// exclude messages 0xC000-0xFFFF
+			if( !(msg->message>=0xC000 && msg->message<=0xFFFF) ) {
+				// CODE HERE!
+			}
+			break;
+	}
Index: /tags/quest-pre-eventrefactoring/MFCtooling/userlog/helpers.cpp
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/userlog/helpers.cpp	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/userlog/helpers.cpp	(revision 540)
@@ -0,0 +1,85 @@
+#include "stdafx.h"
+#include "helpers.h"
+
+bool MessageEquals(const MSG & msg1, const MSG & msg2) {
+	bool retVal = false;
+	if( (msg1.time==-1 && msg1.pt.x==-1 && msg1.pt.y==-1) || (msg2.time==-1 && msg2.pt.x==-1 && msg2.pt.y==-1) ) {
+		retVal = msg1.hwnd==msg2.hwnd && msg1.message==msg2.message && msg1.lParam==msg2.lParam &&
+			msg1.wParam==msg2.wParam;
+	} else {
+		retVal = msg1.hwnd==msg2.hwnd && msg1.message==msg2.message && msg1.lParam==msg2.lParam &&
+			msg1.wParam==msg2.wParam && msg1.time==msg2.time && msg1.pt.x==msg2.pt.x && msg1.pt.y==msg2.pt.y;
+	}
+	return retVal;
+}
+
+int replaceWithXmlEntitiesWString(const wchar_t * source, wchar_t ** target, size_t sourceLength) {
+	size_t j=0;
+	size_t extraLength = 0;
+	size_t bufsize = 300;
+	wchar_t * tmpTarget = new wchar_t[sourceLength+bufsize];
+	size_t i;
+	for( i=0; i<sourceLength && j<sourceLength+bufsize-5; i++ ) {
+		switch (source[i]) {
+			case L'&':
+				tmpTarget[j] = L'&';
+				tmpTarget[j+1]=L'a';
+				tmpTarget[j+2]=L'm';
+				tmpTarget[j+3]=L'p';
+				tmpTarget[j+4]=L';';
+				j += 5;
+				extraLength += 4;
+				break;
+			case L'<':
+				tmpTarget[j] = L'&';
+				tmpTarget[j+1]=L'l';
+				tmpTarget[j+2]=L't';
+				tmpTarget[j+3]=L';';
+				j += 4;
+				extraLength += 3;
+				break;
+			case L'>':
+				tmpTarget[j] = L'&';
+				tmpTarget[j+1]=L'g';
+				tmpTarget[j+2]=L't';
+				tmpTarget[j+3]=L';';
+				j += 4;
+				extraLength += 3;
+				break;
+			case L'\"':
+				tmpTarget[j] = L'&';
+				tmpTarget[j+1]=L'q';
+				tmpTarget[j+2]=L'u';
+				tmpTarget[j+3]=L'o';
+				tmpTarget[j+4]=L't';
+				tmpTarget[j+5]=L';';
+				j += 6;
+				extraLength += 5;
+				break;
+			case L'\'':
+				tmpTarget[j] = L'&';
+				tmpTarget[j+1]=L'a';
+				tmpTarget[j+2]=L'p';
+				tmpTarget[j+3]=L'o';
+				tmpTarget[j+4]=L's';
+				tmpTarget[j+5]=L';';
+				j += 6;
+				extraLength += 5;
+				break;
+			case L'%':
+				tmpTarget[j] = L'\\';
+				tmpTarget[j+1] = L'%';
+				j += 2;
+				extraLength += 1;
+				break;
+			default:
+				tmpTarget[j] = source[i];
+				j++;
+		}
+	}
+	*target = new wchar_t[j+1];
+	memcpy(*target,tmpTarget,j*sizeof(wchar_t));
+	(*target)[j] = '\0';
+	delete tmpTarget;
+	return j;
+}
Index: /tags/quest-pre-eventrefactoring/MFCtooling/userlog/helpers.h
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/userlog/helpers.h	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/userlog/helpers.h	(revision 540)
@@ -0,0 +1,13 @@
+#ifndef __HELPERS_H__
+#define __HELPERS_H__
+
+int replaceWithXmlEntitiesWString(const wchar_t * source, wchar_t ** target, size_t sourceLength);
+
+/**
+ * Compares two messages parameter-wise. 
+ * TODO: Check if this works better, if MSG.time and MSG.pt are ignored in the comparison, as they are missing in CWPSTRUCT.
+ * TODO: In case of CWPSTRICT both values are per default -1. 
+ */
+bool MessageEquals(const MSG & msg1, const MSG & msg2);
+
+#endif // __HELPERS_H__
Index: /tags/quest-pre-eventrefactoring/MFCtooling/userlog/stdafx.cpp
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/userlog/stdafx.cpp	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/userlog/stdafx.cpp	(revision 540)
@@ -0,0 +1,8 @@
+// stdafx.cpp : source file that includes just the standard includes
+// userlog.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+// TODO: reference any additional headers you need in STDAFX.H
+// and not in this file
Index: /tags/quest-pre-eventrefactoring/MFCtooling/userlog/stdafx.h
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/userlog/stdafx.h	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/userlog/stdafx.h	(revision 540)
@@ -0,0 +1,16 @@
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#pragma once
+
+#include "targetver.h"
+
+#define WIN32_LEAN_AND_MEAN             // Exclude rarely-used stuff from Windows headers
+// Windows Header Files:
+#include <windows.h>
+
+#include "cencode.h"
+#include "encode.h"
+// TODO: reference additional headers your program requires here
Index: /tags/quest-pre-eventrefactoring/MFCtooling/userlog/targetver.h
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/userlog/targetver.h	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/userlog/targetver.h	(revision 540)
@@ -0,0 +1,8 @@
+#pragma once
+
+// Including SDKDDKVer.h defines the highest available Windows platform.
+
+// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
+// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
+
+#include <SDKDDKVer.h>
Index: /tags/quest-pre-eventrefactoring/MFCtooling/userlog/userlog.cpp
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/userlog/userlog.cpp	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/userlog/userlog.cpp	(revision 540)
@@ -0,0 +1,528 @@
+#include "stdafx.h"
+#include "userlog.h"
+#include "windowsx.h"
+
+#include <map>
+#include <cstdio>
+
+#include "helpers.h"
+
+#ifdef __USING_MTRACE__
+#define OS_WIN32
+#include "msl/merror/inc/trace.h"
+
+#ifdef __ENCODE_BASE64__
+#include  "encode.h"
+#endif
+
+const static int traceLevel = 3;
+static int level;
+#endif
+
+#ifdef __USING_COSTUMLOG__
+static std::wofstream logfile;
+#endif
+
+#ifdef __TIMING__
+static unsigned long long timing = 0;
+static unsigned long long msgCounter = 0;
+static unsigned long long totalMsgCounter = 0;
+static bool msgCounterChange = false;
+#endif
+
+#ifndef MAXINT
+#define MAXUINT ((UINT)~((UINT)0))
+#define MAXINT ((INT(MAXUINT >> 1))
+#endif
+
+static MSG lastmsg;
+
+static bool keysPressed[256];
+
+inline bool keyAlreadyPressed(const MSG & msg) {
+	return (msg.message==WM_KEYDOWN || msg.message==WM_SYSKEYDOWN) && keysPressed[msg.wParam];
+}
+
+inline bool keyNotPressed(const MSG & msg) {
+	return (msg.message==WM_KEYUP || msg.message==WM_SYSKEYUP) && !keysPressed[msg.wParam];
+}
+
+
+HANDLE mutex;
+
+
+
+USERLOG_API void __cdecl InitUsagelog() {
+
+	mutex = CreateMutex(NULL, FALSE, TEXT("USAGELOGMUTEX"));
+	if( mutex == NULL ) {
+		MessageBox(0, L"MutexFailure", L"MutexFailure", 0);
+	}
+	for(int i=0; i<256; i++) {
+		keysPressed[i] = false;
+	}
+
+#ifdef __USING_COSTUMLOG__
+	InitLogfile();
+#endif
+	InitHookdata();
+	InitHooks();
+#ifdef __USING_MTRACE__
+	MTrace_AddToLevel(traceLevel,"%s<session>", LOGPREFIX);
+#endif
+#ifdef __USING_COSTUMLOG__
+	logfile << LOGPREFIX << "<session>" << std::endl;
+#endif
+}
+
+USERLOG_API void __cdecl ReleaseUsagelog() {
+	ReleaseHooks();
+#ifdef __USING_MTRACE__
+#ifdef __TIMING__
+	char * mtraceBuffer = new char[128];
+	sprintf(mtraceBuffer, "ul timing: %llu \t\t %llu \t\t %llu", timing, msgCounter, totalMsgCounter);
+	MTrace_AddToLevel(traceLevel,mtraceBuffer);
+	delete mtraceBuffer;
+	msgCounterChange = false;
+#endif
+	MTrace_AddToLevel(traceLevel,"%s</session>", LOGPREFIX);
+#endif
+#ifdef __USING_COSTUMLOG__
+	logfile << LOGPREFIX << "</session>" << std::endl;
+	CloseLogfile();
+#endif
+}
+
+#ifdef __USING_COSTUMLOG__
+void InitLogfile() {
+	logfile.open(LOGFILE, std::ios_base::app);
+	if( logfile.fail() ) {
+		MessageBox(0, L"Logfile could not be opend", L"Error", MB_OK);
+	}
+}
+#endif
+
+#ifdef __USING_COSTUMLOG__
+void CloseLogfile() {
+	logfile.close();
+}
+#endif
+
+void InitHookdata() {
+	myhookdata[CALLWNDHOOKID].nType = WH_CALLWNDPROC;
+	myhookdata[CALLWNDHOOKID].hkproc = CallWndProc;
+	myhookdata[GETMSGHOOKID].nType = WH_GETMESSAGE;
+	myhookdata[GETMSGHOOKID].hkproc = GetMsgProc;
+}
+
+void InitHooks() {
+	for( int i=0 ; i<NUMHOOKS ; i++ ) {
+		myhookdata[i].hookhandle = SetWindowsHookEx(myhookdata[i].nType, myhookdata[i].hkproc, (HINSTANCE) NULL, GetCurrentThreadId());
+		if( myhookdata[i].hookhandle!=NULL ) {
+			myhookdata[i].active = true;
+		} else {
+			myhookdata[i].active = false;
+		}
+	}
+}
+
+void ReleaseHooks() {
+	int counter = 0;
+	for( int i=0 ; i<NUMHOOKS ; i++ ) {
+		if( UnhookWindowsHookEx(myhookdata[i].hookhandle) ) counter++;
+	}
+}
+
+
+LRESULT CALLBACK CallWndProc(int nCode, WPARAM wParam, LPARAM lParam) {
+	
+	PCWPSTRUCT cwpMsg = (PCWPSTRUCT) lParam;
+	// Create a MSG struct from the cwpMsg struct
+	// The missing parameters are filled with dummy values
+	MSG msg;
+	msg.hwnd = cwpMsg->hwnd;
+	msg.message = cwpMsg->message;
+	msg.lParam = cwpMsg->lParam;
+	msg.wParam = cwpMsg->wParam;
+	msg.pt.x = -1;
+	msg.pt.y = -1;
+	msg.time = -1;
+	HookProc(CALLWNDHOOKID, nCode, &msg);
+
+	return CallNextHookEx(myhookdata[CALLWNDHOOKID].hookhandle, nCode, wParam, lParam);
+}
+
+LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam) {
+	PMSG msg = (PMSG) lParam;
+	HookProc(GETMSGHOOKID,nCode, msg);
+
+	return CallNextHookEx(myhookdata[GETMSGHOOKID].hookhandle, nCode, wParam, lParam);
+}
+
+void HookProc(int nFrom, int nCode, PMSG msg) {
+#ifdef __TIMING__
+	SYSTEMTIME systemTime;
+	GetSystemTime( &systemTime );
+	int startTime = systemTime.wMilliseconds+systemTime.wSecond*1000;
+#endif
+
+	DWORD waitResult;
+	// simple heuristic to eliminate duplicate messages
+	if( !( MessageEquals(*msg, lastmsg) || keyAlreadyPressed(*msg) || keyNotPressed(*msg) ) ) {
+		lastmsg = *msg;
+		if( msg->message==WM_KEYDOWN || msg->message==WM_SYSKEYDOWN ) {
+			keysPressed[msg->wParam] = true;
+		}
+		if( msg->message==WM_KEYUP || msg->message==WM_SYSKEYUP ) {
+			keysPressed[msg->wParam] = false;
+		}
+
+		// message filter:
+		// all messages that are defined in this switch statement will be part of the log
+		switch(msg->message) {
+			// messages for monitoring GUI state
+			case WM_CREATE:
+			case WM_DESTROY:
+			case WM_SETTEXT:
+
+			// mouse messages
+			case WM_LBUTTONDOWN:
+			case WM_LBUTTONUP:
+			case WM_LBUTTONDBLCLK:
+			case WM_RBUTTONDOWN:
+			case WM_RBUTTONUP:
+			case WM_RBUTTONDBLCLK:
+			case WM_MBUTTONDOWN:
+			case WM_MBUTTONUP:
+			case WM_MBUTTONDBLCLK:
+			case WM_XBUTTONDOWN:
+			case WM_XBUTTONUP:
+			case WM_XBUTTONDBLCLK:
+			case WM_NCLBUTTONDOWN:
+			case WM_NCLBUTTONUP:
+			case WM_NCLBUTTONDBLCLK:
+			case WM_NCRBUTTONDOWN:
+			case WM_NCRBUTTONUP:
+			case WM_NCRBUTTONDBLCLK:
+			case WM_NCMBUTTONDOWN:
+			case WM_NCMBUTTONUP:
+			case WM_NCMBUTTONDBLCLK:
+			case WM_NCXBUTTONDOWN:
+			case WM_NCXBUTTONUP:
+			case WM_NCXBUTTONDBLCLK:
+
+			// keyboard messages
+			case WM_KEYDOWN:
+			case WM_KEYUP:
+			case WM_SYSKEYDOWN:
+			case WM_SYSKEYUP:
+
+			// internal messages usefull for replay/matching of events
+			case WM_KILLFOCUS:
+			case WM_SETFOCUS:
+			case WM_COMMAND:
+			case WM_SYSCOMMAND:
+			case WM_HSCROLL:
+			case WM_VSCROLL:
+			case WM_MENUSELECT:
+			case WM_USER:
+				waitResult = WaitForSingleObject(mutex, 1000);
+				if( waitResult==WAIT_OBJECT_0 ) {
+					WriteLogentryWString(msg, nFrom);
+					ReleaseMutex(mutex);
+				}
+#ifdef __TIMING__
+				msgCounter++;
+				msgCounterChange = true;
+#endif // __TIMING__
+				break;
+			default:
+				break;
+		}
+	}
+
+#ifdef __TIMING__
+	GetSystemTime( &systemTime );
+	timing += systemTime.wMilliseconds+systemTime.wSecond*1000-startTime;
+	totalMsgCounter++;
+	if( msgCounterChange && msgCounter%100==0 ) {
+#ifdef __USING_MTRACE__
+		char * mtraceBuffer = new char[128];
+		sprintf(mtraceBuffer, "ul timing: %llu \t\t %llu \t\t %llu", timing, msgCounter, totalMsgCounter);
+		MTrace_AddToLevel(traceLevel,mtraceBuffer);
+		delete mtraceBuffer;
+		msgCounterChange = false;
+#endif // __USING_MTRACE__
+	}
+#endif // __TIMING__
+}
+
+
+void WriteLogentryWString(PMSG msg, int nFrom) {
+	wchar_t * messageStr = NULL;
+	wchar_t buffer[128];
+	wchar_t * newWindowText = NULL;
+	wchar_t * windowName = NULL;
+	unsigned int command = 0;
+	int sourceType = -1;
+	HWND source = NULL;
+	HWND parentHandle = NULL;
+	wchar_t * windowClass = NULL;
+	bool isPopup = false;
+	bool isModal = false;
+	bool htMenu = false;
+	HWND menuHandle = NULL;
+	int scrollPos = -1;
+	unsigned int scrollType = 0;
+	HWND scrollBarHandle = NULL;
+	int retVal = 0;
+	int pointx = -1;
+	int pointy = -1;
+
+	// debug vars
+	
+	retVal = GetWindowText(msg->hwnd, buffer, 128);
+	if( retVal > 0  && retVal<MAXINT ) {
+		/*
+		 * In one case at the start of MarWin, when a resource with DlgId 1049 is created,
+		 * GetWindowText returns MAXINT. This behaviour is undocumented.
+		 */
+		replaceWithXmlEntitiesWString(buffer, &windowName, retVal+1);
+	}
+	int windowResourceId = GetDlgCtrlID(msg->hwnd);
+	if( windowResourceId<0 ) {
+		windowResourceId = 0;
+	}
+
+	//**************************************
+	// Message specific variables
+	//**************************************
+
+	if( msg->message==WM_COMMAND ) {
+		command = LOWORD(msg->wParam);
+		sourceType = HIWORD(msg->wParam);
+		source = (HWND) msg->lParam;
+	}
+	if( msg->message==WM_SYSCOMMAND ) {
+		command = LOWORD(msg->wParam);
+	}
+
+	if( msg->message==WM_CREATE ) {
+		parentHandle = GetParent(msg->hwnd);
+		
+		retVal = GetClassName(msg->hwnd, buffer, 128);
+		if( retVal > 0  && retVal<MAXINT ) {
+			replaceWithXmlEntitiesWString(buffer, &windowClass, retVal+1);
+		}
+
+		// check is dialog is modal
+		// this check is not always accurate, but the best that I could come up with
+		isModal = IsWindowEnabled(parentHandle)==false;
+	}
+
+	if( msg->message==WM_SETTEXT ) {
+		wchar_t * newWindowTextBuffer = (wchar_t*)msg->lParam;
+		if( newWindowTextBuffer!=NULL ) {
+			size_t len = wcslen(newWindowTextBuffer);
+			replaceWithXmlEntitiesWString(newWindowTextBuffer, &newWindowText, len+1);
+		}
+	}
+
+	if( msg->message==WM_LBUTTONUP || msg->message==WM_RBUTTONUP || msg->message==WM_MBUTTONUP ||
+		msg->message==WM_LBUTTONDOWN || msg->message==WM_RBUTTONDOWN || msg->message==WM_MBUTTONDOWN ||
+		msg->message==WM_LBUTTONDBLCLK || msg->message==WM_RBUTTONDBLCLK || msg->message==WM_MBUTTONDBLCLK ||
+		msg->message==WM_NCLBUTTONUP || msg->message==WM_NCRBUTTONUP || msg->message==WM_NCMBUTTONUP ||
+		msg->message==WM_NCLBUTTONDOWN || msg->message==WM_NCRBUTTONDOWN || msg->message==WM_NCMBUTTONDOWN ||
+		msg->message==WM_NCLBUTTONDBLCLK || msg->message==WM_NCRBUTTONDBLCLK || msg->message==WM_NCMBUTTONDBLCLK) {
+		
+		RECT r;
+		DWORD dCursorPos = GetMessagePos();
+		GetWindowRect(msg->hwnd, &r);
+		//dont log absolut coordinates but relativ ones so you can use them in rule "LeftClickRelativ"
+		pointx = GET_X_LPARAM(dCursorPos)-r.left;
+		pointy = GET_Y_LPARAM(dCursorPos)-r.top;
+	}
+
+	if( msg->message==WM_NCLBUTTONDOWN ) {
+		if( msg->wParam==HTMENU ) {
+			htMenu = true;
+		}
+	}
+	
+	if( msg->message==WM_INITMENU ) {
+		menuHandle = (HWND) msg->wParam;
+	}
+
+	if( msg->message==WM_HSCROLL || msg->message==WM_VSCROLL ) {
+		scrollType = LOWORD(msg->wParam);
+		scrollPos = HIWORD(msg->wParam);
+		scrollBarHandle = (HWND) msg->lParam;
+	}
+
+	/***************************************/
+	// put debugging variables here
+	/***************************************/
+
+
+	/***************************************
+	 * Printing part
+	 ***************************************/
+	
+	size_t bufsize = 2048;
+	wchar_t * msgBuffer = new wchar_t[bufsize];
+	size_t pos = 0;
+	//pos += swprintf_s(msgBuffer+pos, bufsize-pos,LOGPREFIXWSTRING);
+
+	
+	// print msg information
+	pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<msg type=\"%i\">",msg->message);
+	pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"WPARAM\" value=\"%i\"/>", msg->wParam);
+	pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"LPARAM\" value=\"%i\"/>", msg->lParam);
+
+	pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"window.hwnd\" value=\"%i\"/>", msg->hwnd);
+	if( msg->message==WM_COMMAND ) {
+		pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"command\" value=\"%i\"/>",command);
+		pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"sourceType\" value=\"%i\"/>",sourceType);
+		pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"source\" value=\"%i\"/>",source);
+	}
+	if( msg->message==WM_SYSCOMMAND ) {
+		pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"command\" value=\"%i\"/>", command);
+	}
+
+	if( msg->message==WM_LBUTTONUP || msg->message==WM_RBUTTONUP || msg->message==WM_MBUTTONUP ||
+		msg->message==WM_LBUTTONDOWN || msg->message==WM_RBUTTONDOWN || msg->message==WM_MBUTTONDOWN ||
+		msg->message==WM_LBUTTONDBLCLK || msg->message==WM_RBUTTONDBLCLK || msg->message==WM_MBUTTONDBLCLK ||
+		msg->message==WM_NCLBUTTONUP || msg->message==WM_NCRBUTTONUP || msg->message==WM_NCMBUTTONUP ||
+		msg->message==WM_NCLBUTTONDOWN || msg->message==WM_NCRBUTTONDOWN || msg->message==WM_NCMBUTTONDOWN ||
+		msg->message==WM_NCLBUTTONDBLCLK || msg->message==WM_NCRBUTTONDBLCLK || msg->message==WM_NCMBUTTONDBLCLK) {
+		
+		
+		pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"point.x\" value=\"%i\"/>", pointx);
+		pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"point.y\" value=\"%i\"/>", pointy);
+
+		if(msg->message == WM_LBUTTONUP)
+		{
+			//check the listBox selection, store it in "scrollPos"
+			//no selection = -1
+			//this is only working for listBoxes with style 'selection = single'
+			retVal = GetClassName(msg->hwnd, buffer, 128);
+			if( retVal >= -1  && retVal < MAXINT && !lstrcmpi(buffer, L"ListBox") )
+			{
+				scrollPos = (int)SendMessage(msg->hwnd, LB_GETCURSEL, 0, 0);
+				pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"scrollPos\" value=\"%i\"/>", scrollPos);
+			}
+
+
+			retVal = GetClassName(msg->hwnd, buffer, 128);
+			if( retVal >= -1  && retVal < MAXINT && (!lstrcmpi(buffer, L"ComboLBox")||!lstrcmpi(buffer, L"ComboBox")) )
+			{
+				scrollPos = (int)SendMessage(msg->hwnd, CB_GETCURSEL, 0, 0);
+				pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"scrollPos\" value=\"%i\"/>", scrollPos);
+			}
+
+			//check the TabControl selection, store it in "scrollPos"
+			//no selection = -1
+			retVal = GetClassName(msg->hwnd, buffer, 128);
+			if( retVal >= -1  && retVal < MAXINT && !lstrcmpi(buffer, L"SysTabControl32") )
+			{
+				scrollPos = (int)SendMessage(msg->hwnd, (UINT)4875, 0, 0);
+				pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"scrollPos\" value=\"%i\"/>", scrollPos);
+			}
+		}
+	}
+	if( msg->message==WM_MOUSEACTIVATE ) {
+		pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"toplevelwindow.hwnd\" value=\"%i\"/>", (HWND) msg->wParam);
+	}
+	if( msg->message==WM_KEYUP || msg->message==WM_KEYDOWN || msg->message==WM_SYSKEYUP || msg->message==WM_SYSKEYDOWN ) {
+		pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"key\" value=\"%i\"/>", LOWORD(msg->wParam));
+	}
+	if( msg->message==WM_SETTEXT ) {
+		if( newWindowText!=NULL ) {
+			pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"window.newText\" value=\"%s\"/>", newWindowText);
+		}
+	}
+	
+	if( msg->message==WM_NCLBUTTONDOWN && htMenu ) {
+		pos += swprintf_s(msgBuffer+pos, bufsize-pos,L"<param name=\"isMenu\" value=\"true\"/>");
+	}
+
+	if( msg->message==WM_INITMENU ) {
+		pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"menu.hwnd\" value=\"%i\"/>", menuHandle);
+	}
+
+	if( msg->message==WM_CREATE ) {
+		// print window information
+		if( windowName!=NULL ) {
+			pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"window.name\" value=\"%s\"/>", windowName);
+		}
+		if( windowResourceId>0 ) {
+			pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"window.resourceId\" value=\"%i\"/>", windowResourceId);
+		}
+		if( msg->message==WM_CREATE ) {
+			if( parentHandle!=NULL ) {
+				pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"window.parent.hwnd\" value=\"%i\"/>", parentHandle);
+			}
+			if( windowClass!=NULL ) {
+				pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"window.class\" value=\"%s\"/>", windowClass);
+			}
+			if( isModal ) {
+				pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"window.ismodal\" value=\"true\"/>");
+			}
+
+		}
+	}
+	if( msg->message==WM_HSCROLL || msg->message==WM_VSCROLL ) {
+		pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"scrollType\" value=\"%i\"/>", scrollType);
+		pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"scrollPos\" value=\"%i\"/>", scrollPos);
+		pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"scrollBarHandle\" value=\"%i\"/>", scrollBarHandle);
+	}
+
+	if( msg->time!=-1 ) {
+		pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"time\" value=\"%i\"/>", msg->time);
+	}
+	
+	/***************************************/
+	// put debugging and experimental output stuff here
+	/***************************************/
+
+#ifdef __INCLUDEHOOKINFO__
+	pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"hook\" value=\"%i\"/>", nFrom);
+#endif
+	
+
+	pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"</msg>", msg->hwnd);
+#ifdef __USING_MTRACE__
+#ifdef __ENCODE_BASE64__
+	size_t arraySize = (pos+1)*2;
+	size_t encodingSize = arraySize*2;
+	char * base64Buffer = new char[encodingSize];
+
+	base64::encoder enc;
+	retVal = enc.encode((char*)msgBuffer, arraySize, base64Buffer);
+	base64Buffer[retVal] = '\0';
+
+	char * mtraceBuffer = new char[retVal+30];
+	sprintf_s(mtraceBuffer,retVal+29,"%s%s", LOGPREFIX, base64Buffer);
+	delete base64Buffer;
+#else
+	char * mtraceBuffer = new char[pos+1];
+	size_t numConverted;
+	wcstombs_s(&numConverted,mtraceBuffer, pos+1, msgBuffer, pos);
+#endif // __ENCODE_BASE64__
+	MTrace_AddToLevel(traceLevel,mtraceBuffer);
+	delete mtraceBuffer;
+#endif // __USING_MTRACE__
+#ifdef __USING_COSTUMLOG__
+	SYSTEMTIME currentTime;
+	GetSystemTime(&currentTime);
+	logfile << currentTime.wDay << "." << currentTime.wMonth << "." << currentTime.wYear << " ";
+	logfile << currentTime.wHour << ":" << currentTime.wMinute << ":" << currentTime.wSecond << ":";
+	logfile << currentTime.wMilliseconds << "\t";
+	logfile << LOGPREFIX << msgBuffer << std::endl;
+#endif
+	delete messageStr;
+	delete newWindowText;
+	delete windowName;
+	delete windowClass;
+	delete msgBuffer;
+}
Index: /tags/quest-pre-eventrefactoring/MFCtooling/userlog/userlog.h
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/userlog/userlog.h	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/userlog/userlog.h	(revision 540)
@@ -0,0 +1,85 @@
+#ifndef __USERLOG_H__
+#define __USERLOG_H__
+
+#ifdef USERLOG_EXPORTS
+#define USERLOG_API __declspec(dllexport)
+#else
+#define USERLOG_API __declspec(dllimport)
+#endif
+
+#include <iostream>
+#include <fstream>
+
+
+
+//#define __USING_MTRACE__
+//#define __USING_COSTUMLOG__
+//#define __INCLUDEHOOKINFO__
+//#define __TIMING__
+//#define __ENCODE_BASE64__
+
+#define LOGPREFIX " UL: "
+#define LOGPREFIXCONT " ULC: "
+#define LOGPREFIXWSTRING L" UL: "
+
+#define NUMHOOKS 2
+
+#define CALLWNDHOOKID 0
+#define GETMSGHOOKID 1
+
+#ifdef __USING_COSTUMLOG__
+#define LOGFILE "usagelog.txt"
+#endif
+
+typedef struct _HOOKDATA {
+	int nType;
+	HOOKPROC hkproc;
+	HHOOK hookhandle;
+	bool active;
+} HOOKDATA;
+
+HOOKDATA myhookdata[NUMHOOKS];
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * API function that starts the logging of messages. 
+ * All required hooks and logging mechanisms are initialized. 
+ */
+USERLOG_API void __cdecl InitUsagelog();
+
+/**
+ * API function that stopts the logging of messages. 
+ * All existing hooks are released and if required, logging mechnisms are stopped.
+ */
+USERLOG_API void __cdecl ReleaseUsagelog();
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+
+void InitHookdata();
+
+void InitHooks();
+
+void ReleaseHooks();
+
+
+LRESULT CALLBACK CallWndProc(int nCode, WPARAM wParam, LPARAM lParam);
+
+LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam);
+
+void HookProc(int nFrom, int nCode, PMSG msg);
+
+void WriteLogentryWString(PMSG msg, int nFrom);
+
+#ifdef __USING_COSTUMLOG__
+void InitLogfile();
+
+void CloseLogfile();
+#endif
+
+#endif // __USERLOG_H__
Index: /tags/quest-pre-eventrefactoring/MFCtooling/userlog/userlog.vcproj
===================================================================
--- /tags/quest-pre-eventrefactoring/MFCtooling/userlog/userlog.vcproj	(revision 540)
+++ /tags/quest-pre-eventrefactoring/MFCtooling/userlog/userlog.vcproj	(revision 540)
@@ -0,0 +1,352 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9,00"
+	Name="userlog"
+	ProjectGUID="{A881CC90-25D4-4D76-A30D-C8CA09A3434D}"
+	RootNamespace="userlog"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug_MTrace|Win32"
+			OutputDirectory="$(SolutionDir)Debug"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="2"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(SolutionDir)/../"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;USERLOG_EXPORTS;__USING_MTRACE__;__ENCODE_BASE64__"
+				MinimalRebuild="false"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				TreatWChar_tAsBuiltInType="true"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="trace.lib"
+				AdditionalLibraryDirectories="&quot;$(SolutionDir)/../msl/lib/$(PlatformName)/Debug&quot;"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release_MTrace|Win32"
+			OutputDirectory="$(SolutionDir)Release"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="2"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(SolutionDir)/../"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;USERLOG_EXPORTS;__USING_MTRACE__;__ENABLE_BASE64__"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="2"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="trace.lib"
+				AdditionalLibraryDirectories="&quot;$(SolutionDir)/../msl/lib/$(PlatformName)/Release&quot;"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug_Costumlog|Win32"
+			OutputDirectory="$(SolutionDir)Debug"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="2"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories=""
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;USERLOG_EXPORTS;__USING_COSTUMLOG__"
+				MinimalRebuild="false"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				TreatWChar_tAsBuiltInType="true"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalLibraryDirectories=""
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release_Costumlog|Win32"
+			OutputDirectory="$(SolutionDir)Release"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="2"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories=""
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;USERLOG_EXPORTS;__USING_COSTUMLOG__"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalLibraryDirectories=""
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath=".\cencode.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\dllmain.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\helpers.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\stdafx.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\userlog.cpp"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+			<File
+				RelativePath=".\cencode.h"
+				>
+			</File>
+			<File
+				RelativePath=".\encode.h"
+				>
+			</File>
+			<File
+				RelativePath=".\helpers.h"
+				>
+			</File>
+			<File
+				RelativePath=".\stdafx.h"
+				>
+			</File>
+			<File
+				RelativePath=".\targetver.h"
+				>
+			</File>
+			<File
+				RelativePath=".\userlog.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+			>
+		</Filter>
+		<File
+			RelativePath=".\filters.txt"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
Index: /tags/quest-pre-eventrefactoring/PHPMonitor/postlog.php
===================================================================
--- /tags/quest-pre-eventrefactoring/PHPMonitor/postlog.php	(revision 540)
+++ /tags/quest-pre-eventrefactoring/PHPMonitor/postlog.php	(revision 540)
@@ -0,0 +1,34 @@
+<?php
+  /*
+   * Usage monitoring script for PHP web applications.
+   * Requires the apache modules mod_usertrack to provide
+   * a cookie for user identification.
+   */
+  $log_dir = dirname( __FILE__)."/";
+  $log_name = "usage.log";
+  $cookie_name = "swe_informatik_uni-goettingen_de";
+
+  $postkeys = "";
+
+  while (list($key, $value) = each($_POST)) {
+    $postkeys = $postkeys." ".$key;
+  }
+  if( $_SERVER['HTTP_REFERER']=='' ) {
+    $referer = '-';
+  } else {
+    $referer = $_SERVER['HTTP_REFERER'];
+  }
+
+  $cookieVal = $_COOKIE[$cookie_name];
+  if($cookieVal==0) {
+    $apacheHeader = apache_response_headers();
+    $explodeResult1 = explode(';',$apacheHeader['Set-Cookie']);
+    $explodeResult2 = explode('=',$explodeResult1[0]);
+    $cookieVal = $explodeResult2[1];
+  }
+
+  $log_entry = "\"".$cookieVal."\" \"".gmdate('Y-m-d H:i:s')."\" \"".$_SERVER['REQUEST_URI']."\" \"".$referer."\" \"".$_SERVER['HTTP_USER_AGENT']."\" \"".$postkeys."\"\r\n";
+  $fp=fopen( $log_dir . $log_name, 'a' );
+  fputs($fp, $log_entry);
+  fclose($fp);
+?>
Index: /tags/quest-pre-eventrefactoring/java-utils-test/.classpath
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils-test/.classpath	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils-test/.classpath	(revision 540)
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/test-classes" path="src/test/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
Index: /tags/quest-pre-eventrefactoring/java-utils-test/.project
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils-test/.project	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils-test/.project	(revision 540)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>java-utils-test</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
Index: /tags/quest-pre-eventrefactoring/java-utils-test/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils-test/.settings/org.eclipse.jdt.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils-test/.settings/org.eclipse.jdt.core.prefs	(revision 540)
@@ -0,0 +1,5 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.6
Index: /tags/quest-pre-eventrefactoring/java-utils-test/.settings/org.eclipse.m2e.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils-test/.settings/org.eclipse.m2e.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils-test/.settings/org.eclipse.m2e.core.prefs	(revision 540)
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
Index: /tags/quest-pre-eventrefactoring/java-utils-test/pom.xml
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils-test/pom.xml	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils-test/pom.xml	(revision 540)
@@ -0,0 +1,133 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>de.ugoe.cs</groupId>
+  <artifactId>java-utils-test</artifactId>
+  <version>0.0.1-SNAPSHOT</version>
+  <name>java-utils-test</name>
+  <scm>
+    <url>https://quest.informatik.uni-goettingen.de/svn/quest/trunk/java-utils-test</url>
+  </scm>
+  <dependencies>
+    <dependency>
+        <groupId>de.ugoe.cs</groupId>
+        <artifactId>java-utils</artifactId>
+        <version>0.0.1-SNAPSHOT</version>
+        <scope>test</scope>
+    </dependency>
+    <dependency>
+        <groupId>junit</groupId>
+        <artifactId>junit</artifactId>
+        <version>4.8.1</version>
+        <scope>test</scope>
+    </dependency>
+    <dependency>
+	  <groupId>junit-addons</groupId>
+	  <artifactId>junit-addons</artifactId>
+	  <version>1.4</version>
+    </dependency>
+  </dependencies>
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.eclipse.m2e</groupId>
+          <artifactId>lifecycle-mapping</artifactId>
+          <version>1.0.0</version>
+          <configuration>
+            <lifecycleMappingMetadata>
+              <pluginExecutions>
+                <pluginExecution>
+                  <pluginExecutionFilter>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-dependency-plugin</artifactId>
+                    <versionRange>[1.0.0,)</versionRange>
+                    <goals>
+                      <goal>unpack</goal>
+                    </goals>
+                  </pluginExecutionFilter>
+                  <action>
+                    <ignore/>
+                  </action>
+                </pluginExecution>
+                <pluginExecution>
+                  <pluginExecutionFilter>
+                    <groupId>org.codehaus.mojo</groupId>
+                    <artifactId>emma-maven-plugin</artifactId>
+                    <versionRange>[1.0-alpha-3,)</versionRange>
+                    <goals>
+                      <goal>emma</goal>
+                    </goals>
+                  </pluginExecutionFilter>
+                  <action>
+                    <ignore/>
+                  </action>
+                </pluginExecution>
+              </pluginExecutions>
+            </lifecycleMappingMetadata>
+          </configuration>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>2.3.2</version>
+        <configuration>
+          <source>1.6</source>
+          <target>1.6</target>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-dependency-plugin</artifactId>
+        <version>2.4</version>
+        <executions>
+          <execution>
+            <id>unpack</id>
+            <phase>process-classes</phase>
+            <goals>
+              <goal>unpack</goal>
+            </goals>
+            <configuration>
+              <artifactItems>
+                <artifactItem>
+                  <groupId>de.ugoe.cs</groupId>
+                  <artifactId>java-utils</artifactId>
+                  <version>0.0.1-SNAPSHOT</version>
+                  <outputDirectory>${project.build.directory}/classes</outputDirectory>
+                </artifactItem>
+              </artifactItems>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>emma-maven-plugin</artifactId>
+        <version>1.0-alpha-3</version>
+        <inherited>true</inherited>          
+        <executions>
+          <execution>
+            <phase>process-classes</phase>
+            <goals>
+              <goal>emma</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <version>2.3.2</version>
+        <executions>
+          <execution>
+            <goals>
+              <goal>test-jar</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>
Index: /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/ArrayToolsTest.java
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/ArrayToolsTest.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/ArrayToolsTest.java	(revision 540)
@@ -0,0 +1,189 @@
+package de.ugoe.cs.util;
+
+import org.junit.*;
+import static org.junit.Assert.*;
+
+/**
+ * The class <code>ArrayToolsTest</code> contains tests for the class
+ * <code>{@link ArrayTools}</code>.
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class ArrayToolsTest {
+
+	Integer array[];
+
+	@Test
+	public void testFindIndex_1() throws Exception {
+		Integer target = 3;
+		int expected = 3;
+
+		int result = ArrayTools.findIndex(array, target);
+
+		assertEquals(expected, result);
+	}
+
+	@Test
+	public void testFindIndex_2() throws Exception {
+		Integer target = 4;
+		int expected = 4;
+
+		int result = ArrayTools.findIndex(array, target);
+
+		assertEquals(expected, result);
+	}
+
+	@Test
+	public void testFindIndex_3() throws Exception {
+		Integer target = 7;
+
+		int result = ArrayTools.findIndex(array, target);
+		int expected = -1;
+		
+		assertEquals(expected, result);
+	}
+
+	@Test
+	public void testFindIndex_4() throws Exception {
+		Integer target = null;
+		int result = ArrayTools.findIndex(array, target);
+		int expected = 7;
+		assertEquals(expected, result);
+	}
+
+	@Test
+	public void testFindIndex_5() throws Exception {
+		Object[] array = new Object[0];
+		Object other = new Object();
+
+		int result = ArrayTools.findIndex(array, other);
+
+		assertEquals(-1, result);
+	}
+	
+	@Test
+	public void testFindMax_1() throws Exception {
+		int expected = 8;
+		
+		int result = ArrayTools.findMax(array);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testFindMax_2() throws Exception {
+		Integer[] arrayUnsorted = new Integer[]{2,3,6,1,8,9,1,1,3,15,4,0,-1};
+		int expected = 9;
+		
+		int result = ArrayTools.findMax(arrayUnsorted);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testFindMax_3() throws Exception {
+		Integer[] arrayUnsorted = new Integer[]{2,3,6,1,8,9,1,1,3,15,4,15,-1};
+		int expected = 9;
+		
+		int result = ArrayTools.findMax(arrayUnsorted);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testFindMax_4() throws Exception {
+		Integer[] arrayNoLenght = new Integer[]{};
+		int expected = -1;
+		
+		int result = ArrayTools.findMax(arrayNoLenght);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testFindMax_5() throws Exception {
+		Integer[] arrayNulls = new Integer[]{null, null};
+		int expected = -1;
+		
+		int result = ArrayTools.findMax(arrayNulls);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testFindMax_6() throws Exception {
+		int expected = -1;
+		
+		int result = ArrayTools.findMax(null);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testFindMin_1() throws Exception {
+		int expected = 0;
+		
+		int result = ArrayTools.findMin(array);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testFindMin_2() throws Exception {
+		Integer[] arrayUnsorted = new Integer[]{2,3,6,1,8,9,1,1,-3,15,4,0,-1};
+		int expected = 8;
+		
+		int result = ArrayTools.findMin(arrayUnsorted);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testFindMin_3() throws Exception {
+		Integer[] arrayUnsorted = new Integer[]{2,3,6,1,8,9,1,-1,3,15,4,15,-1};
+		int expected = 7;
+		
+		int result = ArrayTools.findMin(arrayUnsorted);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testFindMin_4() throws Exception {
+		Integer[] arrayNoLenght = new Integer[]{};
+		int expected = -1;
+		
+		int result = ArrayTools.findMin(arrayNoLenght);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testFindMin_5() throws Exception {
+		Integer[] arrayNulls = new Integer[]{null, null};
+		int expected = -1;
+		
+		int result = ArrayTools.findMin(arrayNulls);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testFindMin_6() throws Exception {
+		int expected = -1;
+		
+		int result = ArrayTools.findMin(null);
+		
+		assertEquals(expected, result);
+	}
+
+	@Before
+	public void setUp() throws Exception {
+		array = new Integer[] { 0, 1, 2, 3, 4, 4, 5, null, 6 };
+	}
+
+	public static void main(String[] args) {
+		new org.junit.runner.JUnitCore().run(ArrayToolsTest.class);
+	}
+}
Index: /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/FileToolsTest.java
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/FileToolsTest.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/FileToolsTest.java	(revision 540)
@@ -0,0 +1,64 @@
+package de.ugoe.cs.util;
+
+import org.junit.*;
+import static org.junit.Assert.*;
+
+/**
+ * The class <code>FileToolsTest</code> contains tests for the class
+ * <code>{@link FileTools}</code>.
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class FileToolsTest {
+
+	final static String filenameNoCR = "testdata/de.ugoe.cs.util.FileToolsTest/testdata-nocr.txt";
+	final static String filenameCR = "testdata/de.ugoe.cs.util.FileToolsTest/testdata-cr.txt";
+	final static String filenameNotExists = "testdata/de.ugoe.cs.util.FileToolsTest/doesnotexist.txt";
+
+	final static String[] expectedLines = { "line1", "line2", "line3", "",
+			"line5" };
+
+	final static String[] expectedLinesCR = { "line1\r", "line2\r", "line3\r",
+			"\r", "line5" };
+
+	final static String[] expectedWrongCR = { "line1\nline2\nline3\n\nline5" };
+
+	@Test
+	public void testGetLinesFromFile_1() throws Exception {
+		String[] result = FileTools.getLinesFromFile(filenameCR, true);
+		assertArrayEquals(expectedLines, result);
+	}
+
+	@Test
+	public void testGetLinesFromFile_2() throws Exception {
+		String[] result = FileTools.getLinesFromFile(filenameNoCR, true);
+		assertArrayEquals(expectedWrongCR, result);
+	}
+
+	@Test
+	public void testGetLinesFromFile_3() throws Exception {
+		String[] result = FileTools.getLinesFromFile(filenameNoCR, false);
+		assertArrayEquals(expectedLines, result);
+	}
+
+	@Test
+	public void testGetLinesFromFile_4() throws Exception {
+		String[] result = FileTools.getLinesFromFile(filenameCR, false);
+		assertArrayEquals(expectedLinesCR, result);
+	}
+
+	@Test(expected = java.io.FileNotFoundException.class)
+	public void testGetLinesFromFile_5() throws Exception {
+		FileTools.getLinesFromFile(filenameNotExists, true);
+	}
+
+	@Test(expected = java.io.FileNotFoundException.class)
+	public void testGetLinesFromFile_6() throws Exception {
+		FileTools.getLinesFromFile(filenameNotExists, false);
+	}
+
+	public static void main(String[] args) {
+		new org.junit.runner.JUnitCore().run(FileToolsTest.class);
+	}
+}
Index: /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/StringToolsTest.java
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/StringToolsTest.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/StringToolsTest.java	(revision 540)
@@ -0,0 +1,136 @@
+package de.ugoe.cs.util;
+
+import org.junit.*;
+import static org.junit.Assert.*;
+
+/**
+ * The class <code>StringToolsTest</code> contains tests for the class
+ * <code>{@link StringTools}</code>.
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class StringToolsTest {
+
+	@Test
+	public void testXmlEntityReplacement_1() throws Exception {
+		String str = "abc";
+
+		String result = StringTools.xmlEntityReplacement(str);
+
+		// add additional test code here
+		assertEquals("abc", result);
+	}
+
+	@Test
+	public void testXmlEntityReplacement_2() throws Exception {
+		String str = "a&bc";
+		String result = StringTools.xmlEntityReplacement(str);
+		assertEquals("a&amp;bc", result);
+	}
+
+	@Test
+	public void testXmlEntityReplacement_3() throws Exception {
+		String str = "a\"bc";
+		String result = StringTools.xmlEntityReplacement(str);
+		assertEquals("a&quot;bc", result);
+	}
+
+	@Test
+	public void testXmlEntityReplacement_4() throws Exception {
+		String str = "a'bc";
+		String result = StringTools.xmlEntityReplacement(str);
+		assertEquals("a&apos;bc", result);
+	}
+
+	@Test
+	public void testXmlEntityReplacement_5() throws Exception {
+		String str = "a<bc";
+		String result = StringTools.xmlEntityReplacement(str);
+		assertEquals("a&lt;bc", result);
+	}
+
+	@Test
+	public void testXmlEntityReplacement_6() throws Exception {
+		String str = "a>bc";
+		String result = StringTools.xmlEntityReplacement(str);
+		assertEquals("a&gt;bc", result);
+	}
+
+	@Test
+	public void testXmlEntityReplacement_7() throws Exception {
+		String str = "a&amp;bc";
+		String result = StringTools.xmlEntityReplacement(str);
+		assertEquals("a&amp;bc", result);
+	}
+
+	@Test
+	public void testXmlEntityReplacement_8() throws Exception {
+		String str = "a&quot;bc";
+		String result = StringTools.xmlEntityReplacement(str);
+		assertEquals("a&quot;bc", result);
+	}
+
+	@Test
+	public void testXmlEntityReplacement_9() throws Exception {
+		String str = "a&apos;bc";
+		String result = StringTools.xmlEntityReplacement(str);
+		assertEquals("a&apos;bc", result);
+	}
+
+	@Test
+	public void testXmlEntityReplacement_10() throws Exception {
+		String str = "a&lt;bc";
+		String result = StringTools.xmlEntityReplacement(str);
+		assertEquals("a&lt;bc", result);
+	}
+
+	@Test
+	public void testXmlEntityReplacement_11() throws Exception {
+		String str = "a&gt;bc";
+		String result = StringTools.xmlEntityReplacement(str);
+		assertEquals("a&gt;bc", result);
+	}
+
+	@Test
+	public void testXmlEntityReplacement_12() throws Exception {
+		String str = "a&foo;bc";
+		String result = StringTools.xmlEntityReplacement(str);
+		assertEquals("a&amp;foo;bc", result);
+	}
+
+	@Test
+	public void testXmlEntityReplacement_13() throws Exception {
+		String str = "a&b&c";
+		String result = StringTools.xmlEntityReplacement(str);
+		assertEquals("a&amp;b&amp;c", result);
+	}
+	
+	@Test
+	public void testXmlEntityReplacement_14() throws Exception {
+		String str = "";
+		String result = StringTools.xmlEntityReplacement(str);
+		assertEquals("", result);
+	}
+	
+	@Test
+	public void testXmlEntityReplacement_15() throws Exception {
+		String str = null;
+		String result = StringTools.xmlEntityReplacement(str);
+		assertNull(result);
+	}
+
+	@Before
+	public void setUp() throws Exception {
+		// add additional set up code here
+	}
+
+	@After
+	public void tearDown() throws Exception {
+		// Add additional tear down code here
+	}
+
+	public static void main(String[] args) {
+		new org.junit.runner.JUnitCore().run(StringToolsTest.class);
+	}
+}
Index: /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/TestAll.java
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/TestAll.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/TestAll.java	(revision 540)
@@ -0,0 +1,27 @@
+package de.ugoe.cs.util;
+
+import org.junit.runner.JUnitCore;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+/**
+ * The class <code>TestAll</code> builds a suite that can be used to run all
+ * of the tests within its package as well as within any subpackages of its
+ * package.
+ *
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+	StringToolsTest.class,
+	FileToolsTest.class,
+	ArrayToolsTest.class,
+	de.ugoe.cs.util.console.TestAll.class
+})
+public class TestAll {
+
+	public static void main(String[] args) {
+		JUnitCore.runClasses(new Class[] { TestAll.class });
+	}
+}
Index: /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/CommandExecuterTest.java
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/CommandExecuterTest.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/CommandExecuterTest.java	(revision 540)
@@ -0,0 +1,106 @@
+package de.ugoe.cs.util.console;
+
+import org.junit.*;
+
+import de.ugoe.cs.util.console.mock.MockOutputListener;
+import static org.junit.Assert.*;
+
+/**
+ * The class <code>CommandExecuterTest</code> contains tests for the class
+ * <code>{@link CommandExecuter}</code>.
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CommandExecuterTest {
+
+	@Test(expected=java.security.InvalidParameterException.class)
+	public void testAddCommandPackage_1()
+		throws Exception {
+		CommandExecuter fixture = CommandExecuter.getInstance();
+
+		fixture.addCommandPackage("");
+	}
+
+	@Test(expected=java.security.InvalidParameterException.class)
+	public void testAddCommandPackage_2()
+		throws Exception {
+		CommandExecuter fixture = CommandExecuter.getInstance();
+		
+		fixture.addCommandPackage(null);
+	}
+
+	@Test
+	public void testExec_1()
+		throws Exception {
+		CommandExecuter fixture = CommandExecuter.getInstance();
+		MockOutputListener mockListener = new MockOutputListener();
+		Console.getInstance().registerOutputListener(mockListener);
+		fixture.addCommandPackage("de.ugoe.cs.util.console.mock.commands");
+		String command = "mockCommand";
+		String expected = "mock command: run" + System.getProperty("line.separator");
+
+		fixture.exec(command);
+
+		assertEquals(expected, mockListener.getLastOutput());
+	}
+	
+	@Test
+	public void testExec_2()
+		throws Exception {
+		CommandExecuter fixture = CommandExecuter.getInstance();
+		MockOutputListener mockListener = new MockOutputListener();
+		Console.getInstance().registerOutputListener(mockListener);
+		fixture.addCommandPackage("de.ugoe.cs.util.console.mock.commands");
+		String command = "mockCommand param1";
+		String expected = "mock command: help" + System.getProperty("line.separator");
+
+		fixture.exec(command);
+
+		assertEquals(expected, mockListener.getLastOutput());
+	}
+	
+	@Test(expected = java.lang.RuntimeException.class)
+	public void testExec_3()
+		throws Exception {
+		CommandExecuter fixture = CommandExecuter.getInstance();
+		MockOutputListener mockListener = new MockOutputListener();
+		Console.getInstance().registerOutputListener(mockListener);
+		fixture.addCommandPackage("de.ugoe.cs.util.console.mock.commands");
+		String command = "mockCommand param1 param2";
+
+		fixture.exec(command);
+	}
+	
+	@Test
+	public void testExec_4()
+		throws Exception {
+		CommandExecuter fixture = CommandExecuter.getInstance();
+		MockOutputListener mockListener = new MockOutputListener();
+		Console.getInstance().registerOutputListener(mockListener);
+		fixture.addCommandPackage("de.ugoe.cs.util.console.mock.commands");
+		String command = "mockCommandddd";
+		String expected = "Unknown command" + System.getProperty("line.separator");
+		
+		fixture.exec(command);
+		
+		assertEquals(expected, mockListener.getLastOutput());
+	}
+
+	@Test
+	public void testGetInstance_1()
+		throws Exception {
+		CommandExecuter result = CommandExecuter.getInstance();
+
+		assertNotNull(result);
+	}
+	
+	@BeforeClass
+	public static void setupBeforeClass() {
+		Console.reset();
+	}
+
+	public static void main(String[] args) {
+		new org.junit.runner.JUnitCore().run(CommandExecuterTest.class);
+	}
+}
Index: /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/CommandParserTest.java
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/CommandParserTest.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/CommandParserTest.java	(revision 540)
@@ -0,0 +1,255 @@
+package de.ugoe.cs.util.console;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.junit.*;
+import static org.junit.Assert.*;
+
+/**
+ * The class <code>CommandParserTest</code> contains tests for the class
+ * <code>{@link CommandParser}</code>.
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CommandParserTest {
+
+	@Test
+	public void testCommandParser_1() throws Exception {
+
+		CommandParser result = new CommandParser();
+
+		// add additional test code here
+		assertNotNull(result);
+		assertEquals("", result.getCommandName());
+		assertTrue(result.getParameters().isEmpty());
+	}
+
+	@Test
+	public void testGetParameters_1() throws Exception {
+		CommandParser fixture = new CommandParser();
+
+		List<Object> result = fixture.getParameters();
+
+		// add additional test code here
+		assertNotNull(result);
+		assertEquals(0, result.size());
+	}
+
+	@Test
+	public void testParse_1() throws Exception {
+		CommandParser commandParser = new CommandParser();
+		String command = "test";
+		commandParser.parse(command);
+
+		assertEquals("test", commandParser.getCommandName());
+		assertTrue(commandParser.getParameters().isEmpty());
+	}
+
+	@Test
+	public void testParse_2() throws Exception {
+		CommandParser commandParser = new CommandParser();
+		String command = "test param1";
+		List<Object> expectedParameters = new ArrayList<Object>();
+		expectedParameters.add("param1");
+
+		commandParser.parse(command);
+
+		assertEquals("test", commandParser.getCommandName());
+		assertArrayEquals(expectedParameters.toArray(), commandParser
+				.getParameters().toArray());
+	}
+
+	@Test
+	public void testParse_3() throws Exception {
+		CommandParser commandParser = new CommandParser();
+		String command = "test param1 param2";
+		List<Object> expectedParameters = new ArrayList<Object>();
+		expectedParameters.add("param1");
+		expectedParameters.add("param2");
+
+		commandParser.parse(command);
+
+		assertEquals("test", commandParser.getCommandName());
+		assertArrayEquals(expectedParameters.toArray(), commandParser
+				.getParameters().toArray());
+	}
+
+	@Test
+	public void testParse_4() throws Exception {
+		CommandParser commandParser = new CommandParser();
+		String command = "test [array1]";
+		List<Object> expectedParameters = new ArrayList<Object>();
+		expectedParameters.add(new String[] { "array1" });
+
+		commandParser.parse(command);
+
+		assertEquals("test", commandParser.getCommandName());
+		assertArrayEquals(expectedParameters.toArray(), commandParser
+				.getParameters().toArray());
+	}
+
+	@Test
+	public void testParse_5() throws Exception {
+		CommandParser commandParser = new CommandParser();
+		String command = "test [array1 array2]";
+		List<Object> expectedParameters = new ArrayList<Object>();
+		expectedParameters.add(new String[] { "array1", "array2" });
+
+		commandParser.parse(command);
+
+		assertEquals("test", commandParser.getCommandName());
+		assertArrayEquals(expectedParameters.toArray(), commandParser
+				.getParameters().toArray());
+	}
+
+	@Test
+	public void testParse_6() throws Exception {
+		CommandParser commandParser = new CommandParser();
+		String command = "test [array1] param1";
+		List<Object> expectedParameters = new ArrayList<Object>();
+		expectedParameters.add(new String[] { "array1" });
+		expectedParameters.add("param1");
+
+		commandParser.parse(command);
+
+		assertEquals("test", commandParser.getCommandName());
+		assertArrayEquals(expectedParameters.toArray(), commandParser
+				.getParameters().toArray());
+	}
+
+	@Test
+	public void testParse_7() throws Exception {
+		CommandParser commandParser = new CommandParser();
+		String command = "test 'param 1'";
+		List<Object> expectedParameters = new ArrayList<Object>();
+		expectedParameters.add("param 1");
+
+		commandParser.parse(command);
+
+		assertEquals("test", commandParser.getCommandName());
+		assertArrayEquals(expectedParameters.toArray(), commandParser
+				.getParameters().toArray());
+	}
+
+	@Test
+	public void testParse_8() throws Exception {
+		CommandParser commandParser = new CommandParser();
+		String command = "test ['array 1']";
+		List<Object> expectedParameters = new ArrayList<Object>();
+		expectedParameters.add(new String[] { "array 1" });
+
+		commandParser.parse(command);
+
+		assertEquals("test", commandParser.getCommandName());
+		assertArrayEquals(expectedParameters.toArray(), commandParser
+				.getParameters().toArray());
+	}
+
+	@Test
+	public void testParse_9() throws Exception {
+		CommandParser commandParser = new CommandParser();
+		String command = "test ['array 1' array2]";
+		List<Object> expectedParameters = new ArrayList<Object>();
+		expectedParameters.add(new String[] { "array 1", "array2" });
+
+		commandParser.parse(command);
+
+		assertEquals("test", commandParser.getCommandName());
+		assertArrayEquals(expectedParameters.toArray(), commandParser
+				.getParameters().toArray());
+	}
+
+	@Test
+	public void testParse_10() throws Exception {
+		CommandParser commandParser = new CommandParser();
+		String command = "test [array1  array2]";
+		List<Object> expectedParameters = new ArrayList<Object>();
+		expectedParameters.add(new String[] { "array1", "array2" });
+
+		commandParser.parse(command);
+
+		assertEquals("test", commandParser.getCommandName());
+		assertArrayEquals(expectedParameters.toArray(), commandParser
+				.getParameters().toArray());
+	}
+
+	@Test
+	public void testParse_11() throws Exception {
+		CommandParser commandParser = new CommandParser();
+		String command = "test 'param 1";
+		List<Object> expectedParameters = new ArrayList<Object>();
+		expectedParameters.add("param 1");
+
+		commandParser.parse(command);
+
+		assertEquals("test", commandParser.getCommandName());
+		assertArrayEquals(expectedParameters.toArray(), commandParser
+				.getParameters().toArray());
+	}
+
+	@Test
+	public void testParse_12() throws Exception {
+		CommandParser commandParser = new CommandParser();
+		String command = "test 'param1 [array1]";
+		List<Object> expectedParameters = new ArrayList<Object>();
+		expectedParameters.add("param1 [array1]");
+
+		commandParser.parse(command);
+
+		assertEquals("test", commandParser.getCommandName());
+		assertArrayEquals(expectedParameters.toArray(), commandParser
+				.getParameters().toArray());
+	}
+
+	@Test
+	public void testParse_13() throws Exception {
+		CommandParser commandParser = new CommandParser();
+		String command = "test param1' [array1]";
+		List<Object> expectedParameters = new ArrayList<Object>();
+		expectedParameters.add("param1'");
+		expectedParameters.add(new String[] { "array1" });
+
+		commandParser.parse(command);
+
+		assertEquals("test", commandParser.getCommandName());
+		assertArrayEquals(expectedParameters.toArray(), commandParser
+				.getParameters().toArray());
+	}
+
+	@Test
+	public void testParse_14() throws Exception {
+		CommandParser commandParser = new CommandParser();
+		String command = "";
+		commandParser.parse(command);
+		assertEquals("", commandParser.getCommandName());
+		assertTrue(commandParser.getParameters().isEmpty());
+	}
+
+	@Test
+	public void testParse_15() throws Exception {
+		CommandParser commandParser = new CommandParser();
+		String command = null;
+		commandParser.parse(command);
+		assertEquals("", commandParser.getCommandName());
+		assertTrue(commandParser.getParameters().isEmpty());
+	}
+
+	@Test
+	public void testParse_16() throws Exception {
+		CommandParser commandParser = new CommandParser();
+		String command = "test param1  param2";
+		List<Object> expectedParameters = new ArrayList<Object>();
+		expectedParameters.add("param1");
+		expectedParameters.add("param2");
+
+		commandParser.parse(command);
+		assertEquals("test", commandParser.getCommandName());
+		assertArrayEquals(expectedParameters.toArray(), commandParser
+				.getParameters().toArray());
+	}
+
+	public static void main(String[] args) {
+		new org.junit.runner.JUnitCore().run(CommandParserTest.class);
+	}
+}
Index: /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/ConsoleTest.java
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/ConsoleTest.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/ConsoleTest.java	(revision 540)
@@ -0,0 +1,364 @@
+package de.ugoe.cs.util.console;
+
+import org.junit.*;
+import de.ugoe.cs.util.console.mock.MockCommandListener;
+import de.ugoe.cs.util.console.mock.MockErrorListener;
+import de.ugoe.cs.util.console.mock.MockExceptionListener;
+import de.ugoe.cs.util.console.mock.MockObserver;
+import de.ugoe.cs.util.console.mock.MockOutputListener;
+import de.ugoe.cs.util.console.mock.MockTraceListener;
+import static org.junit.Assert.*;
+
+/**
+ * The class <code>ConsoleTest</code> contains tests for the class <code>{@link Console}</code>.
+ *
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class ConsoleTest {
+	
+	private static final String ENDLINE = System.getProperty("line.separator");
+	
+	@Test
+	public void testCommandNotification_1()
+		throws Exception {
+		String command = "test";
+		
+		MockCommandListener commandListener1 = new MockCommandListener();
+		MockCommandListener commandListener2 = new MockCommandListener();
+		
+		Console.getInstance().registerCommandListener(commandListener1);
+		Console.getInstance().registerCommandListener(commandListener2);
+		Console.commandNotification(command);
+		
+		assertEquals(command, commandListener1.getLastCommand());
+		assertEquals(command, commandListener2.getLastCommand());
+	}
+
+	@SuppressWarnings("deprecation")
+	@Test
+	public void testDeleteObserver_1()
+		throws Exception {
+		Console fixture = Console.getInstance();
+		
+		MockObserver mockObserver1 = new MockObserver();
+		MockObserver mockObserver2 = new MockObserver();
+		fixture.registerObserver(mockObserver1);
+		fixture.registerObserver(mockObserver2);
+
+		fixture.deleteObserver(mockObserver1);
+		
+		assertFalse(fixture.hasCommandListener(mockObserver1));
+		assertFalse(fixture.hasErrorListener(mockObserver1));
+		assertFalse(fixture.hasExceptionListener(mockObserver1));
+		assertFalse(fixture.hasOutputListener(mockObserver1));
+		assertFalse(fixture.hasTraceListener(mockObserver1));
+		
+		assertTrue(fixture.hasCommandListener(mockObserver2));
+		assertTrue(fixture.hasErrorListener(mockObserver2));
+		assertTrue(fixture.hasExceptionListener(mockObserver2));
+		assertTrue(fixture.hasOutputListener(mockObserver2));
+		assertTrue(fixture.hasTraceListener(mockObserver2));
+
+		// add additional test code here
+	}
+
+	@Test
+	public void testGetInstance()
+		throws Exception {
+
+		Console result = Console.getInstance();
+		assertNotNull(result);
+	}
+
+	@Test
+	public void testLogException()
+		throws Exception {
+		Exception e = new Exception();
+		MockExceptionListener mockExceptionListener1 = new MockExceptionListener();
+		MockExceptionListener mockExceptionListener2 = new MockExceptionListener();
+		
+		Console.getInstance().registerExceptionListener(mockExceptionListener1);
+		Console.getInstance().registerExceptionListener(mockExceptionListener2);
+		
+		Console.logException(e);
+		
+		assertEquals(e, mockExceptionListener1.getLastException());
+		assertEquals(e, mockExceptionListener2.getLastException());
+	}
+
+	@Test
+	public void testPrint_1()
+		throws Exception {
+		String msg = "test";
+		
+		MockOutputListener mockOutputListener1 = new MockOutputListener();
+		MockOutputListener mockOutputListener2 = new MockOutputListener();
+		
+		Console.getInstance().registerOutputListener(mockOutputListener1);
+		Console.getInstance().registerOutputListener(mockOutputListener2);
+
+		Console.print(msg);
+		
+		assertEquals(msg, mockOutputListener1.getLastOutput());
+		assertEquals(msg, mockOutputListener2.getLastOutput());
+	}
+
+	@Test
+	public void testPrinterr_1()
+		throws Exception {
+		String errMsg = "test";
+		
+		MockErrorListener mockErrorListener1 = new MockErrorListener();
+		MockErrorListener mockErrorListener2 = new MockErrorListener();
+		
+		Console.getInstance().registerErrorListener(mockErrorListener1);
+		Console.getInstance().registerErrorListener(mockErrorListener2);		
+
+		Console.printerr(errMsg);
+		
+		assertEquals(errMsg, mockErrorListener1.getLastError());
+		assertEquals(errMsg, mockErrorListener2.getLastError());
+	}
+
+	@Test
+	public void testPrinterrln_1()
+		throws Exception {
+		String errMsg = "test";
+		
+		MockErrorListener mockErrorListener1 = new MockErrorListener();
+		MockErrorListener mockErrorListener2 = new MockErrorListener();
+		
+		Console.getInstance().registerErrorListener(mockErrorListener1);
+		Console.getInstance().registerErrorListener(mockErrorListener2);		
+
+		Console.printerrln(errMsg);
+		
+		assertEquals(errMsg+ENDLINE, mockErrorListener1.getLastError());
+		assertEquals(errMsg+ENDLINE, mockErrorListener2.getLastError());
+	}
+
+
+	@Test
+	public void testPrintln_1()
+		throws Exception {
+		String msg = "test";
+		
+		MockOutputListener mockOutputListener1 = new MockOutputListener();
+		MockOutputListener mockOutputListener2 = new MockOutputListener();
+		
+		Console.getInstance().registerOutputListener(mockOutputListener1);
+		Console.getInstance().registerOutputListener(mockOutputListener2);
+
+		Console.println(msg);
+		
+		assertEquals(msg+ENDLINE, mockOutputListener1.getLastOutput());
+		assertEquals(msg+ENDLINE, mockOutputListener2.getLastOutput());
+	}
+
+
+	@Test
+	public void testRegisterCommandListener_1()
+		throws Exception {
+		Console fixture = Console.getInstance();
+		MockCommandListener mockCommandListener = new MockCommandListener();
+
+		fixture.registerCommandListener(mockCommandListener);
+		
+		assertTrue(fixture.hasCommandListener(mockCommandListener));
+	}
+
+	@Test
+	public void testRegisterErrorListener_1()
+		throws Exception {
+		Console fixture = Console.getInstance();
+		
+		MockErrorListener mockErrorListener = new MockErrorListener();
+
+		fixture.registerErrorListener(mockErrorListener);
+		
+		assertTrue(fixture.hasErrorListener(mockErrorListener));
+	}
+
+	@Test
+	public void testRegisterExceptionListener_1()
+		throws Exception {
+		Console fixture = Console.getInstance();
+		
+		MockExceptionListener mockExceptionListener = new MockExceptionListener();
+
+		fixture.registerExceptionListener(mockExceptionListener);
+
+		assertTrue(fixture.hasExceptionListener(mockExceptionListener));
+	}
+
+	@SuppressWarnings("deprecation")
+	@Test
+	public void testRegisterObserver_1()
+		throws Exception {
+		Console fixture = Console.getInstance();
+		
+		MockObserver mockObserver = new MockObserver();
+
+		fixture.registerObserver(mockObserver);
+		
+		assertTrue(fixture.hasCommandListener(mockObserver));
+		assertTrue(fixture.hasErrorListener(mockObserver));
+		assertTrue(fixture.hasExceptionListener(mockObserver));
+		assertTrue(fixture.hasOutputListener(mockObserver));
+		assertTrue(fixture.hasTraceListener(mockObserver));
+	}
+
+	@Test
+	public void testRegisterOutputListener_1()
+		throws Exception {
+		Console fixture = Console.getInstance();
+		
+		MockOutputListener mockOutputListener = new MockOutputListener();
+
+		fixture.registerOutputListener(mockOutputListener);
+		
+		assertTrue(fixture.hasOutputListener(mockOutputListener));
+	}
+
+	@Test
+	public void testRegisterTraceListener_1()
+		throws Exception {
+		Console fixture = Console.getInstance();
+		
+		MockTraceListener mockTraceListener = new MockTraceListener();
+
+		fixture.registerTraceListener(mockTraceListener);
+		
+		assertTrue(fixture.hasTraceListener(mockTraceListener));
+	}
+
+	@Test
+	public void testRemoveCommandListener_1()
+		throws Exception {
+		Console fixture = Console.getInstance();
+		
+		MockCommandListener mockCommandListener1 = new MockCommandListener();
+		MockCommandListener mockCommandListener2 = new MockCommandListener();
+		fixture.registerCommandListener(mockCommandListener1);
+		fixture.registerCommandListener(mockCommandListener2);
+		
+		fixture.removeCommandListener(mockCommandListener1);
+		
+		assertFalse(fixture.hasCommandListener(mockCommandListener1));
+		assertTrue(fixture.hasCommandListener(mockCommandListener2));
+	}
+
+	@Test
+	public void testRemoveErrorListener_1()
+		throws Exception {
+		Console fixture = Console.getInstance();
+		
+		MockErrorListener mockErrorListener1 = new MockErrorListener();
+		MockErrorListener mockErrorListener2 = new MockErrorListener();
+		fixture.registerErrorListener(mockErrorListener1);
+		fixture.registerErrorListener(mockErrorListener2);
+
+		fixture.removeErrorListener(mockErrorListener1);
+		
+		assertFalse(fixture.hasErrorListener(mockErrorListener1));
+		assertTrue(fixture.hasErrorListener(mockErrorListener2));
+	}
+
+	@Test
+	public void testRemoveExceptionListener_1()
+		throws Exception {
+		Console fixture = Console.getInstance();
+		
+		MockExceptionListener mockExceptionListener1 = new MockExceptionListener();
+		MockExceptionListener mockExceptionListener2 = new MockExceptionListener();
+		
+		fixture.registerExceptionListener(mockExceptionListener1);
+		fixture.registerExceptionListener(mockExceptionListener2);
+		
+		fixture.removeExceptionListener(mockExceptionListener1);
+		
+		assertFalse(fixture.hasExceptionListener(mockExceptionListener1));
+		assertTrue(fixture.hasExceptionListener(mockExceptionListener2));
+	}
+
+	@Test
+	public void testRemoveOutputListener_1()
+		throws Exception {
+		Console fixture = Console.getInstance();
+		
+		MockOutputListener mockOutputListener1 = new MockOutputListener();
+		MockOutputListener mockOutputListener2 = new MockOutputListener();
+		
+		fixture.registerOutputListener(mockOutputListener1);
+		fixture.registerOutputListener(mockOutputListener2);
+		
+		fixture.removeOutputListener(mockOutputListener1);
+		
+		assertFalse(fixture.hasOutputListener(mockOutputListener1));
+		assertTrue(fixture.hasOutputListener(mockOutputListener2));
+	}
+
+	@Test
+	public void testRemoveTraceListener_1()
+		throws Exception {
+		Console fixture = Console.getInstance();
+		
+		MockTraceListener mockTraceListener1 = new MockTraceListener();
+		MockTraceListener mockTraceListener2 = new MockTraceListener();
+		
+		fixture.registerTraceListener(mockTraceListener1);
+		fixture.registerTraceListener(mockTraceListener2);
+		
+		fixture.removeTraceListener(mockTraceListener1);
+		
+		assertFalse(fixture.hasTraceListener(mockTraceListener1));
+		assertTrue(fixture.hasTraceListener(mockTraceListener2));
+	}
+
+	@Test
+	public void testTrace_1()
+		throws Exception {
+		String traceMsg = "test";
+		
+		MockTraceListener mockTraceListener1 = new MockTraceListener();
+		MockTraceListener mockTraceListener2 = new MockTraceListener();
+		
+		Console.getInstance().registerTraceListener(mockTraceListener1);
+		Console.getInstance().registerTraceListener(mockTraceListener2);
+
+		Console.trace(traceMsg);
+
+		assertEquals(traceMsg, mockTraceListener1.getLastTrace());
+		assertEquals(traceMsg, mockTraceListener2.getLastTrace());
+	}
+	
+	@Test
+	public void testTraceln_1()
+		throws Exception {
+		String traceMsg = "test";
+
+		MockTraceListener mockTraceListener1 = new MockTraceListener();
+		MockTraceListener mockTraceListener2 = new MockTraceListener();
+		
+		Console.getInstance().registerTraceListener(mockTraceListener1);
+		Console.getInstance().registerTraceListener(mockTraceListener2);
+
+		Console.traceln(traceMsg);
+
+		assertEquals(traceMsg+ENDLINE, mockTraceListener1.getLastTrace());
+		assertEquals(traceMsg+ENDLINE, mockTraceListener2.getLastTrace());
+
+		// add additional test code here
+	}
+
+	@Before
+	public void setUp()
+		throws Exception {
+		Console.reset();
+	}
+
+	public static void main(String[] args) {
+		new org.junit.runner.JUnitCore().run(ConsoleTest.class);
+	}
+}
Index: /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/FileOutputListenerTest.java
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/FileOutputListenerTest.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/FileOutputListenerTest.java	(revision 540)
@@ -0,0 +1,98 @@
+package de.ugoe.cs.util.console;
+
+import java.io.File;
+
+import junitx.framework.FileAssert;
+
+import org.junit.*;
+import static org.junit.Assert.*;
+
+/**
+ * The class <code>FileOutputListenerTest</code> contains tests for the class <code>{@link FileOutputListener}</code>.
+ *
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class FileOutputListenerTest {
+	
+	String expectedOutputFilename = "testdata/de.ugoe.cs.util.FileOutputListenerTest/expected.log";
+	String testOutputPath = "testoutput/";
+	String testFilename = testOutputPath + "listener.log";
+	
+	FileOutputListener listener;
+	
+	@Test
+	public void testFileOutputListener_1()
+		throws Exception {
+		String filename = "filename";
+
+		FileOutputListener result = new FileOutputListener(filename);
+		
+		assertNotNull(result);
+		assertEquals(filename, result.getFilename());
+	}
+
+	@Test
+	public void testOutputMsg_1()
+		throws Exception {
+		String message = "test";
+		
+		listener.start();
+		listener.outputMsg(message);
+		listener.stop();
+
+		FileAssert.assertEquals(new File(expectedOutputFilename), new File(testFilename));
+	}
+
+	@Test
+	public void testStart_1()
+		throws Exception {
+		FileOutputListener fixture = new FileOutputListener(testFilename);
+
+		fixture.start();
+		
+		File file = new File(testFilename);
+		assertTrue(file.exists());
+	}
+	
+	@Test
+	public void testStart_2()
+		throws Exception {
+		FileOutputListener fixture = new FileOutputListener("");
+
+		fixture.start();
+		
+		assertNull(fixture.writer);
+	}
+
+	@Test
+	public void testStop_1()
+		throws Exception {
+		listener.stop();
+		assertNull(listener.writer);
+	}
+
+	@Before
+	public void setUp()
+		throws Exception {
+		// add additional set up code here
+		Console.reset();
+		listener = new FileOutputListener(testFilename);
+		File file = new File(testFilename);
+		if( file.exists() ) {
+			file.delete();
+		}
+	}
+
+	@After
+	public void tearDown()
+		throws Exception {
+		if( listener.writer!=null ) {
+			listener.writer.close();
+		}
+	}
+
+	public static void main(String[] args) {
+		new org.junit.runner.JUnitCore().run(FileOutputListenerTest.class);
+	}
+}
Index: /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/TestAll.java
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/TestAll.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/TestAll.java	(revision 540)
@@ -0,0 +1,29 @@
+package de.ugoe.cs.util.console;
+
+import org.junit.runner.JUnitCore;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+/**
+ * The class <code>TestAll</code> builds a suite that can be used to run all
+ * of the tests within its package as well as within any subpackages of its
+ * package.
+ *
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+	CommandParserTest.class,
+	FileOutputListenerTest.class,
+	TextConsoleTest.class,
+	ConsoleTest.class,
+	CommandExecuterTest.class,
+	de.ugoe.cs.util.console.defaultcommands.TestAll.class
+})
+public class TestAll {
+
+	public static void main(String[] args) {
+		JUnitCore.runClasses(new Class[] { TestAll.class });
+	}
+}
Index: /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/TextConsoleTest.java
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/TextConsoleTest.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/TextConsoleTest.java	(revision 540)
@@ -0,0 +1,103 @@
+package de.ugoe.cs.util.console;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+
+import org.junit.*;
+import static org.junit.Assert.*;
+
+/**
+ * The class <code>TextConsoleTest</code> contains tests for the class
+ * <code>{@link TextConsole}</code>.
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class TextConsoleTest {
+
+	private final static String ENDLINE = System.getProperty("line.separator");
+
+	private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();
+	private final ByteArrayOutputStream errContent = new ByteArrayOutputStream();
+
+	@Test
+	public void testTextConsole_1() throws Exception {
+
+		Console.reset();
+		TextConsole result = new TextConsole();
+
+		assertNotNull(result);
+		assertTrue(Console.getInstance().hasErrorListener(result));
+		assertTrue(Console.getInstance().hasExceptionListener(result));
+		assertTrue(Console.getInstance().hasOutputListener(result));
+		assertTrue(Console.getInstance().hasTraceListener(result));
+	}
+
+	@Test
+	public void testErrorMsg_1() throws Exception {
+		TextConsole fixture = new TextConsole();
+		String errMessage = "test";
+
+		fixture.errorMsg(errMessage);
+
+		assertEquals(errMessage, errContent.toString());
+	}
+
+	@Test
+	public void testLogException_1() throws Exception {
+		TextConsole fixture = new TextConsole();
+		Exception e = new Exception("test");
+		;
+
+		fixture.logException(e);
+		assertEquals(e.getMessage() + ENDLINE, errContent.toString());
+	}
+
+	@Test
+	public void testOutputMsg_1() throws Exception {
+		TextConsole fixture = new TextConsole();
+		String newMessage = "test";
+
+		fixture.outputMsg(newMessage);
+
+		assertEquals(newMessage, outContent.toString());
+	}
+
+	@Test
+	public void testTraceMsg_1() throws Exception {
+		TextConsole fixture = new TextConsole();
+		fixture.setDebug(true);
+		String traceMessage = "test";
+
+		fixture.traceMsg(traceMessage);
+
+		assertEquals(traceMessage, outContent.toString());
+	}
+
+	@Test
+	public void testTraceMsg_2() throws Exception {
+		TextConsole fixture = new TextConsole();
+		fixture.setDebug(false);
+		String traceMessage = "test";
+
+		fixture.traceMsg(traceMessage);
+
+		assertEquals("", outContent.toString());
+	}
+
+	@Before
+	public void setUp() throws Exception {
+		System.setOut(new PrintStream(outContent));
+		System.setErr(new PrintStream(errContent));
+	}
+
+	@After
+	public void tearDown() throws Exception {
+		System.setOut(null);
+		System.setErr(null);
+	}
+
+	public static void main(String[] args) {
+		new org.junit.runner.JUnitCore().run(TextConsoleTest.class);
+	}
+}
Index: /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/defaultcommands/CMDexecTest.java
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/defaultcommands/CMDexecTest.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/defaultcommands/CMDexecTest.java	(revision 540)
@@ -0,0 +1,115 @@
+package de.ugoe.cs.util.console.defaultcommands;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.junit.*;
+
+import de.ugoe.cs.util.console.Console;
+import de.ugoe.cs.util.console.mock.MockCommandListener;
+import de.ugoe.cs.util.console.mock.MockOutputListener;
+import de.ugoe.cs.util.console.mock.MockTraceListener;
+import static org.junit.Assert.*;
+
+/**
+ * The class <code>CMDexecTest</code> contains tests for the class
+ * <code>{@link CMDexec}</code>.
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CMDexecTest {
+
+	final static String ENDLINE = System.getProperty("line.separator");
+
+	@Test
+	public void testHelp_1() throws Exception {
+		CMDexec fixture = new CMDexec();
+		MockOutputListener mockListener = new MockOutputListener();
+		Console.getInstance().registerOutputListener(mockListener);
+		String expected = "Usage: exec <filename>" + ENDLINE;
+
+		fixture.help();
+
+		assertEquals(expected, mockListener.getLastOutput());
+	}
+
+	@Test
+	public void testRun_1() throws Exception {
+		CMDexec fixture = new CMDexec();
+		MockCommandListener mockCommandListener = new MockCommandListener();
+		MockTraceListener mockTraceListener = new MockTraceListener();
+		Console.getInstance().registerCommandListener(mockCommandListener);
+		Console.getInstance().registerTraceListener(mockTraceListener);
+		List<Object> parameters = new ArrayList<Object>();
+		parameters
+				.add("testdata/de.ugoe.cs.util.console.defaultcommands.CMDexecTest/script1");
+		String expected = "mockCommand";
+
+		fixture.run(parameters);
+
+		assertEquals(expected, mockCommandListener.getLastCommand());
+		assertEquals(expected + ENDLINE, mockTraceListener.getLastTrace());
+	}
+
+	@Test
+	public void testRun_2() throws Exception {
+		CMDexec fixture = new CMDexec();
+		MockCommandListener mockCommandListener = new MockCommandListener();
+		MockTraceListener mockTraceListener = new MockTraceListener();
+		Console.getInstance().registerCommandListener(mockCommandListener);
+		Console.getInstance().registerTraceListener(mockTraceListener);
+		List<Object> parameters = new ArrayList<Object>();
+		parameters
+				.add("testdata/de.ugoe.cs.util.console.defaultcommands.CMDexecTest/script2");
+		String expected = "mockCommand param1";
+
+		fixture.run(parameters);
+
+		assertEquals(expected, mockCommandListener.getLastCommand());
+		assertEquals(expected + ENDLINE, mockTraceListener.getLastTrace());
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testRun_3() throws Exception {
+		CMDexec fixture = new CMDexec();
+		MockCommandListener mockCommandListener = new MockCommandListener();
+		MockTraceListener mockTraceListener = new MockTraceListener();
+		Console.getInstance().registerCommandListener(mockCommandListener);
+		Console.getInstance().registerTraceListener(mockTraceListener);
+		List<Object> parameters = new ArrayList<Object>();
+
+		fixture.run(parameters);
+	}
+
+	@Test
+	public void testRun_4() throws Exception {
+		CMDexec fixture = new CMDexec();
+		MockCommandListener mockCommandListener = new MockCommandListener();
+		MockTraceListener mockTraceListener = new MockTraceListener();
+		Console.getInstance().registerCommandListener(mockCommandListener);
+		Console.getInstance().registerTraceListener(mockTraceListener);
+		List<Object> parameters = new ArrayList<Object>();
+		parameters
+				.add("testdata/de.ugoe.cs.util.console.defaultcommands.CMDexecTest/script2");
+		parameters.add(Integer.parseInt("1"));
+		String expected = "mockCommand param1";
+
+		fixture.run(parameters);
+
+		assertEquals(expected, mockCommandListener.getLastCommand());
+		assertEquals(expected + ENDLINE, mockTraceListener.getLastTrace());
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testRun_5() throws Exception {
+		CMDexec fixture = new CMDexec();
+		List<Object> parameters = new ArrayList<Object>();
+		parameters.add(Integer.parseInt("1"));
+
+		fixture.run(parameters);
+	}
+
+	public static void main(String[] args) {
+		new org.junit.runner.JUnitCore().run(CMDexecTest.class);
+	}
+}
Index: /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/defaultcommands/CMDexitTest.java
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/defaultcommands/CMDexitTest.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/defaultcommands/CMDexitTest.java	(revision 540)
@@ -0,0 +1,87 @@
+package de.ugoe.cs.util.console.defaultcommands;
+
+import java.security.Permission;
+import java.util.ArrayList;
+import java.util.List;
+import org.junit.*;
+
+import de.ugoe.cs.util.console.Console;
+import de.ugoe.cs.util.console.mock.MockOutputListener;
+import static org.junit.Assert.*;
+
+/**
+ * The class <code>CMDexitTest</code> contains tests for the class
+ * <code>{@link CMDexit}</code>.
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CMDexitTest {
+
+	final static String ENDLINE = System.getProperty("line.separator");
+
+	private static class ExitException extends SecurityException {
+		private static final long serialVersionUID = 1L;
+	}
+
+	private static class NoExitSecurityManager extends SecurityManager {
+		@Override
+		public void checkPermission(Permission perm) {
+			// allow anything.
+		}
+
+		@Override
+		public void checkPermission(Permission perm, Object context) {
+			// allow anything.
+		}
+
+		@Override
+		public void checkExit(int status) {
+			super.checkExit(status);
+			throw new ExitException();
+		}
+	}
+
+	@Test
+	public void testHelp_1() throws Exception {
+		CMDexit fixture = new CMDexit();
+		MockOutputListener mockListener = new MockOutputListener();
+		Console.getInstance().registerOutputListener(mockListener);
+		String expected = "Usage: exit" + ENDLINE;
+
+		fixture.help();
+
+		assertEquals(expected, mockListener.getLastOutput());
+	}
+
+	@Test(expected = ExitException.class)
+	public void testRun_1() throws Exception {
+		CMDexit fixture = new CMDexit();
+		List<Object> parameters = new ArrayList<Object>();
+
+		fixture.run(parameters);
+	}
+
+	@Test(expected = ExitException.class)
+	public void testRun_2() throws Exception {
+		CMDexit fixture = new CMDexit();
+		List<Object> parameters = new ArrayList<Object>();
+		parameters.add("test");
+
+		fixture.run(parameters);
+	}
+
+	@Before
+	public void setUp() throws Exception {
+		System.setSecurityManager(new NoExitSecurityManager());
+	}
+
+	@After
+	public void tearDown() throws Exception {
+		System.setSecurityManager(null);
+	}
+
+	public static void main(String[] args) {
+		new org.junit.runner.JUnitCore().run(CMDexitTest.class);
+	}
+}
Index: /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/defaultcommands/TestAll.java
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/defaultcommands/TestAll.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/defaultcommands/TestAll.java	(revision 540)
@@ -0,0 +1,25 @@
+package de.ugoe.cs.util.console.defaultcommands;
+
+import org.junit.runner.JUnitCore;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+/**
+ * The class <code>TestAll</code> builds a suite that can be used to run all of
+ * the tests within its package as well as within any subpackages of its
+ * package.
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+	CMDexecTest.class,
+	CMDexitTest.class
+})
+public class TestAll {
+
+	public static void main(String[] args) {
+		JUnitCore.runClasses(new Class[] { TestAll.class });
+	}
+}
Index: /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/mock/MockCommandListener.java
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/mock/MockCommandListener.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/mock/MockCommandListener.java	(revision 540)
@@ -0,0 +1,16 @@
+package de.ugoe.cs.util.console.mock;
+
+import de.ugoe.cs.util.console.listener.ICommandListener;
+
+public class MockCommandListener implements ICommandListener {
+	private String lastCommand = null;
+
+	public String getLastCommand() {
+		return lastCommand;
+	}
+
+	@Override
+	public void commandNotification(String command) {
+		lastCommand = command;
+	}
+}
Index: /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/mock/MockErrorListener.java
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/mock/MockErrorListener.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/mock/MockErrorListener.java	(revision 540)
@@ -0,0 +1,14 @@
+package de.ugoe.cs.util.console.mock;
+
+import de.ugoe.cs.util.console.listener.IErrorListener;
+
+public class MockErrorListener implements IErrorListener {
+	private String lastError = null;
+	public String getLastError() {
+		return lastError;
+	}
+	@Override
+	public void errorMsg(String errMessage) {
+		lastError = errMessage;
+	}
+}
Index: /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/mock/MockExceptionListener.java
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/mock/MockExceptionListener.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/mock/MockExceptionListener.java	(revision 540)
@@ -0,0 +1,16 @@
+package de.ugoe.cs.util.console.mock;
+
+import de.ugoe.cs.util.console.listener.IExceptionListener;
+
+public class MockExceptionListener implements IExceptionListener {
+	
+	private Exception lastException = null;
+	public Exception getLastException() {
+		return lastException;
+	}
+	
+	@Override
+	public void logException(Exception e) {
+		lastException = e;
+	}
+}
Index: /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/mock/MockObserver.java
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/mock/MockObserver.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/mock/MockObserver.java	(revision 540)
@@ -0,0 +1,23 @@
+package de.ugoe.cs.util.console.mock;
+
+import de.ugoe.cs.util.console.ConsoleObserver;
+
+@SuppressWarnings("deprecation") 
+public class MockObserver implements ConsoleObserver {
+	
+	@Override
+	public void commandNotification(String command) {
+	}
+	@Override
+	public void errorMsg(String errMessage) {
+	}
+	@Override
+	public void logException(Exception e) {
+	}
+	@Override
+	public void outputMsg(String newMessage) {	
+	}
+	@Override
+	public void traceMsg(String traceMessage) {
+	}
+}
Index: /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/mock/MockOutputListener.java
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/mock/MockOutputListener.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/mock/MockOutputListener.java	(revision 540)
@@ -0,0 +1,22 @@
+package de.ugoe.cs.util.console.mock;
+
+import de.ugoe.cs.util.console.listener.IOutputListener;
+
+public class MockOutputListener implements IOutputListener {
+	private String secondLastOutput = null;
+	private String lastOutput = null;
+	public String getLastOutput() {
+		return lastOutput;
+	}
+	public String getSecondLastOutput() {
+		return secondLastOutput;
+	}
+	@Override
+	public void outputMsg(String newMessage) {
+		if( lastOutput!=null ) {
+			secondLastOutput=lastOutput;
+		}
+		lastOutput = newMessage;
+		
+	}
+}
Index: /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/mock/MockTraceListener.java
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/mock/MockTraceListener.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/mock/MockTraceListener.java	(revision 540)
@@ -0,0 +1,14 @@
+package de.ugoe.cs.util.console.mock;
+
+import de.ugoe.cs.util.console.listener.ITraceListener;
+
+public class MockTraceListener implements ITraceListener {
+	private String lastTrace = null;
+	public String getLastTrace() {
+		return lastTrace;
+	}
+	@Override
+	public void traceMsg(String traceMessage) {
+		lastTrace = traceMessage;
+	}
+}
Index: /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/mock/commands/CMDmockCommand.java
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/mock/commands/CMDmockCommand.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils-test/src/test/java/de/ugoe/cs/util/console/mock/commands/CMDmockCommand.java	(revision 540)
@@ -0,0 +1,29 @@
+package de.ugoe.cs.util.console.mock.commands;
+
+import java.security.InvalidParameterException;
+import java.util.List;
+
+import de.ugoe.cs.util.console.Command;
+import de.ugoe.cs.util.console.Console;
+
+public class CMDmockCommand implements Command {
+
+	@Override
+	public void run(List<Object> parameters) {
+		switch (parameters.size()) {
+		case 0:
+			Console.println("mock command: run");
+			break;
+		case 1:
+			throw new InvalidParameterException();
+		default:
+			throw new RuntimeException();
+		}
+	}
+
+	@Override
+	public void help() {
+		Console.println("mock command: help");
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/java-utils-test/testdata/de.ugoe.cs.util.FileOutputListenerTest/expected.log
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils-test/testdata/de.ugoe.cs.util.FileOutputListenerTest/expected.log	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils-test/testdata/de.ugoe.cs.util.FileOutputListenerTest/expected.log	(revision 540)
@@ -0,0 +1,1 @@
+test
Index: /tags/quest-pre-eventrefactoring/java-utils-test/testdata/de.ugoe.cs.util.FileToolsTest/testdata-cr.txt
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils-test/testdata/de.ugoe.cs.util.FileToolsTest/testdata-cr.txt	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils-test/testdata/de.ugoe.cs.util.FileToolsTest/testdata-cr.txt	(revision 540)
@@ -0,0 +1,5 @@
+line1
+line2
+line3
+
+line5
Index: /tags/quest-pre-eventrefactoring/java-utils-test/testdata/de.ugoe.cs.util.FileToolsTest/testdata-nocr.txt
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils-test/testdata/de.ugoe.cs.util.FileToolsTest/testdata-nocr.txt	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils-test/testdata/de.ugoe.cs.util.FileToolsTest/testdata-nocr.txt	(revision 540)
@@ -0,0 +1,5 @@
+line1
+line2
+line3
+
+line5
Index: /tags/quest-pre-eventrefactoring/java-utils-test/testdata/de.ugoe.cs.util.console.defaultcommands.CMDexecTest/script1
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils-test/testdata/de.ugoe.cs.util.console.defaultcommands.CMDexecTest/script1	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils-test/testdata/de.ugoe.cs.util.console.defaultcommands.CMDexecTest/script1	(revision 540)
@@ -0,0 +1,1 @@
+mockCommand
Index: /tags/quest-pre-eventrefactoring/java-utils-test/testdata/de.ugoe.cs.util.console.defaultcommands.CMDexecTest/script2
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils-test/testdata/de.ugoe.cs.util.console.defaultcommands.CMDexecTest/script2	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils-test/testdata/de.ugoe.cs.util.console.defaultcommands.CMDexecTest/script2	(revision 540)
@@ -0,0 +1,2 @@
+mockCommand
+mockCommand param1
Index: /tags/quest-pre-eventrefactoring/java-utils/.classpath
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils/.classpath	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils/.classpath	(revision 540)
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/classes" path="src/main/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
Index: /tags/quest-pre-eventrefactoring/java-utils/.project
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils/.project	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils/.project	(revision 540)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>java-utils</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
Index: /tags/quest-pre-eventrefactoring/java-utils/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils/.settings/org.eclipse.jdt.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils/.settings/org.eclipse.jdt.core.prefs	(revision 540)
@@ -0,0 +1,12 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.6
Index: /tags/quest-pre-eventrefactoring/java-utils/.settings/org.eclipse.m2e.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils/.settings/org.eclipse.m2e.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils/.settings/org.eclipse.m2e.core.prefs	(revision 540)
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
Index: /tags/quest-pre-eventrefactoring/java-utils/pom.xml
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils/pom.xml	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils/pom.xml	(revision 540)
@@ -0,0 +1,23 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>de.ugoe.cs</groupId>
+	<artifactId>java-utils</artifactId>
+	<version>0.0.1-SNAPSHOT</version>
+	<name>java-utils</name>
+	<scm>
+		<url>https://quest.informatik.uni-goettingen.de/svn/quest/trunk/java-utils</url>
+	</scm>
+	<build>
+		<plugins>
+			<plugin>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>2.3.2</version>
+				<configuration>
+					<source>1.6</source>
+					<target>1.6</target>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+</project>
Index: /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/ArrayTools.java
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/ArrayTools.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/ArrayTools.java	(revision 540)
@@ -0,0 +1,116 @@
+package de.ugoe.cs.util;
+
+/**
+ * <p>
+ * Helper class that provides methods to simplify working with arrays.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+final public class ArrayTools {
+
+	/**
+	 * <p>
+	 * Private constructor to prevent initializing of the class.
+	 * </p>
+	 */
+	private ArrayTools() {
+
+	}
+
+	/**
+	 * <p>
+	 * Finds the first occurrence of an object inside an array.
+	 * </p>
+	 * <p>
+	 * In case {@code other==null}, the first occurrence of a {@code null} value
+	 * in the array is returned.
+	 * </p>
+	 * 
+	 * @param array
+	 *            the array
+	 * @param other
+	 *            the object
+	 * @return index of the object if found, -1 otherwise
+	 */
+	public static int findIndex(Object[] array, Object other) {
+		int retVal = -1;
+		for (int i = 0; i < array.length && retVal == -1; i++) {
+			if (other != null) {
+				if (array[i] != null && array[i].equals(other)) {
+					retVal = i;
+				}
+			} else {
+				if (array[i] == null) {
+					retVal = i;
+				}
+			}
+		}
+		return retVal;
+	}
+
+	/**
+	 * <p>
+	 * Finds the highest element in an array. If multiple elements have the
+	 * maximum value, the index of the first one is returned; null-values are
+	 * ignored. In case the parameter array is null, has length 0 or contains
+	 * only null-values, -1 is returned.
+	 * </p>
+	 * 
+	 * @param <T>
+	 * @param array
+	 *            the array
+	 * @return index of the element with the highest value, -1 in case of an
+	 *         invalid parameter
+	 */
+	@SuppressWarnings("unchecked")
+	public static <T> int findMax(Comparable<T>[] array) {
+		int maxIndex = -1;
+		T maxElement = null;
+		if (array != null) {
+			for (int i = 0; i < array.length; i++) {
+				if (array[i] != null) {
+					if (maxElement == null
+							|| array[i].compareTo(maxElement) > 0) {
+						maxElement = (T) array[i];
+						maxIndex = i;
+					}
+				}
+			}
+		}
+		return maxIndex;
+	}
+
+	/**
+	 * <p>
+	 * Finds the lowest element in an array. If multiple elements have the
+	 * minimal value, the index of the first one is returned; null-values are
+	 * ignored. In case the parameter array is null, has length 0 or contains
+	 * only null-values, -1 is returned.
+	 * </p>
+	 * 
+	 * @param <T>
+	 * @param array
+	 *            the array
+	 * @return index of the element with the lowest value, -1 in case of an
+	 *         invalid parameter
+	 */
+	@SuppressWarnings("unchecked")
+	public static <T> int findMin(Comparable<T>[] array) {
+		int maxIndex = -1;
+		T maxElement = null;
+		if (array != null) {
+			for (int i = 0; i < array.length; i++) {
+				if (array[i] != null) {
+					if (maxElement == null
+							|| array[i].compareTo(maxElement) < 0) {
+						maxElement = (T) array[i];
+						maxIndex = i;
+					}
+				}
+			}
+		}
+		return maxIndex;
+	}
+}
Index: /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/FileTools.java
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/FileTools.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/FileTools.java	(revision 540)
@@ -0,0 +1,88 @@
+package de.ugoe.cs.util;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.charset.Charset;
+
+/**
+ * <p>
+ * Helper class that provides methods that simplify working with files.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class FileTools {
+
+	/**
+	 * <p>
+	 * Private constructor to prevent initializing of the class.
+	 * </p>
+	 */
+	private FileTools() {
+
+	}
+
+	/**
+	 * <p>
+	 * Returns an array of the lines contained in a file. The line separator is
+	 * {@link StringTools#ENDLINE}.
+	 * </p>
+	 * 
+	 * @param filename
+	 *            name of the file
+	 * @return string array, where each line contains a file
+	 * @throws IOException
+	 *             see {@link FileReader#read(char[])},
+	 *             {@link FileReader#close()}
+	 * @throws FileNotFoundException
+	 *             see {@link FileReader#FileReader(File)}
+	 */
+	public static String[] getLinesFromFile(String filename)
+			throws IOException, FileNotFoundException {
+		boolean carriageReturn = true;
+		if( StringTools.ENDLINE.equals("\n") ) {
+			carriageReturn = false;
+		}
+		return getLinesFromFile(filename, carriageReturn);
+	}
+
+	/**
+	 * <p>
+	 * Returns an array of the lines contained in a file.
+	 * </p>
+	 * 
+	 * @param filename
+	 *            name of the file
+	 * @param carriageReturn
+	 *            if true, "\r\n", if false "\n" is used as line separator
+	 * @return string array, where each line contains a file
+	 * @throws IOException
+	 *             see {@link FileReader#read(char[])},
+	 *             {@link FileReader#close()}
+	 * @throws FileNotFoundException
+	 *             see {@link FileReader#FileReader(File)}
+	 */
+	public static String[] getLinesFromFile(String filename,
+			boolean carriageReturn) throws IOException, FileNotFoundException {
+		File f = new File(filename);
+		FileInputStream fis = new FileInputStream(f);
+		InputStreamReader reader = new InputStreamReader(fis,
+				Charset.defaultCharset());
+		char[] buffer = new char[(int) f.length()];
+		reader.read(buffer);
+		reader.close();
+		String splitString;
+		if (carriageReturn) {
+			splitString = "\r\n";
+		} else {
+			splitString = "\n";
+		}
+		return (new String(buffer)).split(splitString);
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/StringTools.java
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/StringTools.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/StringTools.java	(revision 540)
@@ -0,0 +1,53 @@
+package de.ugoe.cs.util;
+
+/**
+ * <p>
+ * Helper class that provides methods to simplify working with {@link String}s.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+final public class StringTools {
+
+	/**
+	 * <p>
+	 * Private constructor to prevent initializing of the class.
+	 * </p>
+	 */
+	private StringTools() {
+
+	}
+
+	/**
+	 * <p>
+	 * Simplifies use of operation system specific line separators.
+	 * </p>
+	 */
+	public final static String ENDLINE = System.getProperty("line.separator");
+
+	/**
+	 * <p>
+	 * Replaces all occurrences of {@literal &, <, >, ', and "} with their
+	 * respective XML entities {@literal &amp;, &lt;, &gt;, &apos;, and &quot;}
+	 * without destroying already existing entities.
+	 * </p>
+	 * 
+	 * @param str
+	 *            String where the XML entities are to be replaced
+	 * @return new String, where the XML entities are used instead of the
+	 *         literals
+	 */
+	public static String xmlEntityReplacement(String str) {
+		String result = str;
+		if (result != null && !"".equals(result)) {
+			result = result
+					.replaceAll("&(?!(?:lt|gt|apos|quot|amp);)", "&amp;");
+			result = result.replaceAll("<", "&lt;");
+			result = result.replaceAll(">", "&gt;");
+			result = result.replaceAll("'", "&apos;");
+			result = result.replaceAll("\"", "&quot;");
+		}
+		return result;
+	}
+}
Index: /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/console/Command.java
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/console/Command.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/console/Command.java	(revision 540)
@@ -0,0 +1,33 @@
+package de.ugoe.cs.util.console;
+
+import java.util.List;
+
+/**
+ * <p>
+ * Defines the interface for a command. The class names of the commands must be
+ * of the form {@code CMD<commandname>}, otherwise they cannot be used by the
+ * {@link CommandExecuter}.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public interface Command {
+
+	/**
+	 * <p>
+	 * Executes a command.
+	 * </p>
+	 * 
+	 * @param parameters
+	 *            parameters for the command.
+	 */
+	public void run(List<Object> parameters);
+
+	/**
+	 * <p>
+	 * Sends information about how to use a command to the console.
+	 * </p>
+	 */
+	public void help();
+}
Index: /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/console/CommandExecuter.java
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/console/CommandExecuter.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/console/CommandExecuter.java	(revision 540)
@@ -0,0 +1,167 @@
+package de.ugoe.cs.util.console;
+
+import java.security.InvalidParameterException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * <p>
+ * Executes commands. The commands have to implement the {@link Command}
+ * interface and be in packages registered using addCommandPackage().
+ * Additionally, default commands are implemented in the
+ * de.ugoe.cs.util.console.defaultcommands package.
+ * </p>
+ * <p>
+ * This class is implemented as a <i>Singleton</i>.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CommandExecuter {
+
+	/**
+	 * <p>
+	 * Handle of the CommandExecuter instance.
+	 * </p>
+	 */
+	private final static CommandExecuter theInstance = new CommandExecuter();
+
+	/**
+	 * <p>
+	 * Prefix of all command classes.
+	 * </p>
+	 */
+	private static final String cmdPrefix = "CMD";
+
+	/**
+	 * <p>
+	 * Name of the package for default commands.
+	 * </p>
+	 */
+	private static final String defaultPackage = "de.ugoe.cs.util.console.defaultcommands";
+
+	/**
+	 * <p>
+	 * List of packages in which commands may be defined. The exec methods trys
+	 * to load command from these packages in the order they have been added.
+	 * </p>
+	 * <p>
+	 * The de.ugoe.cs.util.console.defaultcommands package has always lowest
+	 * priority, unless it is specifically added.
+	 * </p>
+	 */
+	private List<String> commandPackageList;
+
+	/**
+	 * <p>
+	 * Returns the instance of CommandExecuter. If no instances exists yet, a
+	 * new one is created.
+	 * </p>
+	 * 
+	 * @return the instance of CommandExecuter
+	 */
+	public static synchronized CommandExecuter getInstance() {
+		return theInstance;
+	}
+
+	/**
+	 * <p>
+	 * Creates a new CommandExecuter. Private to prevent multiple instances
+	 * (Singleton).
+	 * </p>
+	 */
+	private CommandExecuter() {
+		commandPackageList = new ArrayList<String>();
+	}
+
+	/**
+	 * <p>
+	 * Adds a package that will be used by {@link #exec(String)} to load command
+	 * from.
+	 * </p>
+	 * 
+	 * @param pkg
+	 *            package where commands are located
+	 * @throws InvalidParameterException
+	 *             thrown if the package name is null or empty string
+	 */
+	public void addCommandPackage(String pkg) {
+		if ("".equals(pkg) || pkg == null) {
+			throw new InvalidParameterException(
+					"package name must not be null or empty string");
+		}
+		commandPackageList.add(pkg);
+	}
+
+	/**
+	 * <p>
+	 * Executes the command defined by string. A command has the following form
+	 * (mix of EBNF and natural language):
+	 * </p>
+	 * <code>
+	 * &lt;command&gt; := &lt;commandname&gt;&lt;whitespace&gt;{&lt;parameter&gt;}<br>
+	 * &lt;commandname&gt; := String without whitespaces. Has to be a valid Java class name<br>
+	 * &lt;parameter&gt; := &lt;string&gt;|&lt;stringarray&gt;<br>
+	 * &lt;string&gt; := &lt;stringwithoutwhitespaces&gt;|&lt;stringwithwhitespaces&gt;
+	 * &lt;stringwithoutwhitespaces&gt; := a string without whitespaces<br>
+	 * &lt;stringwithoutwhitespaces&gt; := a string, that can have whitespaces, but must be in double quotes<br>
+	 * &lt;stringarray&gt; := "["&lt;string&gt;{&lt;whitespace&gt;&lt;string&gt;"]"
+	 * </code>
+	 * 
+	 * @param command
+	 *            the command as a string
+	 */
+	public void exec(String command) {
+		Console.commandNotification(command);
+		Command cmd = null;
+		CommandParser parser = new CommandParser();
+		parser.parse(command);
+		for (int i = 0; cmd == null && i < commandPackageList.size(); i++) {
+			cmd = loadCMD(commandPackageList.get(i) + "." + cmdPrefix
+					+ parser.getCommandName());
+		}
+		if (cmd == null) { // check if command is available as default command
+			cmd = loadCMD(defaultPackage + "." + cmdPrefix
+					+ parser.getCommandName());
+		}
+		if (cmd == null) {
+			Console.println("Unknown command");
+		} else {
+			try {
+				cmd.run(parser.getParameters());
+			} catch (InvalidParameterException e) {
+				cmd.help();
+			}
+		}
+	}
+
+	/**
+	 * <p>
+	 * Helper method that loads a class and tries to cast it to {@link Command}.
+	 * </p>
+	 * 
+	 * @param className
+	 *            qualified name of the class (including package name)
+	 * @return if class is available and implement {@link Command} and instance
+	 *         of the class, null otherwise
+	 */
+	private Command loadCMD(String className) {
+		Command cmd = null;
+		try {
+			Class<?> cmdClass = Class.forName(className);
+			cmd = (Command) cmdClass.newInstance();
+		} catch (NoClassDefFoundError e) {
+			String[] splitResult = e.getMessage().split("CMD");
+			String correctName = splitResult[splitResult.length - 1].replace(
+					")", "");
+			Console.println("Did you mean " + correctName + "?");
+		} catch (ClassNotFoundException e) {
+		} catch (IllegalAccessException e) {
+		} catch (InstantiationException e) {
+		} catch (ClassCastException e) {
+			Console.traceln(className + "found, but does not implement Command");
+		}
+		return cmd;
+	}
+}
Index: /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/console/CommandParser.java
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/console/CommandParser.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/console/CommandParser.java	(revision 540)
@@ -0,0 +1,200 @@
+package de.ugoe.cs.util.console;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * <p>
+ * Helper class to parse command strings and create parameters.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CommandParser {
+
+	/**
+	 * <p>
+	 * Name of the command.
+	 * </p>
+	 */
+	private String commandName;
+
+	/**
+	 * <p>
+	 * Parameters of the command as a {@link List}. The parameters can either be
+	 * {@link String} or {@link String} arrays.
+	 * </p>
+	 */
+	private List<Object> parameters;
+
+	/**
+	 * <p>
+	 * Creates a new CommandParser.
+	 * </p>
+	 */
+	public CommandParser() {
+		commandName = "";
+		parameters = new ArrayList<Object>();
+	}
+
+	/**
+	 * <p>
+	 * Returns the name of the command.
+	 * </p>
+	 * 
+	 * @return name of the command
+	 */
+	public String getCommandName() {
+		return commandName;
+	}
+
+	/**
+	 * <p>
+	 * Returns the {@link List} of parameters
+	 * </p>
+	 * 
+	 * @return {@link List} of parameters that were parsed.
+	 */
+	public List<Object> getParameters() {
+		return parameters;
+	}
+
+	/**
+	 * <p>
+	 * Parses a command after the following EBNF (mixed with natural language):
+	 * </p>
+	 * <code>
+	 * &lt;command&gt; :=
+	 * &lt;commandname&gt;&lt;whitespace&gt;{&lt;parameter&gt;}<br>
+	 * &lt;commandname&gt; := String without whitespaces. Has to be a valid Java
+	 * class name<br>
+	 * &lt;parameter&gt; := &lt;string&gt;|&lt;stringarray&gt;<br>
+	 * &lt;string&gt; :=
+	 * &lt;stringwithoutwhitespaces&gt;|&lt;stringwithwhitespaces&gt;
+	 * &lt;stringwithoutwhitespaces&gt; := a string without whitespaces<br>
+	 * &lt;stringwithoutwhitespaces&gt; := a string, that can have whitespaces,
+	 * but must be in double quotes<br>
+	 * &lt;stringarray&gt; :=
+	 * "["&lt;string&gt;{&lt;whitespace&gt;&lt;string&gt;"]"
+	 * </code>
+	 * 
+	 * @param command
+	 *            the command as a string
+	 */
+	public void parse(String command) {
+		if (command == null || command.equals("")) {
+			return;
+		}
+		String[] splitResult = command.split(" ");
+		commandName = splitResult[0];
+		char[] commandChars = command.substring(commandName.length())
+				.toCharArray();
+		boolean startParameter = true;
+		boolean isArray = false;
+		boolean startArrayparameter = false;
+		boolean isString = false;
+		int bufferPos = 0;
+		char[] buffer = new char[1024];
+		boolean quote = false;
+		List<String> arrayBuffer = null;
+		for (int i = 0; i < commandChars.length; i++) {
+			if (i < commandChars.length && startParameter
+					&& commandChars[i] == '[') {
+				isArray = true;
+				startArrayparameter = true;
+				arrayBuffer = new ArrayList<String>();
+				startParameter = false;
+				i++; // skip [
+			}
+			if (i < commandChars.length && startParameter
+					&& commandChars[i] == '\'') {
+				isString = true;
+				quote = true;
+				startParameter = false;
+				i++; // skip '
+			}
+			if (i < commandChars.length && startParameter
+					&& !Character.isWhitespace(commandChars[i])) {
+				isString = true;
+				startParameter = false;
+			}
+			if (isArray) {
+				if (i < commandChars.length && commandChars[i] == ']') {
+					if (bufferPos > 0) {
+						buffer[bufferPos] = '\0';
+						arrayBuffer.add((new String(buffer)).trim());
+					}
+					parameters.add(arrayBuffer.toArray(new String[0]));
+					isArray = false;
+					isString = false;
+					bufferPos = 0;
+					buffer = new char[128];
+					startArrayparameter = false;
+					startParameter = true;
+					i++; // skip ]
+				}
+				if (i < commandChars.length && startArrayparameter
+						&& !Character.isWhitespace(commandChars[i])) {
+					buffer = new char[128];
+					bufferPos = 0;
+					quote = commandChars[i] == '\'';
+					if (quote) {
+						i++; // skip '
+					}
+					startArrayparameter = false;
+				}
+				if (i < commandChars.length && quote && !startArrayparameter && commandChars[i] == '\'') {
+					// end of parameter with '
+					i++; // skip '
+					startArrayparameter = true;
+					buffer[bufferPos] = '\0';
+					arrayBuffer.add((new String(buffer)).trim());
+				}
+				if (i < commandChars.length && !quote && !startArrayparameter
+						&& Character.isWhitespace(commandChars[i])) {
+					startArrayparameter = true;
+					buffer[bufferPos] = '\0';
+					arrayBuffer.add((new String(buffer)).trim());
+				}
+				if (i < commandChars.length && !startArrayparameter
+						&& !startParameter) {
+					buffer[bufferPos] = commandChars[i];
+					bufferPos++;
+				}
+			}
+			if (isString) {
+				if ((quote && commandChars[i] == '\'')
+						|| (!quote && Character.isWhitespace(commandChars[i]))) {
+					// end of parameter with '
+					if (quote) {
+						i++; // skip '
+					}
+					if (bufferPos > 0) {
+						buffer[bufferPos] = '\0';
+					}
+					parameters.add((new String(buffer).trim()));
+					isArray = false;
+					isString = false;
+					bufferPos = 0;
+					buffer = new char[128];
+					startArrayparameter = false;
+					startParameter = true;
+				}
+				if (!startParameter) {
+					buffer[bufferPos] = commandChars[i];
+					bufferPos++;
+				}
+			}
+		}
+		if (bufferPos > 0) {
+			if (isArray) {
+				//arrayBuffer.add((new String(buffer)).trim());
+				parameters.add(arrayBuffer.toArray(new String[0]));
+			}
+			if (isString) {
+				parameters.add((new String(buffer)).trim());
+			}
+		}
+	}
+}
Index: /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/console/Console.java
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/console/Console.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/console/Console.java	(revision 540)
@@ -0,0 +1,457 @@
+package de.ugoe.cs.util.console;
+
+import java.util.Collection;
+import java.util.LinkedHashSet;
+
+import de.ugoe.cs.util.StringTools;
+import de.ugoe.cs.util.console.listener.ICommandListener;
+import de.ugoe.cs.util.console.listener.IErrorListener;
+import de.ugoe.cs.util.console.listener.IExceptionListener;
+import de.ugoe.cs.util.console.listener.IOutputListener;
+import de.ugoe.cs.util.console.listener.ITraceListener;
+
+/**
+ * <p>
+ * This class provides an interface for communication with the user without have
+ * to rely on a specific user interface. Thus, it can be used to decouple the
+ * programs logic from its user interface.
+ * </p>
+ * <p>
+ * {@link Command} objects can be used to execute behavior.
+ * </p>
+ * <p>
+ * To send output to the user interface, the Observer pattern is used. The
+ * Console is an observable, the concrete user interfaces are the observers. The
+ * interface for the observers is {@link ConsoleObserver}.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public final class Console {
+
+	/**
+	 * <p>
+	 * Listeners for the output stream.
+	 * </p>
+	 */
+	private Collection<IOutputListener> outputListener;
+
+	/**
+	 * <p>
+	 * Listeners for the error stream.
+	 * </p>
+	 */
+	private Collection<IErrorListener> errorListener;
+
+	/**
+	 * <p>
+	 * Listeners for the trace stream.
+	 * </p>
+	 */
+	private Collection<ITraceListener> traceListener;
+
+	/**
+	 * <p>
+	 * Listeners for the command stream.
+	 * </p>
+	 */
+	private Collection<ICommandListener> commandListener;
+
+	/**
+	 * <p>
+	 * Listeners for the exception stream.
+	 * </p>
+	 */
+	private Collection<IExceptionListener> exceptionListener;
+
+	/**
+	 * <p>
+	 * Handle of the Console instance.
+	 * </p>
+	 */
+	private static Console theInstance = new Console();
+
+	/**
+	 * <p>
+	 * Returns the instance of Console. If no instances exists yet, a new one is
+	 * created.
+	 * </p>
+	 * 
+	 * @return instance of this class
+	 */
+	public static Console getInstance() {
+		return theInstance;
+	}
+
+	/**
+	 * <p>
+	 * Resets the Console by creating a new instance that has no registered
+	 * observers.
+	 * </p>
+	 */
+	public static void reset() {
+		theInstance.init();
+	}
+
+	/**
+	 * <p>
+	 * Creates a new Console. Private to prevent multiple instances (Singleton).
+	 * </p>
+	 */
+	private Console() {
+		init();
+	}
+
+	/**
+	 * <p>
+	 * Initializes the console.
+	 * </p>
+	 */
+	private void init() {
+		outputListener = new LinkedHashSet<IOutputListener>();
+		errorListener = new LinkedHashSet<IErrorListener>();
+		traceListener = new LinkedHashSet<ITraceListener>();
+		commandListener = new LinkedHashSet<ICommandListener>();
+		exceptionListener = new LinkedHashSet<IExceptionListener>();
+	}
+
+	/**
+	 * <p>
+	 * Register a new observer.
+	 * </p>
+	 * 
+	 * @deprecated use registerXYZListener instead
+	 * @param observer
+	 *            observer to be added
+	 */
+	public void registerObserver(ConsoleObserver observer) {
+		registerOutputListener(observer);
+		registerErrorListener(observer);
+		registerTraceListener(observer);
+		registerCommandListener(observer);
+		registerExceptionListener(observer);
+	}
+
+	/**
+	 * <p>
+	 * Registers an output listener.
+	 * </p>
+	 * 
+	 * @param listener
+	 *            listener that is registered
+	 */
+	public void registerOutputListener(IOutputListener listener) {
+		outputListener.add(listener);
+	}
+
+	/**
+	 * <p>
+	 * Registers an error listener.
+	 * </p>
+	 * 
+	 * @param listener
+	 *            listener that is registered
+	 */
+	public void registerErrorListener(IErrorListener listener) {
+		errorListener.add(listener);
+	}
+
+	/**
+	 * <p>
+	 * Registers a trace listener.
+	 * </p>
+	 * 
+	 * @param listener
+	 *            listener that is registered
+	 */
+	public void registerTraceListener(ITraceListener listener) {
+		traceListener.add(listener);
+	}
+
+	/**
+	 * <p>
+	 * Registers a command listener.
+	 * </p>
+	 * 
+	 * @param listener
+	 *            listener that is registered
+	 */
+	public void registerCommandListener(ICommandListener listener) {
+		commandListener.add(listener);
+	}
+
+	/**
+	 * <p>
+	 * Registers an exception listener.
+	 * </p>
+	 * 
+	 * @param listener
+	 *            listener that is registered
+	 */
+	public void registerExceptionListener(IExceptionListener listener) {
+		exceptionListener.add(listener);
+	}
+
+	/**
+	 * <p>
+	 * Remove an observer. If the observer is not found, nothing is done.
+	 * </p>
+	 * 
+	 * @deprecated use removeXYZListener instead
+	 * @param observer
+	 *            observer to be removed
+	 */
+	public void deleteObserver(ConsoleObserver observer) {
+		removeOutputListener(observer);
+		removeErrorListener(observer);
+		removeTraceListener(observer);
+		removeCommandListener(observer);
+		removeExceptionListener(observer);
+	}
+
+	/**
+	 * <p>
+	 * Removes an output listener.
+	 * </p>
+	 * 
+	 * @param listener
+	 *            listener that is removed
+	 */
+	public void removeOutputListener(IOutputListener listener) {
+		outputListener.remove(listener);
+	}
+
+	/**
+	 * <p>
+	 * Removes an error listener.
+	 * </p>
+	 * 
+	 * @param listener
+	 *            listener that is removed
+	 */
+	public void removeErrorListener(IErrorListener listener) {
+		errorListener.remove(listener);
+	}
+
+	/**
+	 * <p>
+	 * Removes an trace listener.
+	 * </p>
+	 * 
+	 * @param listener
+	 *            listener that is removed
+	 */
+	public void removeTraceListener(ITraceListener listener) {
+		traceListener.remove(listener);
+	}
+
+	/**
+	 * <p>
+	 * Removes a command listener.
+	 * </p>
+	 * 
+	 * @param listener
+	 *            listener that is removed
+	 */
+	public void removeCommandListener(ICommandListener listener) {
+		commandListener.remove(listener);
+	}
+
+	/**
+	 * <p>
+	 * Removes an exception listener.
+	 * </p>
+	 * 
+	 * @param listener
+	 *            listener that is removed
+	 */
+	public void removeExceptionListener(IExceptionListener listener) {
+		exceptionListener.remove(listener);
+	}
+
+	/**
+	 * <p>
+	 * Checks if a listener is registered.
+	 * </p>
+	 * 
+	 * @param listener
+	 *            listener that is checked
+	 * @return true, is listener is registered; false, otherwise
+	 */
+	public boolean hasOutputListener(IOutputListener listener) {
+		return outputListener.contains(listener);
+	}
+
+	/**
+	 * <p>
+	 * Checks if a listener is registered.
+	 * </p>
+	 * 
+	 * @param listener
+	 *            listener that is checked
+	 * @return true, is listener is registered; false, otherwise
+	 */
+	public boolean hasErrorListener(IErrorListener listener) {
+		return errorListener.contains(listener);
+	}
+
+	/**
+	 * <p>
+	 * Checks if a listener is registered.
+	 * </p>
+	 * 
+	 * @param listener
+	 *            listener that is checked
+	 * @return true, is listener is registered; false, otherwise
+	 */
+	public boolean hasTraceListener(ITraceListener listener) {
+		return traceListener.contains(listener);
+	}
+
+	/**
+	 * <p>
+	 * Checks if a listener is registered.
+	 * </p>
+	 * 
+	 * @param listener
+	 *            listener that is checked
+	 * @return true, is listener is registered; false, otherwise
+	 */
+	public boolean hasCommandListener(ICommandListener listener) {
+		return commandListener.contains(listener);
+	}
+
+	/**
+	 * <p>
+	 * Checks if a listener is registered.
+	 * </p>
+	 * 
+	 * @param listener
+	 *            listener that is checked
+	 * @return true, is listener is registered; false, otherwise
+	 */
+	public boolean hasExceptionListener(IExceptionListener listener) {
+		return exceptionListener.contains(listener);
+	}
+
+	/**
+	 * <p>
+	 * Sends a message to all observers containing the message that was passed
+	 * to this function.
+	 * </p>
+	 * 
+	 * @param msg
+	 *            message that is send to the console
+	 */
+	public static void print(String msg) {
+		for (IOutputListener observer : theInstance.outputListener) {
+			observer.outputMsg(msg);
+		}
+	}
+
+	/**
+	 * <p>
+	 * Sends a message to all observers containing the message that was passed
+	 * to this function and adds an endline to the message.
+	 * </p>
+	 * 
+	 * @param msg
+	 *            message that is send to the observers
+	 */
+	public static void println(String msg) {
+		for (IOutputListener observer : theInstance.outputListener) {
+			observer.outputMsg(msg + StringTools.ENDLINE);
+		}
+	}
+
+	/**
+	 * <p>
+	 * Sends an error message to all observers containing the message that was
+	 * passed to this function.
+	 * </p>
+	 * 
+	 * @param errMsg
+	 *            message that is send to the observers
+	 */
+	public static void printerr(String errMsg) {
+		for (IErrorListener observer : theInstance.errorListener) {
+			observer.errorMsg(errMsg);
+		}
+	}
+
+	/**
+	 * <p>
+	 * Sends an error message to all observers containing the message that was
+	 * passed to this function and adds an endline to the message.
+	 * </p>
+	 * 
+	 * @param errMsg
+	 *            message that is send to the observers
+	 */
+	public static void printerrln(String errMsg) {
+		for (IErrorListener observer : theInstance.errorListener) {
+			observer.errorMsg(errMsg + StringTools.ENDLINE);
+		}
+	}
+
+	/**
+	 * <p>
+	 * Sends an exception to all observers to print its stack trace.
+	 * </p>
+	 * 
+	 * @param e
+	 *            exception whose stack trace is to be printed
+	 */
+	public static void logException(Exception e) {
+		for (IExceptionListener observer : theInstance.exceptionListener) {
+			observer.logException(e);
+		}
+	}
+
+	/**
+	 * <p>
+	 * Sends a debug message to all observers containing the message that was
+	 * passed to this function.
+	 * </p>
+	 * 
+	 * @param traceMsg
+	 *            message that is send to the observers
+	 */
+	public static void trace(String traceMsg) {
+		for (ITraceListener observer : theInstance.traceListener) {
+			observer.traceMsg(traceMsg);
+		}
+	}
+
+	/**
+	 * <p>
+	 * Sends a debug message to all observers containing the message that was
+	 * passed to this function and adds an {@link StringTools#ENDLINE} to the
+	 * message.
+	 * </p>
+	 * 
+	 * @param traceMsg
+	 *            message that is send to the observers
+	 */
+	public static void traceln(String traceMsg) {
+		for (ITraceListener observer : theInstance.traceListener) {
+			observer.traceMsg(traceMsg + StringTools.ENDLINE);
+		}
+	}
+
+	/**
+	 * <p>
+	 * Called by {@link CommandExecuter#exec(String)}.
+	 * </p>
+	 * 
+	 * @param command
+	 *            command that is executed
+	 */
+	static void commandNotification(String command) {
+		for (ICommandListener observer : theInstance.commandListener) {
+			observer.commandNotification(command);
+		}
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/console/ConsoleObserver.java
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/console/ConsoleObserver.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/console/ConsoleObserver.java	(revision 540)
@@ -0,0 +1,20 @@
+package de.ugoe.cs.util.console;
+
+import de.ugoe.cs.util.console.listener.ICommandListener;
+import de.ugoe.cs.util.console.listener.IErrorListener;
+import de.ugoe.cs.util.console.listener.IExceptionListener;
+import de.ugoe.cs.util.console.listener.IOutputListener;
+import de.ugoe.cs.util.console.listener.ITraceListener;
+
+/**
+ * <p>
+ * Observer for Console.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 2.0
+ * @deprecated Use listeners defined in the package de.ugoe.cs.console.listeners instead.
+ */
+public interface ConsoleObserver extends ITraceListener, IOutputListener, IErrorListener, ICommandListener, IExceptionListener {
+
+}
Index: /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/console/FileOutputListener.java
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/console/FileOutputListener.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/console/FileOutputListener.java	(revision 540)
@@ -0,0 +1,126 @@
+package de.ugoe.cs.util.console;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+
+import de.ugoe.cs.util.console.listener.IOutputListener;
+
+/**
+ * <p>
+ * Implements an {@link IOutputListener} for the {@link Console} that logs all
+ * outputs in a file. This can be used to "pipe" the output-stream of the
+ * console into a file. The advantage of using this mechanism for piping is that
+ * the file will only contain the output stream. No errors, no commands, etc.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class FileOutputListener implements IOutputListener {
+
+	/**
+	 * <p>
+	 * Flag that ensures that only one log message is produced if the listener
+	 * breaks, e.g., because of a full hard disk/quota.
+	 * </p>
+	 */
+	boolean failureLogged = false;
+
+	/**
+	 * <p>
+	 * Name of the output file.
+	 * </p>
+	 */
+	String filename;
+
+	/**
+	 * <p>
+	 * Writer for the output.
+	 * </p>
+	 */
+	OutputStreamWriter writer = null;
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new FileOutputListener.
+	 * </p>
+	 * 
+	 * @param filename
+	 *            name and path of the file the listener writes to.
+	 */
+	public FileOutputListener(String filename) {
+		this.filename = filename;
+
+	}
+
+	/**
+	 * <p>
+	 * Starts the listener by opening the file and registering it with the
+	 * {@link Console}.
+	 * </p>
+	 */
+	public void start() {
+		try {
+			FileOutputStream fos = new FileOutputStream(filename);
+			writer = new OutputStreamWriter(fos, "UTF-8");
+			Console.getInstance().registerOutputListener(this);
+		} catch (IOException e) {
+			Console.printerrln("Failed to start FileOutputListener for file "
+					+ filename + ": " + e.getMessage());
+		}
+	}
+
+	/**
+	 * <p>
+	 * Stops the listener by closing the file and removing itself from the
+	 * {@link Console}.
+	 * </p>
+	 */
+	public void stop() {
+		Console.getInstance().removeOutputListener(this);
+		if( writer!=null ) {
+			try {
+				writer.close();
+				writer = null;
+			} catch (IOException e) {
+				Console.printerrln("Failed to close file " + filename + ": "
+						+ e.getMessage());
+			}
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * de.ugoe.cs.util.console.listener.IOutputListener#outputMsg(java.lang.
+	 * String)
+	 */
+	@Override
+	public void outputMsg(String newMessage) {
+		if( writer!=null ) {
+			try {
+				writer.write(newMessage);
+			} catch (IOException e) {
+				if (!failureLogged) {
+					Console.printerrln("FileOutpustListener for file " + filename
+							+ " broken: " + e.getMessage());
+					failureLogged = true;
+				}
+			}
+		}
+	}
+
+	/**
+	 * <p>
+	 * Returns the name of the log file used by this listener.
+	 * </p>
+	 * 
+	 * @return name of the log file
+	 */
+	public String getFilename() {
+		return filename;
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/console/TextConsole.java
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/console/TextConsole.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/console/TextConsole.java	(revision 540)
@@ -0,0 +1,149 @@
+package de.ugoe.cs.util.console;
+
+import java.io.IOException;
+import java.nio.charset.Charset;
+
+import de.ugoe.cs.util.console.listener.IErrorListener;
+import de.ugoe.cs.util.console.listener.IExceptionListener;
+import de.ugoe.cs.util.console.listener.IOutputListener;
+import de.ugoe.cs.util.console.listener.ITraceListener;
+
+/**
+ * <p>
+ * Implements a simple console observer that prints normal text to
+ * {@code stdout}, errors to {@code stderr} and reads from {@code stdin}.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class TextConsole implements IOutputListener, IErrorListener,
+		ITraceListener, IExceptionListener {
+
+	/**
+	 * <p>
+	 * In the debug mode, trace messages will be printed.
+	 * </p>
+	 */
+	private boolean debugMode = true;
+
+	/**
+	 * <p>
+	 * Creates a new text console and automatically registers it as observer.
+	 * </p>
+	 */
+	public TextConsole() {
+		Console.getInstance().registerOutputListener(this);
+		Console.getInstance().registerErrorListener(this);
+		Console.getInstance().registerTraceListener(this);
+		Console.getInstance().registerExceptionListener(this);
+	}
+
+	/**
+	 * <p>
+	 * Prints messages to {@code stdout}.
+	 * </p>
+	 * 
+	 * @see ConsoleObserver#outputMsg(java.lang.String)
+	 */
+	public void outputMsg(String newMessage) {
+		System.out.print(newMessage);
+	}
+
+	/**
+	 * <p>
+	 * Prints messages to {@code stderr}.
+	 * </p>
+	 * 
+	 * @see ConsoleObserver#errorMsg(String)
+	 */
+	@Override
+	public void errorMsg(String errMessage) {
+		System.err.print(errMessage);
+	}
+
+	/**
+	 * <p>
+	 * Prints the stacktrace of an exception to {@code stderr}.
+	 * </p>
+	 * 
+	 * @see ConsoleObserver#logException(Exception)
+	 */
+	@Override
+	public void logException(Exception e) {
+		System.err.println(e.getMessage());
+	}
+
+	/**
+	 * <p>
+	 * Prints messages to {@code stdout}. These messages are only printed, if
+	 * the console is run in debug mode.
+	 * </p>
+	 */
+	@Override
+	public void traceMsg(String traceMessage) {
+		if (debugMode) {
+			System.out.print(traceMessage);
+		}
+	}
+
+	/**
+	 * <p>
+	 * Starts a new TextConsole. If the text console is started, it can be used
+	 * not only to print message, but also to execute commands by reading
+	 * {@code stdin}.
+	 * </p>
+	 * 
+	 * @param debugMode
+	 *            true, if the application is to run in debug mode, i.e. trace
+	 *            messages will be printed
+	 */
+	public void run(boolean debugMode) {
+		this.debugMode = debugMode;
+		CommandExecuter exec = CommandExecuter.getInstance();
+		while (true) {
+			System.out.print("> ");
+			String command = getCommand().trim();
+			if (!command.equals("")) {
+				exec.exec(command);
+			}
+		}
+	}
+
+	/**
+	 * <p>
+	 * Reads a new command from {@code stdin}.
+	 * </p>
+	 * 
+	 * @return a string with a command
+	 */
+	protected String getCommand() {
+		byte[] buffer = new byte[1024];
+		int bytesRead = 0;
+		String command;
+		try {
+			bytesRead = System.in.read(buffer);
+		} catch (IOException e) {
+
+		}
+		if (bytesRead == 0) {
+			command = "";
+		} else {
+			command = new String(buffer, Charset.defaultCharset());
+		}
+		return command;
+	}
+
+	/**
+	 * <p>
+	 * Configures if the debug mode of the text console is enabled.
+	 * </p>
+	 * 
+	 * @param debug
+	 *            if true, debug mode is enabled.
+	 */
+	public void setDebug(boolean debug) {
+		debugMode = debug;
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/console/defaultcommands/CMDexec.java
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/console/defaultcommands/CMDexec.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/console/defaultcommands/CMDexec.java	(revision 540)
@@ -0,0 +1,67 @@
+package de.ugoe.cs.util.console.defaultcommands;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.security.InvalidParameterException;
+import java.util.List;
+
+import de.ugoe.cs.util.console.Command;
+import de.ugoe.cs.util.console.CommandExecuter;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Command to execute a batch of {@link Command}s. The batch is defined as a
+ * text file, where each line defines one command.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CMDexec implements Command {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#run(java.util.List)
+	 */
+	public void run(List<Object> parameters) {
+		String script;
+		try {
+			script = (String) parameters.get(0);
+		} catch (Exception e) {
+			throw new InvalidParameterException();
+		}
+		try {
+			String[] commands;
+			File f = new File(script);
+			FileInputStream fis = new FileInputStream(f);
+			InputStreamReader reader = new InputStreamReader(fis, "UTF-8");
+			char[] buffer = new char[(int) f.length()];
+			reader.read(buffer);
+			commands = (new String(buffer)).split("\n");
+			for (String command : commands) {
+				Console.traceln(command.trim());
+				CommandExecuter.getInstance().exec(command);
+			}
+			reader.close();
+		} catch (FileNotFoundException e) {
+			Console.printerrln(e.getMessage());
+		} catch (IOException e) {
+			Console.printerrln(e.getMessage());
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see databasebuilder.console.commands.Command#help()
+	 */
+	@Override
+	public void help() {
+		Console.println("Usage: exec <filename>");
+	}
+}
Index: /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/console/defaultcommands/CMDexit.java
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/console/defaultcommands/CMDexit.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/console/defaultcommands/CMDexit.java	(revision 540)
@@ -0,0 +1,38 @@
+package de.ugoe.cs.util.console.defaultcommands;
+
+import java.util.List;
+
+import de.ugoe.cs.util.console.Command;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Command to terminate an application.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CMDexit implements Command {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see databasebuilder.console.commands.Command#help()
+	 */
+	@Override
+	public void help() {
+		Console.println("Usage: exit");
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#run(java.util.List)
+	 */
+	@Override
+	public void run(List<Object> parameters) {
+		System.exit(0);
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/console/listener/ICommandListener.java
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/console/listener/ICommandListener.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/console/listener/ICommandListener.java	(revision 540)
@@ -0,0 +1,25 @@
+package de.ugoe.cs.util.console.listener;
+
+import de.ugoe.cs.util.console.CommandExecuter;
+
+/**
+ * <p>
+ * Interface for listeners observing the commands executed by the
+ * {@link CommandExecuter}.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public interface ICommandListener {
+	/**
+	 * <p>
+	 * Receives the command strings of all executed by the
+	 * {@link CommandExecuter}.
+	 * </p>
+	 * 
+	 * @param command
+	 *            string of the command.
+	 */
+	public void commandNotification(String command);
+}
Index: /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/console/listener/IErrorListener.java
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/console/listener/IErrorListener.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/console/listener/IErrorListener.java	(revision 540)
@@ -0,0 +1,24 @@
+package de.ugoe.cs.util.console.listener;
+
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Interface for listeners observing the error stream of the {@link Console}.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public interface IErrorListener {
+
+	/**
+	 * <p>
+	 * Receives messages send to the error stream of the {@link Console}.
+	 * </p>
+	 * 
+	 * @param errMessage
+	 *            error message
+	 */
+	public void errorMsg(String errMessage);
+}
Index: /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/console/listener/IExceptionListener.java
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/console/listener/IExceptionListener.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/console/listener/IExceptionListener.java	(revision 540)
@@ -0,0 +1,24 @@
+package de.ugoe.cs.util.console.listener;
+
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Received all exceptions passed to the {@link Console} for logging.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public interface IExceptionListener {
+
+	/**
+	 * <p>
+	 * Logs an exception passed to the {@link Console}.
+	 * </p>
+	 * 
+	 * @param e
+	 *            Exception that is logged
+	 */
+	public void logException(Exception e);
+}
Index: /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/console/listener/IOutputListener.java
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/console/listener/IOutputListener.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/console/listener/IOutputListener.java	(revision 540)
@@ -0,0 +1,25 @@
+package de.ugoe.cs.util.console.listener;
+
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Interface for listeners observing the output stream of the {@link Console}.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public interface IOutputListener {
+
+	/**
+	 * <p>
+	 * Receives messages send to the output stream of the {@link Console}.
+	 * </p>
+	 * 
+	 * @param newMessage
+	 *            message that was send to the console.
+	 */
+	public void outputMsg(String newMessage);
+
+}
Index: /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/console/listener/ITraceListener.java
===================================================================
--- /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/console/listener/ITraceListener.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/java-utils/src/main/java/de/ugoe/cs/util/console/listener/ITraceListener.java	(revision 540)
@@ -0,0 +1,23 @@
+package de.ugoe.cs.util.console.listener;
+
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Interface for listeners observing traces stream to the {@link Console}.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public interface ITraceListener {
+	/**
+	 * <p>
+	 * Receives messages send to the trace stream of the {@link Console}.
+	 * </p>
+	 * 
+	 * @param traceMessage
+	 *            error message
+	 */
+	public void traceMsg(String traceMessage);
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-assertions-test/.classpath
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-assertions-test/.classpath	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-assertions-test/.classpath	(revision 540)
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/test-classes" path="src/test/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="src" output="target/classes" path="src/main/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
Index: /tags/quest-pre-eventrefactoring/quest-core-assertions-test/.project
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-assertions-test/.project	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-assertions-test/.project	(revision 540)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>quest-core-assertions-test</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
Index: /tags/quest-pre-eventrefactoring/quest-core-assertions-test/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-assertions-test/.settings/org.eclipse.jdt.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-assertions-test/.settings/org.eclipse.jdt.core.prefs	(revision 540)
@@ -0,0 +1,5 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.6
Index: /tags/quest-pre-eventrefactoring/quest-core-assertions-test/.settings/org.eclipse.m2e.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-assertions-test/.settings/org.eclipse.m2e.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-assertions-test/.settings/org.eclipse.m2e.core.prefs	(revision 540)
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
Index: /tags/quest-pre-eventrefactoring/quest-core-assertions-test/pom.xml
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-assertions-test/pom.xml	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-assertions-test/pom.xml	(revision 540)
@@ -0,0 +1,151 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>de.ugoe.cs.quest</groupId>
+  <artifactId>quest-core-assertions-test</artifactId>
+  <version>0.0.1-SNAPSHOT</version>
+  <name>quest-core-assertions-test</name>
+  <scm>
+    <url>https://quest.informatik.uni-goettingen.de/svn/quest/trunk/quest-core-events-test</url>
+  </scm>
+  <dependencies>
+    <dependency>
+        <groupId>de.ugoe.cs.quest</groupId>
+        <artifactId>quest-core-events</artifactId>
+        <version>0.0.1-SNAPSHOT</version>
+        <scope>test</scope>
+    </dependency>
+    <dependency>
+		<groupId>de.ugoe.cs.quest</groupId>
+		<artifactId>quest-core-assertions</artifactId>
+		<version>0.0.1-SNAPSHOT</version>
+		<scope>test</scope>
+	</dependency>
+	<dependency>
+		<groupId>de.ugoe.cs.quest</groupId>
+		<artifactId>quest-core-events-test</artifactId>
+		<version>0.0.1-SNAPSHOT</version>
+		<type>test-jar</type>
+		<scope>test</scope>
+	</dependency>
+    <dependency>
+        <groupId>junit</groupId>
+        <artifactId>junit</artifactId>
+        <version>4.8.1</version>
+        <scope>test</scope>
+    </dependency>
+    <!-- <dependency>
+	  <groupId>junit-addons</groupId>
+	  <artifactId>junit-addons</artifactId>
+	  <version>1.4</version>
+    </dependency>
+    <dependency>
+	  <groupId>nl.jqno.equalsverifier</groupId>
+	  <artifactId>equalsverifier</artifactId>
+	  <version>1.1.3</version>
+    </dependency>-->
+  </dependencies>
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.eclipse.m2e</groupId>
+          <artifactId>lifecycle-mapping</artifactId>
+          <version>1.0.0</version>
+          <configuration>
+            <lifecycleMappingMetadata>
+              <pluginExecutions>
+                <pluginExecution>
+                  <pluginExecutionFilter>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-dependency-plugin</artifactId>
+                    <versionRange>[1.0.0,)</versionRange>
+                    <goals>
+                      <goal>unpack</goal>
+                    </goals>
+                  </pluginExecutionFilter>
+                  <action>
+                    <ignore/>
+                  </action>
+                </pluginExecution>
+                <pluginExecution>
+                  <pluginExecutionFilter>
+                    <groupId>org.codehaus.mojo</groupId>
+                    <artifactId>emma-maven-plugin</artifactId>
+                    <versionRange>[1.0-alpha-3,)</versionRange>
+                    <goals>
+                      <goal>emma</goal>
+                    </goals>
+                  </pluginExecutionFilter>
+                  <action>
+                    <ignore/>
+                  </action>
+                </pluginExecution>
+              </pluginExecutions>
+            </lifecycleMappingMetadata>
+          </configuration>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>2.3.2</version>
+        <configuration>
+          <source>1.6</source>
+          <target>1.6</target>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-dependency-plugin</artifactId>
+        <version>2.4</version>
+        <executions>
+          <execution>
+            <id>unpack</id>
+            <phase>process-classes</phase>
+            <goals>
+              <goal>unpack</goal>
+            </goals>
+            <configuration>
+              <artifactItems>
+                <artifactItem>
+                  <groupId>de.ugoe.cs.quest</groupId>
+                  <artifactId>quest-core-assertions</artifactId>
+                  <version>0.0.1-SNAPSHOT</version>
+                  <outputDirectory>${project.build.directory}/classes</outputDirectory>
+                </artifactItem>
+              </artifactItems>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>emma-maven-plugin</artifactId>
+        <version>1.0-alpha-3</version>
+        <inherited>true</inherited>          
+        <executions>
+          <execution>
+            <phase>process-classes</phase>
+            <goals>
+              <goal>emma</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <version>2.3.2</version>
+        <executions>
+          <execution>
+            <goals>
+              <goal>test-jar</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>
Index: /tags/quest-pre-eventrefactoring/quest-core-assertions-test/src/test/java/de/ugoe/cs/quest/assertions/AssertEventTest.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-assertions-test/src/test/java/de/ugoe/cs/quest/assertions/AssertEventTest.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-assertions-test/src/test/java/de/ugoe/cs/quest/assertions/AssertEventTest.java	(revision 540)
@@ -0,0 +1,38 @@
+package de.ugoe.cs.quest.assertions;
+
+import org.junit.*;
+
+import de.ugoe.cs.quest.assertions.AssertEvent;
+import de.ugoe.cs.quest.eventcore.mock.MockReplayable;
+import static org.junit.Assert.*;
+
+/**
+ * The class <code>AssertEventTest</code> contains tests for the class
+ * <code>{@link AssertEvent}</code>.
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class AssertEventTest {
+
+	@Test
+	public void testAssertEvent_1() throws Exception {
+		String type = "typeString";
+
+		AssertEvent<MockReplayable> result = new AssertEvent<MockReplayable>(
+				type);
+
+		assertNotNull(result);
+		assertEquals(type, result.getType());
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testAssertEvent_2() throws Exception {
+
+		new AssertEvent<MockReplayable>(null);
+	}
+
+	public static void main(String[] args) {
+		new org.junit.runner.JUnitCore().run(AssertEventTest.class);
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-assertions-test/src/test/java/de/ugoe/cs/quest/assertions/FileEqualsReplayTest.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-assertions-test/src/test/java/de/ugoe/cs/quest/assertions/FileEqualsReplayTest.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-assertions-test/src/test/java/de/ugoe/cs/quest/assertions/FileEqualsReplayTest.java	(revision 540)
@@ -0,0 +1,80 @@
+package de.ugoe.cs.quest.assertions;
+
+import org.junit.*;
+
+import de.ugoe.cs.quest.assertions.FileEqualsReplay;
+import static org.junit.Assert.*;
+
+/**
+ * The class <code>FileEqualsReplayTest</code> contains tests for the class
+ * <code>{@link FileEqualsReplay}</code>.
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class FileEqualsReplayTest {
+
+	private final static String ENDLINE = System.getProperty("line.separator");
+
+	@Test
+	public void testFileEqualsReplay_1() throws Exception {
+		String expectedFile = "expectedFileString";
+		String actualFile = "actualFileString";
+
+		FileEqualsReplay result = new FileEqualsReplay(expectedFile, actualFile);
+
+		assertNotNull(result);
+		assertEquals(expectedFile, result.expectedFile);
+		assertEquals(actualFile, result.actualFile);
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testFileEqualsReplay_2() throws Exception {
+		String actualFile = "actualFileString";
+
+		new FileEqualsReplay(null, actualFile);
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testFileEqualsReplay_3() throws Exception {
+		String expectedFile = "expectedFileString";
+
+		new FileEqualsReplay(expectedFile, null);
+	}
+
+	@Test
+	public void testGetReplay_1() throws Exception {
+		FileEqualsReplay fixture = new FileEqualsReplay("", "");
+
+		String result = fixture.getReplay();
+
+		assertEquals("  <fileEquals actualFile=\"\" expectedFile=\"\"/>"
+				+ ENDLINE, result);
+	}
+
+	@Test
+	public void testGetReplay_2() throws Exception {
+
+		FileEqualsReplay fixture = new FileEqualsReplay("expectedFileString",
+				"actualFileString");
+
+		String result = fixture.getReplay();
+
+		assertEquals(
+				"  <fileEquals actualFile=\"actualFileString\" expectedFile=\"expectedFileString\"/>"
+						+ ENDLINE, result);
+	}
+
+	@Test
+	public void testGetTarget_1() throws Exception {
+		FileEqualsReplay fixture = new FileEqualsReplay("", "");
+
+		String result = fixture.getTarget();
+
+		assertEquals("targetNotUsed", result);
+	}
+
+	public static void main(String[] args) {
+		new org.junit.runner.JUnitCore().run(FileEqualsReplayTest.class);
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-assertions-test/src/test/java/de/ugoe/cs/quest/assertions/TestAll.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-assertions-test/src/test/java/de/ugoe/cs/quest/assertions/TestAll.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-assertions-test/src/test/java/de/ugoe/cs/quest/assertions/TestAll.java	(revision 540)
@@ -0,0 +1,27 @@
+package de.ugoe.cs.quest.assertions;
+
+import org.junit.runner.JUnitCore;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+/**
+ * The class <code>TestAll</code> builds a suite that can be used to run all
+ * of the tests within its package as well as within any subpackages of its
+ * package.
+ *
+ * @generatedBy CodePro at 12/21/11 11:53 AM
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+	FileEqualsReplayTest.class,
+	TextEqualsReplayTest.class,
+	AssertEventTest.class
+})
+public class TestAll {
+
+	public static void main(String[] args) {
+		JUnitCore.runClasses(new Class[] { TestAll.class });
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-assertions-test/src/test/java/de/ugoe/cs/quest/assertions/TextEqualsReplayTest.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-assertions-test/src/test/java/de/ugoe/cs/quest/assertions/TextEqualsReplayTest.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-assertions-test/src/test/java/de/ugoe/cs/quest/assertions/TextEqualsReplayTest.java	(revision 540)
@@ -0,0 +1,85 @@
+package de.ugoe.cs.quest.assertions;
+
+import org.junit.*;
+
+import de.ugoe.cs.quest.assertions.TextEqualsReplay;
+import static org.junit.Assert.*;
+
+/**
+ * The class <code>TextEqualsReplayTest</code> contains tests for the class
+ * <code>{@link TextEqualsReplay}</code>.
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class TextEqualsReplayTest {
+
+	private final static String ENDLINE = System.getProperty("line.separator");
+
+	@Test
+	public void testTextEqualsReplay_1() throws Exception {
+		String expectedValue = "expectedValueString";
+		String target = "targetString";
+
+		TextEqualsReplay result = new TextEqualsReplay(expectedValue, target);
+
+		assertNotNull(result);
+		assertEquals(expectedValue, result.expectedValue);
+		assertEquals(target, result.target);
+	}
+
+	@Test
+	public void testTextEqualsReplay_2() throws Exception {
+		String target = "targetString";
+
+		TextEqualsReplay result = new TextEqualsReplay(null, target);
+
+		assertNotNull(result);
+		assertEquals(null, result.expectedValue);
+		assertEquals(target, result.target);
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testTextEqualsReplay_3() throws Exception {
+		String expectedValue = "expectedValueString";
+
+		new TextEqualsReplay(expectedValue, null);
+	}
+
+	@Test
+	public void testGetReplay_1() throws Exception {
+		TextEqualsReplay fixture = new TextEqualsReplay("", "");
+
+		String result = fixture.getReplay();
+
+		assertEquals(" <textEquals expectedValue=\"\">" + ENDLINE + "<target>"
+				+ ENDLINE + ENDLINE + "</target>" + ENDLINE + "</textEquals>"
+				+ ENDLINE, result);
+	}
+
+	@Test
+	public void testGetReplay_2() throws Exception {
+		TextEqualsReplay fixture = new TextEqualsReplay("expectedValueString",
+				"targetString");
+
+		String result = fixture.getReplay();
+
+		assertEquals(" <textEquals expectedValue=\"expectedValueString\">"
+				+ ENDLINE + "<target>" + ENDLINE + "targetString" + ENDLINE
+				+ "</target>" + ENDLINE + "</textEquals>" + ENDLINE, result);
+	}
+
+	@Test
+	public void testGetTarget_1() throws Exception {
+		TextEqualsReplay fixture = new TextEqualsReplay("expectedValueString",
+				"targetString");
+
+		String result = fixture.getTarget();
+
+		assertEquals("targetString", result);
+	}
+
+	public static void main(String[] args) {
+		new org.junit.runner.JUnitCore().run(TextEqualsReplayTest.class);
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-assertions/.classpath
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-assertions/.classpath	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-assertions/.classpath	(revision 540)
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/classes" path="src/main/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
Index: /tags/quest-pre-eventrefactoring/quest-core-assertions/.project
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-assertions/.project	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-assertions/.project	(revision 540)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>quest-core-assertions</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
Index: /tags/quest-pre-eventrefactoring/quest-core-assertions/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-assertions/.settings/org.eclipse.jdt.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-assertions/.settings/org.eclipse.jdt.core.prefs	(revision 540)
@@ -0,0 +1,5 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.6
Index: /tags/quest-pre-eventrefactoring/quest-core-assertions/.settings/org.eclipse.m2e.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-assertions/.settings/org.eclipse.m2e.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-assertions/.settings/org.eclipse.m2e.core.prefs	(revision 540)
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
Index: /tags/quest-pre-eventrefactoring/quest-core-assertions/pom.xml
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-assertions/pom.xml	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-assertions/pom.xml	(revision 540)
@@ -0,0 +1,29 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>de.ugoe.cs.quest</groupId>
+  <artifactId>quest-core-assertions</artifactId>
+  <version>0.0.1-SNAPSHOT</version>
+  <name>quest-core-assertions</name>
+	<scm>
+		<url>https://quest.informatik.uni-goettingen.de/svn/quest/trunk/quest-core-assertions</url>
+	</scm>
+	<dependencies>
+		<dependency>
+			<groupId>de.ugoe.cs.quest</groupId>
+			<artifactId>quest-core-events</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+		</dependency>
+	</dependencies>
+	<build>
+		<plugins>
+			<plugin>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>2.3.2</version>
+				<configuration>
+					<source>1.6</source>
+					<target>1.6</target>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+</project>
Index: /tags/quest-pre-eventrefactoring/quest-core-assertions/src/main/java/de/ugoe/cs/quest/assertions/AssertEvent.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-assertions/src/main/java/de/ugoe/cs/quest/assertions/AssertEvent.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-assertions/src/main/java/de/ugoe/cs/quest/assertions/AssertEvent.java	(revision 540)
@@ -0,0 +1,41 @@
+package de.ugoe.cs.quest.assertions;
+
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.eventcore.IReplayable;
+import de.ugoe.cs.quest.eventcore.ReplayableEvent;
+
+/**
+ * <p>
+ * Subclass of {@link ReplayableEvent} for assertions
+ * </p>
+ * 
+ * @author Jeffrey Hall
+ * @version 1.0
+ * 
+ * @param <T>
+ *            Allows only types that extend {@link IReplayable} and is used to
+ *            define the type of the assertion.
+ * 
+ */
+public class AssertEvent<T extends IReplayable> extends ReplayableEvent<T> {
+
+	/**
+	 * <p>
+	 * Id for object serialization.
+	 * </p>
+	 */
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new event with the given type.
+	 * <p>
+	 * 
+	 * @param type
+	 *            type of the event
+	 * @see Event#Event(String)
+	 */
+	public AssertEvent(String type) {
+		super(type);
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-assertions/src/main/java/de/ugoe/cs/quest/assertions/FileEqualsReplay.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-assertions/src/main/java/de/ugoe/cs/quest/assertions/FileEqualsReplay.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-assertions/src/main/java/de/ugoe/cs/quest/assertions/FileEqualsReplay.java	(revision 540)
@@ -0,0 +1,91 @@
+package de.ugoe.cs.quest.assertions;
+
+import java.security.InvalidParameterException;
+
+import de.ugoe.cs.quest.eventcore.IReplayable;
+import de.ugoe.cs.util.StringTools;
+
+/**
+ * <p>
+ * This class defines the replay for file equals assertions.
+ * </p>
+ * 
+ * @author Jeffrey Hall, Steffen Herbold
+ * @version 2.0
+ */
+public class FileEqualsReplay implements IReplayable {
+
+	/**
+	 * <p>
+	 * The file that should be equal to expectedFile.
+	 * </p>
+	 */
+	protected final String actualFile;
+
+	/**
+	 * <p>
+	 * The file that is used as the reference.
+	 * </p>
+	 */
+	protected final String expectedFile;
+
+	/**
+	 * <p>
+	 * Id for object serialization.
+	 * </p>
+	 */
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new FileEqualsReplay.
+	 * </p>
+	 * 
+	 * @param expectedFile
+	 *            name and path of the expected file
+	 * @param actualFile
+	 *            name and path of the actual file
+	 * @throws InvalidParameterException
+	 *             thrown if expectedFile or actualFile are null
+	 */
+	public FileEqualsReplay(String expectedFile, String actualFile) {
+		if (expectedFile == null) {
+			throw new InvalidParameterException(
+					"expected file must not be null");
+		}
+		if (actualFile == null) {
+			throw new InvalidParameterException("actual file must not be null");
+		}
+		this.expectedFile = expectedFile;
+		this.actualFile = actualFile;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.eventcore.IReplayable#getReplay()
+	 */
+	public String getReplay() {
+
+		String actualFileTmp = StringTools.xmlEntityReplacement(actualFile);
+		String expectedFileTmp = StringTools.xmlEntityReplacement(expectedFile);
+
+		StringBuilder currentMsgStr = new StringBuilder(800);
+		currentMsgStr.append("  <fileEquals ");
+		currentMsgStr.append("actualFile=\"" + actualFileTmp + "\" ");
+		currentMsgStr.append("expectedFile=\"" + expectedFileTmp + "\"/>");
+		currentMsgStr.append(StringTools.ENDLINE);
+		return currentMsgStr.toString();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.eventcore.IReplayable#getTarget()
+	 */
+	@Override
+	public String getTarget() {
+		return "targetNotUsed";
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-assertions/src/main/java/de/ugoe/cs/quest/assertions/TextEqualsReplay.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-assertions/src/main/java/de/ugoe/cs/quest/assertions/TextEqualsReplay.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-assertions/src/main/java/de/ugoe/cs/quest/assertions/TextEqualsReplay.java	(revision 540)
@@ -0,0 +1,94 @@
+package de.ugoe.cs.quest.assertions;
+
+import java.security.InvalidParameterException;
+
+import de.ugoe.cs.quest.eventcore.IReplayable;
+import de.ugoe.cs.util.StringTools;
+
+/**
+ * <p>
+ * This class defines the replay for a textEquals assertion.
+ * </p>
+ * 
+ * @author Jeffrey Hall, Steffen Herbold
+ * @version 2.0
+ */
+public class TextEqualsReplay implements IReplayable {
+
+	/**
+	 * <p>
+	 * Reference value which is compared to the targets text.
+	 * </p>
+	 */
+	protected final String expectedValue;
+
+	/**
+	 * <p>
+	 * Target to which the text is compared.
+	 * </p>
+	 */
+	protected final String target;
+
+	/**
+	 * <p>
+	 * Id for object serialization.
+	 * </p>
+	 */
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new TextEqualsReplay.
+	 * 
+	 * @param expectedValue
+	 *            expected string value
+	 * @param target
+	 *            string description of the target whose string value is
+	 *            compared to the expected value
+	 * @throws InvalidParameterException
+	 *             thrown if target is null
+	 */
+	public TextEqualsReplay(String expectedValue, String target) {
+		if (target == null) {
+			throw new InvalidParameterException("target must not be null");
+		}
+		this.expectedValue = expectedValue;
+		this.target = target;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.eventcore.IReplayable#getReplay()
+	 */
+	@Override
+	public String getReplay() {
+
+		String expectedValueTmp = StringTools.xmlEntityReplacement(expectedValue);
+
+		StringBuilder currentMsgStr = new StringBuilder(400);
+		currentMsgStr.append(" <textEquals expectedValue=\"" + expectedValueTmp
+				+ "\">");
+		currentMsgStr.append(StringTools.ENDLINE);
+		currentMsgStr.append("<target>");
+		currentMsgStr.append(StringTools.ENDLINE);
+		currentMsgStr.append(target);
+		currentMsgStr.append(StringTools.ENDLINE);
+		currentMsgStr.append("</target>");
+		currentMsgStr.append(StringTools.ENDLINE);
+		currentMsgStr.append("</textEquals>");
+		currentMsgStr.append(StringTools.ENDLINE);
+		return currentMsgStr.toString();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.eventcore.IReplayable#getTarget()
+	 */
+	@Override
+	public String getTarget() {
+		return target;
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-coverage-test/.classpath
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-coverage-test/.classpath	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-coverage-test/.classpath	(revision 540)
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/test-classes" path="src/test/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="src" output="target/classes" path="src/main/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
Index: /tags/quest-pre-eventrefactoring/quest-core-coverage-test/.project
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-coverage-test/.project	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-coverage-test/.project	(revision 540)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>quest-core-coverage-test</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
Index: /tags/quest-pre-eventrefactoring/quest-core-coverage-test/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-coverage-test/.settings/org.eclipse.jdt.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-coverage-test/.settings/org.eclipse.jdt.core.prefs	(revision 540)
@@ -0,0 +1,5 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.6
Index: /tags/quest-pre-eventrefactoring/quest-core-coverage-test/.settings/org.eclipse.m2e.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-coverage-test/.settings/org.eclipse.m2e.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-coverage-test/.settings/org.eclipse.m2e.core.prefs	(revision 540)
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
Index: /tags/quest-pre-eventrefactoring/quest-core-coverage-test/pom.xml
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-coverage-test/pom.xml	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-coverage-test/pom.xml	(revision 540)
@@ -0,0 +1,151 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>de.ugoe.cs.quest</groupId>
+  <artifactId>quest-core-coverage-test</artifactId>
+  <version>0.0.1-SNAPSHOT</version>
+  <name>quest-core-coverage-test</name>
+<scm>
+    <url>https://quest.informatik.uni-goettingen.de/svn/quest/trunk/quest-core-events-test</url>
+  </scm>
+  <dependencies>
+    <dependency>
+        <groupId>de.ugoe.cs.quest</groupId>
+        <artifactId>quest-core-events</artifactId>
+        <version>0.0.1-SNAPSHOT</version>
+        <scope>test</scope>
+    </dependency>
+    <dependency>
+			<groupId>de.ugoe.cs.quest</groupId>
+			<artifactId>quest-core-usageprofiles-test</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+			<type>test-jar</type>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>de.ugoe.cs.quest</groupId>
+			<artifactId>quest-core-coverage</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+			<scope>test</scope>
+		</dependency>
+    <dependency>
+        <groupId>junit</groupId>
+        <artifactId>junit</artifactId>
+        <version>4.8.1</version>
+        <scope>test</scope>
+    </dependency>
+    <!-- <dependency>
+	  <groupId>junit-addons</groupId>
+	  <artifactId>junit-addons</artifactId>
+	  <version>1.4</version>
+    </dependency>
+    <dependency>
+	  <groupId>nl.jqno.equalsverifier</groupId>
+	  <artifactId>equalsverifier</artifactId>
+	  <version>1.1.3</version>
+    </dependency>-->
+  </dependencies>
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.eclipse.m2e</groupId>
+          <artifactId>lifecycle-mapping</artifactId>
+          <version>1.0.0</version>
+          <configuration>
+            <lifecycleMappingMetadata>
+              <pluginExecutions>
+                <pluginExecution>
+                  <pluginExecutionFilter>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-dependency-plugin</artifactId>
+                    <versionRange>[1.0.0,)</versionRange>
+                    <goals>
+                      <goal>unpack</goal>
+                    </goals>
+                  </pluginExecutionFilter>
+                  <action>
+                    <ignore/>
+                  </action>
+                </pluginExecution>
+                <pluginExecution>
+                  <pluginExecutionFilter>
+                    <groupId>org.codehaus.mojo</groupId>
+                    <artifactId>emma-maven-plugin</artifactId>
+                    <versionRange>[1.0-alpha-3,)</versionRange>
+                    <goals>
+                      <goal>emma</goal>
+                    </goals>
+                  </pluginExecutionFilter>
+                  <action>
+                    <ignore/>
+                  </action>
+                </pluginExecution>
+              </pluginExecutions>
+            </lifecycleMappingMetadata>
+          </configuration>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>2.3.2</version>
+        <configuration>
+          <source>1.6</source>
+          <target>1.6</target>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-dependency-plugin</artifactId>
+        <version>2.4</version>
+        <executions>
+          <execution>
+            <id>unpack</id>
+            <phase>process-classes</phase>
+            <goals>
+              <goal>unpack</goal>
+            </goals>
+            <configuration>
+              <artifactItems>
+                <artifactItem>
+                  <groupId>de.ugoe.cs.quest</groupId>
+                  <artifactId>quest-core-coverage</artifactId>
+                  <version>0.0.1-SNAPSHOT</version>
+                  <outputDirectory>${project.build.directory}/classes</outputDirectory>
+                </artifactItem>
+              </artifactItems>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>emma-maven-plugin</artifactId>
+        <version>1.0-alpha-3</version>
+        <inherited>true</inherited>          
+        <executions>
+          <execution>
+            <phase>process-classes</phase>
+            <goals>
+              <goal>emma</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <version>2.3.2</version>
+        <executions>
+          <execution>
+            <goals>
+              <goal>test-jar</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>
Index: /tags/quest-pre-eventrefactoring/quest-core-coverage-test/src/test/java/de/ugoe/cs/quest/coverage/CoverageCalculatorObservedTest.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-coverage-test/src/test/java/de/ugoe/cs/quest/coverage/CoverageCalculatorObservedTest.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-coverage-test/src/test/java/de/ugoe/cs/quest/coverage/CoverageCalculatorObservedTest.java	(revision 540)
@@ -0,0 +1,313 @@
+package de.ugoe.cs.quest.coverage;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import de.ugoe.cs.quest.coverage.CoverageCalculatorObserved;
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.usageprofiles.MockTrieBasedModel;
+
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Random;
+import java.util.Set;
+
+import org.junit.*;
+
+import static org.junit.Assert.*;
+
+/**
+ * The class <code>CoverageCalculatorObservedTest</code> contains tests for the
+ * class <code>{@link CoverageCalculatorObserved}</code>.
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CoverageCalculatorObservedTest {
+	
+	Collection<List<? extends Event<?>>> sequencesObserved;
+	
+	Set<List<? extends Event<?>>> sequencesCovered;
+	Set<List<? extends Event<?>>> sequencesCovered2;
+	Set<List<? extends Event<?>>> sequencesNewPossible;
+	
+	MockTrieBasedModel mockProcess;
+	
+	@Test
+	public void testCoverageCalculatorObserved_1() throws Exception {
+		int length = 2;
+
+		CoverageCalculatorObserved result = new CoverageCalculatorObserved(
+				sequencesObserved, sequencesCovered, length);
+		assertNotNull(result);
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testCoverageCalculatorObserved_2() throws Exception {
+		int length = 2;
+
+		new CoverageCalculatorObserved(null,sequencesCovered, length);
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testCoverageCalculatorObserved_3() throws Exception {
+		int length = 2;
+
+		new CoverageCalculatorObserved(sequencesObserved, null, length);
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testCoverageCalculatorObserved_4() throws Exception {
+		int length = 0;
+
+		new CoverageCalculatorObserved(sequencesObserved, sequencesCovered, length);
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testCoverageCalculatorObserved_5() throws Exception {
+		int length = -1;
+
+		new CoverageCalculatorObserved(sequencesObserved, sequencesCovered, length);
+	}
+	
+	@Test
+	public void testCoverageObserved_1() throws Exception {
+		int length = 2;
+		CoverageCalculatorObserved fixture = new CoverageCalculatorObserved(
+				sequencesObserved, sequencesCovered, length);
+		
+		double result = fixture.getCoverageObserved();
+		
+		assertEquals(3.0/6.0, result, 0.0001);
+	}
+	
+	@Test
+	public void testCoverageObserved_2() throws Exception {
+		int length = 2;
+		CoverageCalculatorObserved fixture = new CoverageCalculatorObserved(
+				sequencesObserved, sequencesCovered2, length);
+		
+		double result = fixture.getCoverageObserved();
+		
+		assertEquals(2.0/6.0, result, 0.0001);
+	}
+	
+	@Test
+	public void testCoverageObservedWeigth_1() throws Exception {
+		int length = 2;
+		CoverageCalculatorObserved fixture = new CoverageCalculatorObserved(
+				sequencesObserved, sequencesCovered, length);
+		
+		double result = fixture.getCoverageObservedWeigth(mockProcess);
+		
+		assertEquals(6.0, result, 0.0001);
+	}
+	
+	@Test
+	public void testCoverageObservedWeigth_2() throws Exception {
+		int length = 2;
+		CoverageCalculatorObserved fixture = new CoverageCalculatorObserved(
+				sequencesObserved, sequencesCovered2, length);
+		
+		double result = fixture.getCoverageObservedWeigth(mockProcess);
+		
+		assertEquals(4.0, result, 0.0001);
+	}
+	
+	@Test
+	public void testGetNewPercentage_1() throws Exception {
+		int length = 2;
+		CoverageCalculatorObserved fixture = new CoverageCalculatorObserved(
+				sequencesObserved, sequencesCovered, length);
+		
+		double result = fixture.getNewPercentage();
+		
+		assertEquals(1.0/4.0, result, 0.0001);
+	}
+	
+	@Test
+	public void testGetNewPercentage_2() throws Exception {
+		int length = 2;
+		CoverageCalculatorObserved fixture = new CoverageCalculatorObserved(
+				sequencesObserved, sequencesCovered2, length);
+		
+		double result = fixture.getNewPercentage();
+		
+		assertEquals(0.0, result, 0.0001);
+	}
+	
+	@Test
+	public void testCoveragePossibleNew_1() throws Exception {
+		int length = 3;
+		CoverageCalculatorObserved fixture = new CoverageCalculatorObserved(
+				sequencesObserved, sequencesNewPossible, length);
+		
+		double result = fixture.getCoveragePossibleNew(mockProcess);
+		
+		assertEquals(1.0/11.0, result, 0.0001);
+	}
+	
+	@Test
+	public void testCoveragePossibleNew_2() throws Exception {
+		int length = 2;
+		CoverageCalculatorObserved fixture = new CoverageCalculatorObserved(
+				sequencesObserved, sequencesCovered, length);
+		
+		double result = fixture.getCoveragePossibleNew(mockProcess);
+		
+		assertEquals(0.0, result, 0.0001);
+	}
+	
+	@Test(expected = java.security.InvalidParameterException.class ) 
+	public void testCoveragePossibleNew_3() throws Exception {
+		int length = 3;
+		CoverageCalculatorObserved fixture = new CoverageCalculatorObserved(
+				sequencesObserved, sequencesCovered, length);
+		
+		fixture.getCoveragePossibleNew(null);
+	}
+	
+	@Test
+	public void testCoveragePossibleNewWeight_1() throws Exception {
+		int length = 3;
+		CoverageCalculatorObserved fixture = new CoverageCalculatorObserved(
+				sequencesObserved, sequencesNewPossible, length);
+		
+		double result = fixture.getCoveragePossibleNewWeight(mockProcess);
+		
+		assertEquals(2.0, result, 0.0001);
+	}
+	
+	@Test
+	public void testCoveragePossibleNewWeight_2() throws Exception {
+		int length = 2;
+		CoverageCalculatorObserved fixture = new CoverageCalculatorObserved(
+				sequencesObserved, sequencesCovered, length);
+		
+		double result = fixture.getCoveragePossibleNewWeight(mockProcess);
+		
+		assertEquals(0.0, result, 0.0001);
+	}
+	
+	@Test(expected = java.security.InvalidParameterException.class ) 
+	public void testCoveragePossibleNewWeight_3() throws Exception {
+		int length = 3;
+		CoverageCalculatorObserved fixture = new CoverageCalculatorObserved(
+				sequencesObserved, sequencesCovered, length);
+		
+		fixture.getCoveragePossibleNewWeight(null);
+	}	
+	
+	
+	@Test
+	public void testGetNumObserved_1() throws Exception {
+		int length = 2;
+		CoverageCalculatorObserved fixture = new CoverageCalculatorObserved(
+				sequencesObserved, sequencesCovered, length);
+		
+		int result = fixture.getNumObserved();
+		
+		assertEquals(6, result);
+	}
+	
+	@Test
+	public void testGetNumCovered_1() throws Exception {
+		int length = 2;
+		CoverageCalculatorObserved fixture = new CoverageCalculatorObserved(
+				sequencesObserved, sequencesCovered, length);
+		
+		int result = fixture.getNumCovered();
+		
+		assertEquals(4, result);
+	}
+	
+	@Test
+	public void testGetNumCovered_2() throws Exception {
+		int length = 2;
+		CoverageCalculatorObserved fixture = new CoverageCalculatorObserved(
+				sequencesObserved, sequencesCovered2, length);
+		
+		int result = fixture.getNumCovered();
+		
+		assertEquals(2, result);
+	}
+	
+	@Test
+	public void testGetNumNew_1() throws Exception {
+		int length = 2;
+		CoverageCalculatorObserved fixture = new CoverageCalculatorObserved(
+				sequencesObserved, sequencesCovered, length);
+		
+		int result = fixture.getNumNew();
+		
+		assertEquals(1, result);
+	}
+	
+	@Test
+	public void testGetNumNew_2() throws Exception {
+		int length = 2;
+		CoverageCalculatorObserved fixture = new CoverageCalculatorObserved(
+				sequencesObserved, sequencesCovered2, length);
+		
+		int result = fixture.getNumNew();
+		
+		assertEquals(0, result);
+	}
+	
+	@Before
+	public void setUp() throws Exception {
+		sequencesObserved = new LinkedList<List<? extends Event<?>>>();
+		List<Event<?>> sequence1 = new ArrayList<Event<?>>();
+		sequence1.add(new Event<String>("a"));
+		sequence1.add(new Event<String>("b"));
+		sequence1.add(new Event<String>("r"));
+		sequence1.add(new Event<String>("a"));
+		List<Event<?>> sequence2 = new ArrayList<Event<?>>();
+		sequence2.add(new Event<String>("c"));
+		sequence2.add(new Event<String>("a"));
+		sequence2.add(new Event<String>("d"));
+		sequence2.add(new Event<String>("a"));
+		sequence2.add(new Event<String>("b"));
+		sequence2.add(new Event<String>("r"));
+		sequence2.add(new Event<String>("a"));
+		sequencesObserved.add(sequence1);
+		sequencesObserved.add(sequence2);
+
+		sequencesCovered = new LinkedHashSet<List<? extends Event<?>>>();
+		List<Event<?>> tmpList = new ArrayList<Event<?>>();
+		tmpList.add(new Event<String>("a"));
+		tmpList.add(new Event<String>("b"));
+		tmpList.add(new Event<String>("r"));
+		sequencesCovered.add(tmpList);
+		tmpList = new ArrayList<Event<?>>();
+		tmpList.add(new Event<String>("b"));
+		tmpList.add(new Event<String>("r"));
+		tmpList.add(new Event<String>("a"));
+		tmpList.add(new Event<String>("e"));
+		sequencesCovered.add(tmpList);
+
+		sequencesCovered2 = new LinkedHashSet<List<? extends Event<?>>>();
+		tmpList = new ArrayList<Event<?>>();
+		tmpList.add(new Event<String>("a"));
+		tmpList.add(new Event<String>("b"));
+		tmpList.add(new Event<String>("r"));
+		sequencesCovered2.add(tmpList);
+		
+		sequencesNewPossible = new LinkedHashSet<List<? extends Event<?>>>();
+		tmpList = new ArrayList<Event<?>>();
+		tmpList.add(new Event<String>("r"));
+		tmpList.add(new Event<String>("a"));
+		tmpList.add(new Event<String>("b"));
+		sequencesNewPossible.add(tmpList);
+		
+		int markovOrder = 2;
+		mockProcess = new MockTrieBasedModel(markovOrder, new Random());
+		mockProcess.train(sequencesObserved);
+	}
+
+	public static void main(String[] args) {
+		new org.junit.runner.JUnitCore()
+				.run(CoverageCalculatorObservedTest.class);
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-coverage-test/src/test/java/de/ugoe/cs/quest/coverage/CoverageCalculatorProcessTest.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-coverage-test/src/test/java/de/ugoe/cs/quest/coverage/CoverageCalculatorProcessTest.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-coverage-test/src/test/java/de/ugoe/cs/quest/coverage/CoverageCalculatorProcessTest.java	(revision 540)
@@ -0,0 +1,236 @@
+package de.ugoe.cs.quest.coverage;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Random;
+import java.util.Set;
+import de.ugoe.cs.quest.coverage.CoverageCalculatorProcess;
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.usageprofiles.MockTrieBasedModel;
+
+import org.junit.*;
+
+import static org.junit.Assert.*;
+
+/**
+ * The class <code>CoverageCalculatorProcessTest</code> contains tests for the
+ * class <code>{@link CoverageCalculatorProcess}</code>.
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CoverageCalculatorProcessTest {
+
+	Set<List<? extends Event<?>>> sequencesCovered;
+	Set<List<? extends Event<?>>> sequencesCovered2;
+	MockTrieBasedModel mockProcess;
+
+	@Test
+	public void testCoverageCalculatorProcess_1() throws Exception {
+		int length = 2;
+
+		CoverageCalculatorProcess result = new CoverageCalculatorProcess(
+				mockProcess, sequencesCovered, length);
+		assertNotNull(result);
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testCoverageCalculatorProcess_2() throws Exception {
+		int length = 2;
+
+		new CoverageCalculatorProcess(null,sequencesCovered, length);
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testCoverageCalculatorProcess_3() throws Exception {
+		int length = 2;
+
+		new CoverageCalculatorProcess(mockProcess, null, length);
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testCoverageCalculatorProcess_4() throws Exception {
+		int length = 0;
+
+		new CoverageCalculatorProcess(mockProcess, sequencesCovered, length);
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testCoverageCalculatorProcess_5() throws Exception {
+		int length = -1;
+
+		new CoverageCalculatorProcess(mockProcess, sequencesCovered, length);
+	}
+
+	@Test
+	public void testGetCoverageAllNoWeight_1() throws Exception {
+		int length = 2;
+		CoverageCalculatorProcess fixture = new CoverageCalculatorProcess(
+				mockProcess, sequencesCovered, length);
+
+		double result = fixture.getCoverageAllNoWeight();
+
+		assertEquals(3.0 / 49.0, result, 0.0001);
+	}
+
+	@Test
+	public void testGetCoverageAllNoWeight_2() throws Exception {
+		int length = 2;
+		CoverageCalculatorProcess fixture = new CoverageCalculatorProcess(
+				mockProcess, sequencesCovered2, length);
+
+		double result = fixture.getCoverageAllNoWeight();
+
+		assertEquals(2.0 / 49.0, result, 0.0001);
+	}
+
+	@Test
+	public void testGetCoveragePossibleNoWeight_1() throws Exception {
+		int length = 2;
+		CoverageCalculatorProcess fixture = new CoverageCalculatorProcess(
+				mockProcess, sequencesCovered, length);
+
+		double result = fixture.getCoveragePossibleNoWeight();
+
+		assertEquals(3.0 / 9.0, result, 0.0001);
+	}
+
+	@Test
+	public void testGetCoveragePossibleNoWeight_2() throws Exception {
+		int length = 2;
+		CoverageCalculatorProcess fixture = new CoverageCalculatorProcess(
+				mockProcess, sequencesCovered2, length);
+
+		double result = fixture.getCoveragePossibleNoWeight();
+
+		assertEquals(2.0 / 9.0, result, 0.0001);
+	}
+
+	@Test
+	public void testGetCoveragePossibleWeight_1() throws Exception {
+		int length = 2;
+		CoverageCalculatorProcess fixture = new CoverageCalculatorProcess(
+				mockProcess, sequencesCovered, length);
+
+		double result = fixture.getCoveragePossibleWeight();
+
+		assertEquals(6.0, result, 0.0001);
+	}
+
+	@Test
+	public void testGetCoveragePossibleWeight_2() throws Exception {
+		int length = 2;
+		CoverageCalculatorProcess fixture = new CoverageCalculatorProcess(
+				mockProcess, sequencesCovered2, length);
+
+		double result = fixture.getCoveragePossibleWeight();
+
+		assertEquals(4.0, result, 0.0001);
+	}
+
+	@Test
+	public void testGetNumCovered_1() throws Exception {
+		int length = 2;
+		CoverageCalculatorProcess fixture = new CoverageCalculatorProcess(
+				mockProcess, sequencesCovered, length);
+
+		int result = fixture.getNumCovered();
+
+		assertEquals(3, result);
+	}
+
+	@Test
+	public void testGetNumCovered_2() throws Exception {
+		int length = 2;
+		CoverageCalculatorProcess fixture = new CoverageCalculatorProcess(
+				mockProcess, sequencesCovered2, length);
+
+		int result = fixture.getNumCovered();
+
+		assertEquals(2, result);
+	}
+
+	@Test
+	public void testGetNumPossible_1() throws Exception {
+		int length = 2;
+		CoverageCalculatorProcess fixture = new CoverageCalculatorProcess(
+				mockProcess, sequencesCovered, length);
+
+		int result = fixture.getNumPossible();
+
+		assertEquals(9, result);
+	}
+
+	@Test
+	public void testSetSequences_1() throws Exception {
+		int length = 2;
+		CoverageCalculatorProcess fixture = new CoverageCalculatorProcess(
+				mockProcess, sequencesCovered, length);
+
+		fixture.setSequences(sequencesCovered2);
+
+		// testing indirectly if sequences were changed
+		assertEquals(2, fixture.getNumCovered());
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testSetSequences_2() throws Exception {
+		int length = 2;
+		CoverageCalculatorProcess fixture = new CoverageCalculatorProcess(
+				mockProcess, sequencesCovered, length);
+
+		fixture.setSequences(null);
+	}
+
+	@Before
+	public void setUp() throws Exception {
+		Collection<List<? extends Event<?>>> sequences = new LinkedList<List<? extends Event<?>>>();
+		List<Event<?>> sequence1 = new ArrayList<Event<?>>();
+		sequence1.add(new Event<String>("a"));
+		sequence1.add(new Event<String>("b"));
+		sequence1.add(new Event<String>("r"));
+		sequence1.add(new Event<String>("a"));
+		List<Event<?>> sequence2 = new ArrayList<Event<?>>();
+		sequence2.add(new Event<String>("c"));
+		sequence2.add(new Event<String>("a"));
+		sequence2.add(new Event<String>("d"));
+		sequence2.add(new Event<String>("a"));
+		sequence2.add(new Event<String>("b"));
+		sequence2.add(new Event<String>("r"));
+		sequence2.add(new Event<String>("a"));
+		sequences.add(sequence1);
+		sequences.add(sequence2);
+
+		sequencesCovered = new LinkedHashSet<List<? extends Event<?>>>();
+		List<Event<?>> tmpList = new ArrayList<Event<?>>();
+		tmpList.add(new Event<String>("a"));
+		tmpList.add(new Event<String>("b"));
+		tmpList.add(new Event<String>("r"));
+		sequencesCovered.add(tmpList);
+		tmpList = new ArrayList<Event<?>>();
+		tmpList.add(new Event<String>("b"));
+		tmpList.add(new Event<String>("r"));
+		tmpList.add(new Event<String>("a"));
+		sequencesCovered.add(tmpList);
+
+		sequencesCovered2 = new LinkedHashSet<List<? extends Event<?>>>();
+		tmpList = new ArrayList<Event<?>>();
+		tmpList.add(new Event<String>("a"));
+		tmpList.add(new Event<String>("b"));
+		tmpList.add(new Event<String>("r"));
+		sequencesCovered2.add(tmpList);
+
+		int markovOrder = 2;
+		mockProcess = new MockTrieBasedModel(markovOrder, new Random());
+		mockProcess.train(sequences);
+	}
+
+	public static void main(String[] args) {
+		new org.junit.runner.JUnitCore()
+				.run(CoverageCalculatorProcessTest.class);
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-coverage-test/src/test/java/de/ugoe/cs/quest/coverage/SequenceToolsTest.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-coverage-test/src/test/java/de/ugoe/cs/quest/coverage/SequenceToolsTest.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-coverage-test/src/test/java/de/ugoe/cs/quest/coverage/SequenceToolsTest.java	(revision 540)
@@ -0,0 +1,201 @@
+package de.ugoe.cs.quest.coverage;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Random;
+import java.util.Set;
+import de.ugoe.cs.quest.coverage.SequenceTools;
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.usageprofiles.FirstOrderMarkovModel;
+import de.ugoe.cs.quest.usageprofiles.IStochasticProcess;
+import de.ugoe.cs.quest.usageprofiles.MockTrieBasedModel;
+
+import org.junit.*;
+
+import static org.junit.Assert.*;
+
+/**
+ * The class <code>SequenceToolsTest</code> contains tests for the class <code>{@link SequenceTools}</code>.
+ *
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class SequenceToolsTest {
+	
+	Collection<List<? extends Event<?>>> sequences;
+	Set<List<? extends Event<?>>> subSequences;
+	MockTrieBasedModel mockProcess;
+	
+	@Test
+	public void testContainedSubSequences_1()
+		throws Exception {
+		int length = 2;
+
+		Set<List<? extends Event<?>>> result = SequenceTools.containedSubSequences(sequences, length);
+
+		assertNotNull(result);
+		assertTrue(result.containsAll(subSequences));
+		assertEquals(subSequences.size(), result.size());
+	}
+	
+	@Test
+	public void testContainedSubSequences_2()
+		throws Exception {
+		int length = 2;
+
+		Set<List<? extends Event<?>>> result = SequenceTools.containedSubSequences(null, length);
+		assertNotNull(result);
+		assertTrue(result.isEmpty());
+	}
+	
+	@Test(expected=java.security.InvalidParameterException.class)
+	public void testContainedSubSequences_3()
+		throws Exception {
+		int length = 0;
+
+		SequenceTools.containedSubSequences(sequences, length);
+	}
+	
+	@Test(expected=java.security.InvalidParameterException.class)
+	public void testContainedSubSequences_4()
+		throws Exception {
+		int length = -1;
+
+		SequenceTools.containedSubSequences(sequences, length);
+	}
+
+	@Test
+	public void testGenerateWeights_1()
+		throws Exception {
+		Map<List<? extends Event<?>>, Double> result = SequenceTools.generateWeights(mockProcess, subSequences);
+
+		assertNotNull(result);
+		Set<Entry<List<? extends Event<?>>, Double>> entrySet = result.entrySet();
+		assertEquals(subSequences.size(),entrySet.size());
+		for( Entry<List<? extends Event<?>>, Double> entry : entrySet ) {
+			assertEquals(Double.valueOf(2.0d), entry.getValue());
+			assertTrue(subSequences.contains(entry.getKey()));
+		}
+	}
+	
+	@Test
+	public void testGenerateWeights_2()
+		throws Exception {
+		Map<List<? extends Event<?>>, Double> result = SequenceTools.generateWeights(null, subSequences);
+		
+		Set<Entry<List<? extends Event<?>>, Double>> entrySet = result.entrySet();
+		assertEquals(subSequences.size(),entrySet.size());
+		for( Entry<List<? extends Event<?>>, Double> entry : entrySet ) {
+			assertEquals(Double.valueOf(0.0d), entry.getValue());
+			assertTrue(subSequences.contains(entry.getKey()));
+		}
+	}
+	
+	@Test
+	public void testGenerateWeights_3()
+		throws Exception {
+		Map<List<? extends Event<?>>, Double> result = SequenceTools.generateWeights(mockProcess, null);
+		
+		assertNotNull(result);
+		assertTrue(result.isEmpty());
+	}
+
+	@Test
+	public void testNumSequences_1()
+		throws Exception {
+		int length = 2;
+		int expected = 49;
+
+		long result = SequenceTools.numSequences(mockProcess, length);
+
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testNumSequences_2()
+		throws Exception {
+		int length = 2;
+		int expected = 49;
+
+		long result = SequenceTools.numSequences(mockProcess, length);
+
+		assertEquals(expected, result);
+	}
+	
+	@Test(expected = java.security.InvalidParameterException.class )
+	public void testNumSequences_3()
+		throws Exception {
+		int length = 0;
+
+		SequenceTools.numSequences(mockProcess, length);
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class )
+	public void testNumSequences_4()
+		throws Exception {
+		IStochasticProcess process = new FirstOrderMarkovModel(new Random());
+		int length = -1;
+
+		SequenceTools.numSequences(process, length);
+	}
+	
+	@Before
+	public void setUp()
+		throws Exception {
+		sequences = new LinkedList<List<? extends Event<?>>>();
+		List<Event<?>> sequence1 = new ArrayList<Event<?>>();
+		sequence1.add(new Event<String>("a"));
+		sequence1.add(new Event<String>("b"));
+		sequence1.add(new Event<String>("r"));
+		sequence1.add(new Event<String>("a"));
+		List<Event<?>> sequence2 = new ArrayList<Event<?>>();
+		sequence2.add(new Event<String>("c"));
+		sequence2.add(new Event<String>("a"));
+		sequence2.add(new Event<String>("d"));
+		sequence2.add(new Event<String>("a"));
+		sequence2.add(new Event<String>("b"));
+		sequence2.add(new Event<String>("r"));
+		sequence2.add(new Event<String>("a"));
+		sequences.add(sequence1);
+		sequences.add(sequence2);
+		
+		subSequences = new LinkedHashSet<List<? extends Event<?>>>();
+		List<Event<?>> tmpList = new ArrayList<Event<?>>();
+		tmpList.add(new Event<String>("a"));
+		tmpList.add(new Event<String>("b"));
+		subSequences.add(tmpList);
+		tmpList = new ArrayList<Event<?>>();
+		tmpList.add(new Event<String>("b"));
+		tmpList.add(new Event<String>("r"));
+		subSequences.add(tmpList);
+		tmpList = new ArrayList<Event<?>>();
+		tmpList.add(new Event<String>("r"));
+		tmpList.add(new Event<String>("a"));
+		subSequences.add(tmpList);
+		tmpList = new ArrayList<Event<?>>();
+		tmpList.add(new Event<String>("c"));
+		tmpList.add(new Event<String>("a"));
+		subSequences.add(tmpList);
+		tmpList = new ArrayList<Event<?>>();
+		tmpList.add(new Event<String>("a"));
+		tmpList.add(new Event<String>("d"));
+		subSequences.add(tmpList);
+		tmpList = new ArrayList<Event<?>>();
+		tmpList.add(new Event<String>("d"));
+		tmpList.add(new Event<String>("a"));
+		subSequences.add(tmpList);
+		
+		int markovOrder = 2;
+		mockProcess = new MockTrieBasedModel(markovOrder, new Random());
+		mockProcess.train(sequences);
+	}
+
+	public static void main(String[] args) {
+		new org.junit.runner.JUnitCore().run(SequenceToolsTest.class);
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-coverage-test/src/test/java/de/ugoe/cs/quest/coverage/TestAll.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-coverage-test/src/test/java/de/ugoe/cs/quest/coverage/TestAll.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-coverage-test/src/test/java/de/ugoe/cs/quest/coverage/TestAll.java	(revision 540)
@@ -0,0 +1,26 @@
+package de.ugoe.cs.quest.coverage;
+
+import org.junit.runner.JUnitCore;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+/**
+ * The class <code>TestAll</code> builds a suite that can be used to run all
+ * of the tests within its package as well as within any subpackages of its
+ * package.
+ *
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+	CoverageCalculatorObservedTest.class,
+	CoverageCalculatorProcessTest.class,
+	SequenceToolsTest.class
+})
+public class TestAll {
+
+	public static void main(String[] args) {
+		JUnitCore.runClasses(new Class[] { TestAll.class });
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-coverage/.classpath
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-coverage/.classpath	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-coverage/.classpath	(revision 540)
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/classes" path="src/main/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
Index: /tags/quest-pre-eventrefactoring/quest-core-coverage/.project
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-coverage/.project	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-coverage/.project	(revision 540)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>quest-core-coverage</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
Index: /tags/quest-pre-eventrefactoring/quest-core-coverage/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-coverage/.settings/org.eclipse.jdt.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-coverage/.settings/org.eclipse.jdt.core.prefs	(revision 540)
@@ -0,0 +1,5 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.6
Index: /tags/quest-pre-eventrefactoring/quest-core-coverage/.settings/org.eclipse.m2e.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-coverage/.settings/org.eclipse.m2e.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-coverage/.settings/org.eclipse.m2e.core.prefs	(revision 540)
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
Index: /tags/quest-pre-eventrefactoring/quest-core-coverage/pom.xml
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-coverage/pom.xml	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-coverage/pom.xml	(revision 540)
@@ -0,0 +1,34 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>de.ugoe.cs.quest</groupId>
+  <artifactId>quest-core-coverage</artifactId>
+  <version>0.0.1-SNAPSHOT</version>
+  <name>quest-core-coverage</name>
+  <scm>
+		<url>https://quest.informatik.uni-goettingen.de/svn/quest/trunk/quest-core-coverage</url>
+	</scm>
+  	<dependencies>
+		<dependency>
+			<groupId>de.ugoe.cs.quest</groupId>
+			<artifactId>quest-core-events</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+		</dependency>
+		<dependency>
+			<groupId>de.ugoe.cs.quest</groupId>
+			<artifactId>quest-core-usageprofiles</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+		</dependency>
+	</dependencies>
+	<build>
+		<plugins>
+			<plugin>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>2.3.2</version>
+				<configuration>
+					<source>1.6</source>
+					<target>1.6</target>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+</project>
Index: /tags/quest-pre-eventrefactoring/quest-core-coverage/src/main/java/de/ugoe/cs/quest/coverage/CoverageCalculatorObserved.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-coverage/src/main/java/de/ugoe/cs/quest/coverage/CoverageCalculatorObserved.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-coverage/src/main/java/de/ugoe/cs/quest/coverage/CoverageCalculatorObserved.java	(revision 540)
@@ -0,0 +1,272 @@
+package de.ugoe.cs.quest.coverage;
+
+import java.security.InvalidParameterException;
+import java.util.Collection;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.usageprofiles.IStochasticProcess;
+
+/**
+ * <p>
+ * This class calculates various types of sequence coverage in relation to a
+ * collection of observed sequences.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CoverageCalculatorObserved {
+
+	/**
+	 * <p>
+	 * Sequences for which the coverage is calculated.
+	 * </p>
+	 */
+	private final Collection<List<? extends Event<?>>> sequences;
+
+	/**
+	 * <p>
+	 * Observed sequences that are baseline for the coverage calculation.
+	 * </p>
+	 */
+	private final Collection<List<? extends Event<?>>> observedSequences;
+
+	/**
+	 * <p>
+	 * Length of the subsequences in relation to which the covarage is
+	 * calculated.
+	 * </p>
+	 */
+	private final int length;
+
+	/**
+	 * <p>
+	 * All subsequences of {@link #length} of {@link #sequences}.
+	 * </p>
+	 */
+	private Collection<List<? extends Event<?>>> subSeqsGenerated = null;
+
+	/**
+	 * <p>
+	 * All subsequences of {@link #length} of {@link #observedSequences}.
+	 * </p>
+	 */
+	private Collection<List<? extends Event<?>>> subSeqsObserved = null;
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new CoverageCalculatorObserved for given
+	 * collections of observed sequences and generated sequences.
+	 * </p>
+	 * 
+	 * @param observedSequences
+	 *            observed sequences in relation to which the coverage is
+	 *            calculated; must not be null
+	 * @param sequences
+	 *            sequences for which the coverage is calculated; must not be
+	 *            null
+	 * @param length
+	 *            length of the subsequences for which the coverage is analyzed;
+	 *            must be >0
+	 * @throws InvalidParameterException
+	 *             thrown if observedSequences or sequences is null or length
+	 *             less than or equal to 0
+	 */
+	public CoverageCalculatorObserved(
+			Collection<List<? extends Event<?>>> observedSequences,
+			Collection<List<? extends Event<?>>> sequences, int length) {
+		if (observedSequences == null) {
+			throw new InvalidParameterException(
+					"observed sequences must not be null");
+		}
+		if (sequences == null) {
+			throw new InvalidParameterException("sequences must not be null");
+		}
+		if (length <= 0) {
+			throw new InvalidParameterException(
+					"length must be >0; actual value: " + length);
+		}
+		this.observedSequences = observedSequences;
+		this.sequences = sequences;
+		this.length = length;
+	}
+
+	/**
+	 * <p>
+	 * Calculates the percentage of subsequences of length k that occur, with
+	 * reference to those that were observed.
+	 * </p>
+	 * 
+	 * @return coverage percentage
+	 */
+	public double getCoverageObserved() {
+		createSubSeqs();
+		Collection<List<? extends Event<?>>> subSeqsObservedCopy = new LinkedHashSet<List<? extends Event<?>>>(
+				subSeqsObserved);
+		subSeqsObservedCopy.retainAll(subSeqsGenerated);
+		return ((double) subSeqsObservedCopy.size()) / subSeqsObserved.size();
+	}
+
+	/**
+	 * <p>
+	 * Calculates the weight of subsequences of length k that occur, with
+	 * reference to those that were observed.
+	 * </p>
+	 * 
+	 * @param process
+	 *            stochastic process in reference to which the weight is
+	 *            calculated
+	 * @return coverage percentage
+	 */
+
+	public double getCoverageObservedWeigth(IStochasticProcess process) {
+		createSubSeqs();
+		Map<List<? extends Event<?>>, Double> weightMap = SequenceTools
+				.generateWeights(process, subSeqsObserved);
+
+		Collection<List<? extends Event<?>>> subSeqsObservedCopy = new LinkedHashSet<List<? extends Event<?>>>(
+				subSeqsObserved);
+		subSeqsObservedCopy.retainAll(subSeqsGenerated);
+		double weight = 0.0d;
+		for (List<? extends Event<?>> subSeq : subSeqsObservedCopy) {
+			weight += weightMap.get(subSeq);
+		}
+		return weight;
+	}
+
+	/**
+	 * <p>
+	 * Calculates the percentage of generated subsequences of length k that
+	 * occur and have not been observed, with reference to all generated
+	 * subsequences.
+	 * </p>
+	 * 
+	 * @return coverage percentage
+	 */
+	public double getNewPercentage() {
+		createSubSeqs();
+		Collection<List<? extends Event<?>>> subSeqsGeneratedCopy = new LinkedHashSet<List<? extends Event<?>>>(
+				subSeqsGenerated);
+		subSeqsGeneratedCopy.removeAll(subSeqsObserved);
+		return ((double) subSeqsGeneratedCopy.size()) / subSeqsGenerated.size();
+	}
+
+	/**
+	 * <p>
+	 * Calculates the percentage of generated subsequences of length k that
+	 * occur and have not been observed, with references to all possible new
+	 * subsequences.
+	 * </p>
+	 * 
+	 * @param process
+	 *            stochastic process which is used to determine which
+	 *            subsequences are possible
+	 * @return coverage percentage
+	 * @throws InvalidParameterException
+	 *             thrown if process is null
+	 */
+	public double getCoveragePossibleNew(IStochasticProcess process) {
+		if (process == null) {
+			throw new InvalidParameterException("process must not be null");
+		}
+		createSubSeqs();
+		Collection<List<? extends Event<?>>> subSeqsGeneratedCopy = new LinkedHashSet<List<? extends Event<?>>>(
+				subSeqsGenerated);
+		Collection<List<? extends Event<?>>> subSeqsPossible = process
+				.generateSequences(length);
+		subSeqsGeneratedCopy.removeAll(subSeqsObserved);
+		subSeqsPossible.removeAll(subSeqsObserved);
+		int possibleSize = subSeqsPossible.size();
+		subSeqsPossible.retainAll(subSeqsGeneratedCopy);
+		return ((double) subSeqsPossible.size()) / possibleSize;
+	}
+
+	/**
+	 * <p>
+	 * Calculates the weight of generated subsequences of length k that occur
+	 * and have not been observed, with references to all possible new
+	 * subsequences.
+	 * </p>
+	 * 
+	 * @param process
+	 *            stochastic process which is used to determine the weights and
+	 *            which subsequences are possible
+	 * @return coverage percentage
+	 * @throws InvalidParameterException
+	 *             thrown if process is null
+	 */
+	public double getCoveragePossibleNewWeight(IStochasticProcess process) {
+		if (process == null) {
+			throw new InvalidParameterException("process must not be null");
+		}
+		createSubSeqs();
+		Collection<List<? extends Event<?>>> subSeqsGeneratedCopy = new LinkedHashSet<List<? extends Event<?>>>(
+				subSeqsGenerated);
+		Collection<List<? extends Event<?>>> subSeqsPossible = process
+				.generateSequences(length);
+		subSeqsGeneratedCopy.removeAll(subSeqsObserved);
+		subSeqsPossible.removeAll(subSeqsObserved);
+		Map<List<? extends Event<?>>, Double> weightMap = SequenceTools
+				.generateWeights(process, subSeqsPossible);
+		double weight = 0.0d;
+		for (List<? extends Event<?>> subSeq : subSeqsGeneratedCopy) {
+			Double currentWeight = weightMap.get(subSeq);
+			if( currentWeight!=null ) {
+				weight += currentWeight;
+			}
+		}
+		return weight;
+	}
+
+	/**
+	 * <p>
+	 * Returns the number of covered subsequences of length k.
+	 * </p>
+	 * 
+	 * @return number of covered subsequences
+	 */
+	public int getNumObserved() {
+		createSubSeqs();
+		return subSeqsObserved.size();
+	}
+
+	/**
+	 * <p>
+	 * Returns the number of covered subsequences of length k.
+	 * </p>
+	 * 
+	 * @return number of covered subsequences
+	 */
+	public int getNumCovered() {
+		createSubSeqs();
+		return subSeqsGenerated.size();
+	}
+
+	public int getNumNew() {
+		createSubSeqs();
+		Collection<List<? extends Event<?>>> subSeqsGeneratedCopy = new LinkedHashSet<List<? extends Event<?>>>(
+				subSeqsGenerated);
+		subSeqsGeneratedCopy.removeAll(subSeqsObserved);
+		return subSeqsGeneratedCopy.size();
+	}
+
+	/**
+	 * <p>
+	 * Helper function that calcuates the subsequences of length k that have
+	 * been observed and generated.
+	 * </p>
+	 */
+	private void createSubSeqs() {
+		if (subSeqsObserved == null) {
+			subSeqsObserved = SequenceTools.containedSubSequences(
+					observedSequences, length);
+		}
+		if (subSeqsGenerated == null) {
+			subSeqsGenerated = SequenceTools.containedSubSequences(sequences,
+					length);
+		}
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-coverage/src/main/java/de/ugoe/cs/quest/coverage/CoverageCalculatorProcess.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-coverage/src/main/java/de/ugoe/cs/quest/coverage/CoverageCalculatorProcess.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-coverage/src/main/java/de/ugoe/cs/quest/coverage/CoverageCalculatorProcess.java	(revision 540)
@@ -0,0 +1,218 @@
+package de.ugoe.cs.quest.coverage;
+
+import java.security.InvalidParameterException;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.usageprofiles.IStochasticProcess;
+
+/**
+ * <p>
+ * This class calculates various types of sequence coverage in relation to a
+ * stochastic process.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CoverageCalculatorProcess {
+
+	/**
+	 * <p>
+	 * Stochastic process that is the foundation for probabilistic coverages and
+	 * coverages with reference to all possible sequences.
+	 * </p>
+	 */
+	private final IStochasticProcess process;
+
+	/**
+	 * <p>
+	 * Sequences for which the coverage is calculated.
+	 * </p>
+	 */
+	private Collection<List<? extends Event<?>>> sequences;
+
+	/**
+	 * <p>
+	 * Length of the subsequences in relation to which the coverage is
+	 * calculated.
+	 * </p>
+	 */
+	private final int length;
+
+	/**
+	 * <p>
+	 * All subsequences of {@link #length} of {@link #sequences}.
+	 * </p>
+	 */
+	private Collection<List<? extends Event<?>>> containedSubSeqs = null;
+
+	/**
+	 * <p>
+	 * All subsequences of {@link #length} that can be generated by
+	 * {@link #process}.
+	 * </p>
+	 */
+	private Collection<List<? extends Event<?>>> allPossibleSubSeqs = null;
+
+	/**
+	 * <p>
+	 * The probabilities of all subsequences of {@link #length} according to
+	 * {@link #process}.
+	 * </p>
+	 */
+	private Map<List<? extends Event<?>>, Double> subSeqWeights = null;
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new CoverageCalculatorProcess for a given
+	 * stochastic process and generated sequences.
+	 * </p>
+	 * 
+	 * @param process
+	 *            stochastic process used for coverage calculations; must not be
+	 *            null
+	 * @param sequences
+	 *            sequences for which the coverage is calculated; must not be
+	 *            null
+	 * @param length
+	 *            length of the subsequences for which the coverage is analyzed;
+	 *            must be >0
+	 * @throws InvalidParameterException
+	 *             thrown if process or sequences is null or length less than or equal to 0
+	 */
+	public CoverageCalculatorProcess(IStochasticProcess process,
+			Collection<List<? extends Event<?>>> sequences, int length) {
+		if (process == null) {
+			throw new InvalidParameterException("process must not be null");
+		}
+		if (sequences == null) {
+			throw new InvalidParameterException("sequences must not be null");
+		}
+		if (length <= 0) {
+			throw new InvalidParameterException(
+					"length must be >0; actual value: " + length);
+		}
+		this.process = process;
+		this.sequences = sequences;
+		this.length = length;
+	}
+
+	/**
+	 * <p>
+	 * Calculates the percentage of subsequences of length k that occur,
+	 * including those that cannot be generated by {@link #process}.
+	 * </p>
+	 * 
+	 * @return coverage percentage
+	 */
+	public double getCoverageAllNoWeight() {
+		if (containedSubSeqs == null) {
+			containedSubSeqs = SequenceTools.containedSubSequences(sequences,
+					length);
+		}
+		return ((double) containedSubSeqs.size())
+				/ SequenceTools.numSequences(process, length);
+	}
+
+	/**
+	 * <p>
+	 * Calculates the percentage of subsequences of length k that occur and can
+	 * generated by {@link #process}.
+	 * </p>
+	 * 
+	 * @return coverage percentage
+	 */
+	public double getCoveragePossibleNoWeight() {
+		if (containedSubSeqs == null) {
+			containedSubSeqs = SequenceTools.containedSubSequences(sequences,
+					length);
+		}
+		if (allPossibleSubSeqs == null) {
+			allPossibleSubSeqs = process.generateSequences(length);
+		}
+		return ((double) containedSubSeqs.size()) / allPossibleSubSeqs.size();
+	}
+
+	/**
+	 * <p>
+	 * Calculates the weight of the subsequences that occur with relation to
+	 * {@link #process}, i.e., the mass of the subsequence probability covered
+	 * by the subsequences.
+	 * </p>
+	 * 
+	 * @return coverage weight
+	 */
+	public double getCoveragePossibleWeight() {
+		if (containedSubSeqs == null) {
+			containedSubSeqs = SequenceTools.containedSubSequences(sequences,
+					length);
+		}
+		if (allPossibleSubSeqs == null) {
+			allPossibleSubSeqs = process.generateSequences(length);
+		}
+		if (subSeqWeights == null) {
+			subSeqWeights = SequenceTools.generateWeights(process,
+					allPossibleSubSeqs);
+		}
+		double weight = 0.0;
+		for (List<? extends Event<?>> subSeq : containedSubSeqs) {
+			Double curWeight = subSeqWeights.get(subSeq);
+			if( curWeight!=null ) {
+				weight += curWeight;
+			}
+		}
+		return weight;
+	}
+
+	/**
+	 * <p>
+	 * Returns the number of covered subsequences of length k.
+	 * </p>
+	 * 
+	 * @return number of covered subsequences
+	 */
+	public int getNumCovered() {
+		if (containedSubSeqs == null) {
+			containedSubSeqs = SequenceTools.containedSubSequences(sequences,
+					length);
+		}
+		return containedSubSeqs.size();
+	}
+
+	/**
+	 * <p>
+	 * Returns the number of possible subsequences of length k according to the
+	 * stochastic process.
+	 * </p>
+	 * 
+	 * @return number of possible subsequences
+	 */
+	public int getNumPossible() {
+		if (allPossibleSubSeqs == null) {
+			allPossibleSubSeqs = process.generateSequences(length);
+		}
+		return allPossibleSubSeqs.size();
+	}
+
+	/**
+	 * <p>
+	 * Sets a new collection of sequences for which the coverage is analyzed.
+	 * </p>
+	 * 
+	 * @param newSequences
+	 *            new collection of sequences
+	 * @throws InvalidParameterException
+	 *             thrown is newSequences is null
+	 */
+	public void setSequences(Collection<List<? extends Event<?>>> newSequences) {
+		if (newSequences == null) {
+			throw new InvalidParameterException("sequences must not be null");
+		}
+		this.sequences = newSequences;
+		containedSubSeqs = null;
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-coverage/src/main/java/de/ugoe/cs/quest/coverage/SequenceTools.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-coverage/src/main/java/de/ugoe/cs/quest/coverage/SequenceTools.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-coverage/src/main/java/de/ugoe/cs/quest/coverage/SequenceTools.java	(revision 540)
@@ -0,0 +1,147 @@
+package de.ugoe.cs.quest.coverage;
+
+import java.security.InvalidParameterException;
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.usageprofiles.IStochasticProcess;
+
+/**
+ * <p>
+ * This class gathers some helper functions to work with sequences.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class SequenceTools {
+	
+	/**
+	 * <p>
+	 * Private constructor to prevent initializing of the class.
+	 * </p>
+	 */
+	private SequenceTools() {
+		
+	}
+
+	/**
+	 * <p>
+	 * Calculates the weights for all sequences passed to this function as
+	 * defined by the stochastic process and stores them in a {@link Map}. The
+	 * weights are normalized, i.e., the sum of all weights contained in this
+	 * map is 1.
+	 * </p>
+	 * 
+	 * @param process
+	 *            process used for weight calculation
+	 * @param sequences
+	 *            sequences for which the weights are calculated
+	 * @return {@link Map} of weights
+	 */
+	public static Map<List<? extends Event<?>>, Double> generateWeights(
+			IStochasticProcess process,
+			Collection<List<? extends Event<?>>> sequences) {
+		Map<List<? extends Event<?>>, Double> subSeqWeights = new LinkedHashMap<List<? extends Event<?>>, Double>();
+		if (sequences != null && !sequences.isEmpty()) {
+			if (process != null) {
+				double sum = 0.0;
+				for (List<? extends Event<?>> sequence : sequences) {
+					double prob = process.getProbability(sequence);
+					subSeqWeights.put(sequence, prob);
+					sum += prob;
+				}
+				if (sum < 1.0) {
+					for (Map.Entry<List<? extends Event<?>>, Double> entry : subSeqWeights
+							.entrySet()) {
+						entry.setValue(entry.getValue() / sum);
+					}
+				}
+			} else {
+				for( List<? extends Event<?>> sequence : sequences ) {
+					subSeqWeights.put(sequence, 0.0d);
+				}
+			}
+		}
+		return subSeqWeights;
+	}
+
+	/**
+	 * <p>
+	 * Calculates the number of all existing sequences of a given length,
+	 * regardless whether they are possible or not.
+	 * </p>
+	 * 
+	 * @param process
+	 *            stochastic process whose symbols are the basis for this
+	 *            calculation
+	 * @param length
+	 *            lenght of the sequences
+	 * @return numStates^length
+	 * @throws InvalidParameterException
+	 *             thrown if length less or equal to 0
+	 */
+	public static long numSequences(IStochasticProcess process, int length) {
+		if (length <= 0) {
+			throw new InvalidParameterException(
+					"length must be a positive integer");
+		}
+		long result = 0;
+		if (process != null) {
+			result = (long) Math.pow(process.getNumSymbols(), length);
+		}
+		return result;
+	}
+
+	/**
+	 * <p>
+	 * Creates a {@link Set} of all subsequences of a given length that are
+	 * contained in a sequence collection.
+	 * </p>
+	 * 
+	 * @param sequences
+	 *            sequences from which the subsequences are extracted
+	 * @param length
+	 *            length of the subsequences
+	 * @return {@link Set} of all subsequences
+	 * @throws InvalidParameterException
+	 *             thrown if length less or equal to 0
+	 */
+	public static Set<List<? extends Event<?>>> containedSubSequences(
+			Collection<List<? extends Event<?>>> sequences, int length) {
+		if (length <= 0) {
+			throw new InvalidParameterException(
+					"length must be a positive integer");
+		}
+		Set<List<? extends Event<?>>> containedSubSeqs = new LinkedHashSet<List<? extends Event<?>>>();
+		if (sequences != null) {
+			for (List<? extends Event<?>> sequence : sequences) {
+				List<Event<?>> subSeq = new LinkedList<Event<?>>();
+				boolean minLengthReached = false;
+				for (Event<?> event : sequence) {
+					subSeq.add(event);
+					if (!minLengthReached) {
+						if (subSeq.size() == length) {
+							minLengthReached = true;
+						}
+					} else {
+						subSeq.remove(0);
+					}
+					if (minLengthReached) {
+						if (!containedSubSeqs.contains(subSeq)) {
+							containedSubSeqs.add(new LinkedList<Event<?>>(
+									subSeq));
+						}
+					}
+				}
+			}
+		}
+		return containedSubSeqs;
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events-patrick/.classpath
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-patrick/.classpath	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-patrick/.classpath	(revision 540)
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/classes" path="src/main/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="src" output="target/test-classes" path="src/test/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
Index: /tags/quest-pre-eventrefactoring/quest-core-events-patrick/.project
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-patrick/.project	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-patrick/.project	(revision 540)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>quest-core-events-patrick</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
Index: /tags/quest-pre-eventrefactoring/quest-core-events-patrick/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-patrick/.settings/org.eclipse.jdt.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-patrick/.settings/org.eclipse.jdt.core.prefs	(revision 540)
@@ -0,0 +1,5 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.6
Index: /tags/quest-pre-eventrefactoring/quest-core-events-patrick/.settings/org.eclipse.m2e.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-patrick/.settings/org.eclipse.m2e.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-patrick/.settings/org.eclipse.m2e.core.prefs	(revision 540)
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
Index: /tags/quest-pre-eventrefactoring/quest-core-events-patrick/pom.xml
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-patrick/pom.xml	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-patrick/pom.xml	(revision 540)
@@ -0,0 +1,35 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>de.ugoe.cs.quest</groupId>
+  <artifactId>quest-core-events-patrick</artifactId>
+  <version>0.0.1-SNAPSHOT</version>
+  <name>quest-core-events-patrick</name>
+  <scm>
+    <url>https://quest.informatik.uni-goettingen.de/svn/quest/trunk/quest-core-events-patrick</url>
+  </scm>
+  <dependencies>
+    <dependency>
+      <groupId>de.ugoe.cs.quest</groupId>
+      <artifactId>quest-misc</artifactId>
+      <version>0.0.1-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.8.1</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>2.3.2</version>
+        <configuration>
+          <source>1.6</source>
+          <target>1.6</target>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
Index: /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/AbstractDefaultGUIElement.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/AbstractDefaultGUIElement.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/AbstractDefaultGUIElement.java	(revision 540)
@@ -0,0 +1,70 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: AbstractDefaultGUIElement.java,v $
+// Version   : $Revision: 0.0 $  $Author: Patrick $  $Date: 27.11.2011 17:21:28 $
+// Project   : TaskTreePerformanceTest
+// Creation  : 2011 by Patrick
+// Copyright : Patrick Harms, 2011
+//-------------------------------------------------------------------------------------------------
+
+package de.ugoe.cs.quest.eventcore.guimodel;
+
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ *
+ * @version $Revision: $ $Date: $
+ * @author  2011, last modified by $Author: $
+ */
+//-------------------------------------------------------------------------------------------------
+
+public abstract class AbstractDefaultGUIElement implements GUIElement
+{
+  /** the parent interaction element */
+  private GUIElement mParent;
+
+  /** the information about the original type before the mapping */
+  private String mOriginalTypeInfo;
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see GUIElement#setParent(GUIElement)
+   */
+  //-----------------------------------------------------------------------------------------------
+  public void setParent(GUIElement parent)
+  {
+    mParent = parent;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see GUIElement#getParent()
+   */
+  //-----------------------------------------------------------------------------------------------
+  public GUIElement getParent()
+  {
+    return mParent;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.ugoe.cs.tasktree.guimodel.GUIElement#getOriginalTypeInfo()
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public String getOriginalTypeInfo()
+  {
+    return mOriginalTypeInfo;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see GUIElement#setOriginalTypeInfo(String)
+   */
+  //-----------------------------------------------------------------------------------------------
+  void setOriginalTypeInfo(String originalTypeInfo)
+  {
+    mOriginalTypeInfo = originalTypeInfo;
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/AbstractDefaultGUIElementFactory.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/AbstractDefaultGUIElementFactory.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/AbstractDefaultGUIElementFactory.java	(revision 540)
@@ -0,0 +1,300 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: AbstractDefaultGUIElementFactory.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 13.05.2012 $
+// Project   : GUIModel
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.eventcore.guimodel;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 13.05.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public class AbstractDefaultGUIElementFactory
+{
+  /** */
+  private Properties mMappingsFromConfiguration;
+
+  /** */
+  private Map<String, List<GUIElement>> mGuiElementCache = new HashMap<String, List<GUIElement>>();
+  
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param key
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  protected List<GUIElement> getGUIElementCandidates(String key)
+  {
+    return mGuiElementCache.get(key);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param retVal
+   */
+  //-----------------------------------------------------------------------------------------------
+  protected void addGUIElementToCache(String key, GUIElement guiElement)
+  {
+    List<GUIElement> candidates = mGuiElementCache.get(key);
+    
+    if (candidates == null)
+    {
+      candidates = new ArrayList<GUIElement>();
+      mGuiElementCache.put(key, candidates);
+    }
+    
+    candidates.add(guiElement);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param icon
+   * @param icon2
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  protected boolean equals(Object object1, Object object2)
+  {
+    if (object1 == object2)
+    {
+      return true;
+    }
+    else if (object1 != null)
+    {
+      return object1.equals(object2);
+    }
+    else
+    {
+      return object2 == null;
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param name
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  protected String getKey(String name)
+  {
+    if (name == null)
+    {
+      return "noName";
+    }
+    else
+    {
+      return name;
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param parameterTypes
+   * @param parameters
+   * @return
+   * @throws GUIModelConfigurationException 
+   */
+  //-----------------------------------------------------------------------------------------------
+  protected GUIElement instantiateGUIElementFromConfiguredMappings(String    type,
+                                                                   Object... parameters)
+    throws GUIModelConfigurationException
+  {
+    Properties mappings = getMappingsFromConfiguration();
+    
+    String className = mappings.getProperty(type);
+    if (className != null)
+    {
+      try
+      {
+        Class<?> clazz = this.getClass().getClassLoader().loadClass(className);
+        
+        if (!GUIElement.class.isAssignableFrom(clazz))
+        {
+          Logger.getLogger(this.getClass().getName()).warning
+            ("configured GUI element representing class " + className + " is no valid GUIElement " +
+             "derivate.");
+          
+          return null;
+        }
+        
+        Class<?>[] parameterTypes = new Class<?>[parameters.length];
+        
+        for (int i = 0; i < parameters.length; i++)
+        {
+          parameterTypes[i] = parameters[i].getClass();
+          
+          if (Boolean.class.equals(parameterTypes[i]))
+          {
+            parameterTypes[i] = boolean.class;
+          }
+          else if (Integer.class.equals(parameterTypes[i]))
+          {
+            parameterTypes[i] = int.class;
+          }
+          else if (Double.class.equals(parameterTypes[i]))
+          {
+            parameterTypes[i] = double.class;
+          }
+          else if (Character.class.equals(parameterTypes[i]))
+          {
+            parameterTypes[i] = char.class;
+          }
+          else if (Byte.class.equals(parameterTypes[i]))
+          {
+            parameterTypes[i] = byte.class;
+          }
+          else if (Float.class.equals(parameterTypes[i]))
+          {
+            parameterTypes[i] = float.class;
+          }
+          else if (Long.class.equals(parameterTypes[i]))
+          {
+            parameterTypes[i] = long.class;
+          }
+          else if (Short.class.equals(parameterTypes[i]))
+          {
+            parameterTypes[i] = short.class;
+          }
+        }
+        
+        GUIElement guiElement =
+          (GUIElement) clazz.getConstructor(parameterTypes).newInstance(parameters);
+        
+        if (guiElement instanceof AbstractDefaultGUIElement)
+        {
+          ((AbstractDefaultGUIElement) guiElement).setOriginalTypeInfo(type);
+        }
+        
+        return guiElement;
+      }
+      catch (ClassNotFoundException e)
+      {
+        Logger.getLogger(this.getClass().getName()).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)
+      {
+        Logger.getLogger(this.getClass().getName()).log
+          (Level.WARNING, "configured GUI element representing class " + className + " can not " +
+           "be instantiated due to security reasons.", e);
+        throw new GUIModelConfigurationException
+          ("configured GUI element representing class " + className + " can not " +
+           "be instantiated due to security reasons.", e);
+      }
+      catch (NoSuchMethodException e)
+      {
+        Logger.getLogger(this.getClass().getName()).warning
+          ("configured GUI element representing class " + className + " does not provide an " +
+           "appropriate constructur.");
+        throw new GUIModelConfigurationException
+          ("configured GUI element representing class " + className + " does not provide an " +
+           "appropriate constructur.", e);
+      }
+      catch (IllegalArgumentException e)
+      {
+        Logger.getLogger(this.getClass().getName()).warning
+          ("configured GUI element representing class " + className + " does not provide an " +
+           "appropriate constructur accepting the provided parameters.");
+        throw new GUIModelConfigurationException
+          ("configured GUI element representing class " + className + " does not provide an " +
+           "appropriate constructur accepting the provided parameters.", e);
+      }
+      catch (InstantiationException e)
+      {
+        Logger.getLogger(this.getClass().getName()).log
+          (Level.WARNING, "configured GUI element representing class " + className + " can not " +
+           "be instantiated.", e);
+        throw new GUIModelConfigurationException
+          ("configured GUI element representing class " + className + " can not " +
+           "be instantiated.", e);
+      }
+      catch (IllegalAccessException e)
+      {
+        Logger.getLogger(this.getClass().getName()).log
+          (Level.WARNING, "configured GUI element representing class " + className + " can not " +
+           "be instantiated.", e);
+        throw new GUIModelConfigurationException
+          ("configured GUI element representing class " + className + " can not " +
+           "be instantiated.", e);
+      }
+      catch (InvocationTargetException e)
+      {
+        Logger.getLogger(this.getClass().getName()).log
+          (Level.WARNING, "configured GUI element representing class " + className + " can not " +
+           "be instantiated.", e);
+        throw new GUIModelConfigurationException
+          ("configured GUI element representing class " + className + " can not " +
+           "be instantiated.", e);
+      }
+    }
+    
+    return null;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  private synchronized Properties getMappingsFromConfiguration()
+  {
+    if (mMappingsFromConfiguration != null)
+    {
+      return mMappingsFromConfiguration;
+    }
+    else
+    {
+      mMappingsFromConfiguration = new Properties();
+      
+      InputStream inStream =
+        this.getClass().getClassLoader().getResourceAsStream("GUIElementMapping.txt");
+      
+      if (inStream != null)
+      {
+        try
+        {
+          mMappingsFromConfiguration.load(inStream);
+        }
+        catch (IOException e)
+        {
+          Logger.getLogger(this.getClass().getName()).warning
+            ("could not load GUIElementMapping.txt from classpath, but this may be intended");
+        }
+      }
+      
+      return mMappingsFromConfiguration;
+    }
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/Button.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/Button.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/Button.java	(revision 540)
@@ -0,0 +1,21 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: TrackBar.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 28.04.2012 $
+// Project   : GUIModel
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.eventcore.guimodel;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 28.04.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public interface Button extends GUIElement
+{
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/Canvas.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/Canvas.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/Canvas.java	(revision 540)
@@ -0,0 +1,21 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: TrackBar.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 28.04.2012 $
+// Project   : GUIModel
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.eventcore.guimodel;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 28.04.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public interface Canvas extends GUIElement
+{
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/Container.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/Container.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/Container.java	(revision 540)
@@ -0,0 +1,36 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: Container.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 15.04.2012 $
+// Project   : GUIModel
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.eventcore.guimodel;
+
+import java.util.List;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 15.04.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public interface Container extends GUIElement
+{
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  public void addChild(GUIElement child);
+  
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  public List<GUIElement> getChildren();
+  
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/Dialog.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/Dialog.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/Dialog.java	(revision 540)
@@ -0,0 +1,21 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: TrackBar.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 28.04.2012 $
+// Project   : GUIModel
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.eventcore.guimodel;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 28.04.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public interface Dialog extends GUIElement
+{
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/Frame.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/Frame.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/Frame.java	(revision 540)
@@ -0,0 +1,21 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: TrackBar.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 28.04.2012 $
+// Project   : GUIModel
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.eventcore.guimodel;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 28.04.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public interface Frame extends GUIElement
+{
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/GUIElement.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/GUIElement.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/GUIElement.java	(revision 540)
@@ -0,0 +1,51 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: GUIElement.java,v $
+// Version   : $Revision: 0.0 $  $Author: Patrick $  $Date: 06.11.2011 10:26:40 $
+// Project   : TaskTreePerformanceTest
+// Creation  : 2011 by Patrick
+// Copyright : Patrick Harms, 2011
+//-------------------------------------------------------------------------------------------------
+
+package de.ugoe.cs.quest.eventcore.guimodel;
+
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ *
+ * @version $Revision: $ $Date: $
+ * @author  2011, last modified by $Author: $
+ */
+//-------------------------------------------------------------------------------------------------
+public interface GUIElement
+{
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  public void setParent(GUIElement parent);
+  
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  public GUIElement getParent();
+  
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  public String getOriginalTypeInfo();
+  
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * @param other
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  public boolean equals(GUIElement other);
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/GUIModelConfigurationException.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/GUIModelConfigurationException.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/GUIModelConfigurationException.java	(revision 540)
@@ -0,0 +1,72 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: GUIModelConfigurationException.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 27.05.2012 $
+// Project   : GUIModel
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.eventcore.guimodel;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 27.05.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public class GUIModelConfigurationException extends Exception
+{
+
+  /**  */
+  private static final long serialVersionUID = 1L;
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  public GUIModelConfigurationException()
+  {
+    super();
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param message
+   */
+  //-----------------------------------------------------------------------------------------------
+  public GUIModelConfigurationException(String message)
+  {
+    super(message);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param cause
+   */
+  //-----------------------------------------------------------------------------------------------
+  public GUIModelConfigurationException(Throwable cause)
+  {
+    super(cause);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param message
+   * @param cause
+   */
+  //-----------------------------------------------------------------------------------------------
+  public GUIModelConfigurationException(String message, Throwable cause)
+  {
+    super(message, cause);
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/Menu.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/Menu.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/Menu.java	(revision 540)
@@ -0,0 +1,21 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: TrackBar.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 28.04.2012 $
+// Project   : GUIModel
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.eventcore.guimodel;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 28.04.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public interface Menu extends GUIElement
+{
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/MenuBar.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/MenuBar.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/MenuBar.java	(revision 540)
@@ -0,0 +1,21 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: TrackBar.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 28.04.2012 $
+// Project   : GUIModel
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.eventcore.guimodel;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 28.04.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public interface MenuBar extends Menu
+{
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/MenuButton.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/MenuButton.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/MenuButton.java	(revision 540)
@@ -0,0 +1,21 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: TrackBar.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 28.04.2012 $
+// Project   : GUIModel
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.eventcore.guimodel;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 28.04.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public interface MenuButton extends Button
+{
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/Panel.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/Panel.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/Panel.java	(revision 540)
@@ -0,0 +1,21 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: TrackBar.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 28.04.2012 $
+// Project   : GUIModel
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.eventcore.guimodel;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 28.04.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public interface Panel extends GUIElement
+{
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/ScrollBar.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/ScrollBar.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/ScrollBar.java	(revision 540)
@@ -0,0 +1,21 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: TrackBar.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 28.04.2012 $
+// Project   : GUIModel
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.eventcore.guimodel;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 28.04.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public interface ScrollBar extends GUIElement
+{
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/ScrollPane.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/ScrollPane.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/ScrollPane.java	(revision 540)
@@ -0,0 +1,21 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: TrackBar.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 28.04.2012 $
+// Project   : GUIModel
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.eventcore.guimodel;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 28.04.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public interface ScrollPane extends GUIElement
+{
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/Shape.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/Shape.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/Shape.java	(revision 540)
@@ -0,0 +1,21 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: TrackBar.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 28.04.2012 $
+// Project   : GUIModel
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.eventcore.guimodel;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 28.04.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public interface Shape extends GUIElement
+{
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/SplitPane.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/SplitPane.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/SplitPane.java	(revision 540)
@@ -0,0 +1,21 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: TrackBar.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 28.04.2012 $
+// Project   : GUIModel
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.eventcore.guimodel;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 28.04.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public interface SplitPane extends GUIElement
+{
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/TabbedPane.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/TabbedPane.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/TabbedPane.java	(revision 540)
@@ -0,0 +1,21 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: TrackBar.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 28.04.2012 $
+// Project   : GUIModel
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.eventcore.guimodel;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 28.04.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public interface TabbedPane extends GUIElement
+{
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/TextArea.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/TextArea.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/TextArea.java	(revision 540)
@@ -0,0 +1,21 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: TrackBar.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 28.04.2012 $
+// Project   : GUIModel
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.eventcore.guimodel;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 28.04.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public interface TextArea extends GUIElement
+{
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/TextField.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/TextField.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/TextField.java	(revision 540)
@@ -0,0 +1,21 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: TrackBar.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 28.04.2012 $
+// Project   : GUIModel
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.eventcore.guimodel;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 28.04.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public interface TextField extends GUIElement
+{
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/ToolBar.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/ToolBar.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/ToolBar.java	(revision 540)
@@ -0,0 +1,21 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: TrackBar.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 28.04.2012 $
+// Project   : GUIModel
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.eventcore.guimodel;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 28.04.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public interface ToolBar extends GUIElement
+{
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/TrackBar.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/TrackBar.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/TrackBar.java	(revision 540)
@@ -0,0 +1,21 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: TrackBar.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 28.04.2012 $
+// Project   : GUIModel
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.eventcore.guimodel;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 28.04.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public interface TrackBar extends GUIElement
+{
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/Interaction.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/Interaction.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/Interaction.java	(revision 540)
@@ -0,0 +1,43 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: Interaction.java,v $
+// Version   : $Revision: 0.0 $  $Author: Patrick $  $Date: 06.11.2011 10:26:33 $
+// Project   : TaskTreePerformanceTest
+// Creation  : 2011 by Patrick
+// Copyright : Patrick Harms, 2011
+//-------------------------------------------------------------------------------------------------
+
+package de.ugoe.cs.quest.eventcore.userinteraction;
+
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ *
+ * @version $Revision: $ $Date: $
+ * @author  2011, last modified by $Author: $
+ */
+//-------------------------------------------------------------------------------------------------
+public interface Interaction
+{
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  public String getName();
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  public boolean startsLogicalSequence();
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  public boolean finishesLogicalSequence();
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/InteractionEvent.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/InteractionEvent.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/InteractionEvent.java	(revision 540)
@@ -0,0 +1,73 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: InteractionEvent.java,v $
+// Version   : $Revision: 0.0 $  $Author: Patrick $  $Date: 06.11.2011 10:48:01 $
+// Project   : TaskTreePerformanceTest
+// Creation  : 2011 by Patrick
+// Copyright : Patrick Harms, 2011
+//-------------------------------------------------------------------------------------------------
+
+package de.ugoe.cs.quest.eventcore.userinteraction;
+
+import de.ugoe.cs.quest.eventcore.guimodel.GUIElement;
+
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ *
+ * @version $Revision: $ $Date: $
+ * @author  2011, last modified by $Author: $
+ */
+//-------------------------------------------------------------------------------------------------
+public class InteractionEvent
+{
+  /** */
+  private GUIElement mGUIElement;
+  
+  /** */
+  private Interaction mInteraction;
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * @param GUIElement
+   * @param interaction
+   */
+  //-----------------------------------------------------------------------------------------------
+  public InteractionEvent(GUIElement guiElement, Interaction interaction)
+  {
+    mGUIElement = guiElement;
+    mInteraction = interaction;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  public GUIElement getGUIElement()
+  {
+    return mGUIElement;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  public Interaction getInteraction()
+  {
+    return mInteraction;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see java.lang.Object#toString()
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public String toString()
+  {
+    return mInteraction + " on " + mGUIElement;
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/InteractionEventList.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/InteractionEventList.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/InteractionEventList.java	(revision 540)
@@ -0,0 +1,279 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: InteractionEventList.java,v $
+// Version   : $Revision: 0.0 $  $Author: Patrick $  $Date: 04.12.2011 10:20:14 $
+// Project   : TaskTreePerformanceTest
+// Creation  : 2011 by Patrick
+// Copyright : Patrick Harms, 2011
+//-------------------------------------------------------------------------------------------------
+
+package de.ugoe.cs.quest.eventcore.userinteraction;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ *
+ * @version $Revision: $ $Date: $
+ * @author  2011, last modified by $Author: $
+ */
+//-------------------------------------------------------------------------------------------------
+@SuppressWarnings("serial")
+public class InteractionEventList
+  extends ArrayList<InteractionEvent>
+  implements List<InteractionEvent>
+{
+  /** stores the events to be handled later in the order, they should be processed */
+  private List<KeyEventPair> mEventPairs = new ArrayList<KeyEventPair>();
+  
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * this method sorts interaction events for pressed keys. The reason is, that sometimes the
+   * release of one key comes after the pressing of the succeeding key. This only makes sense
+   * for shift, ctrl or alt keys, but not for usual characters. So the events are sorted.<br/>
+   * Furthermore, this methods creates key released events in the specific case, where a key is
+   * pressed for a long time. Here, many subsequent key pressed events for the same key can be
+   * observed, for which there are no key released events.
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public boolean add(InteractionEvent event)
+  {
+    if (event.getInteraction() instanceof KeyInteraction)
+    {
+      for (int i = 0; i < mEventPairs.size(); i++)
+      {
+        KeyEventPair eventPair = mEventPairs.get(i);
+        
+        if (eventPair.process(event))
+        {
+          // handle all leading and completed event pairs, if any
+          while ((mEventPairs.size() > 0) && (mEventPairs.get(0).isComplete()))
+          {
+            addEventPair(mEventPairs.get(0));
+            mEventPairs.remove(0);
+          }
+          return true;
+        }
+      }
+      
+      mEventPairs.add(new KeyEventPair(event));
+      return true;
+    }
+    else
+    {
+      // any other event is simply added
+      return super.add(event);
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see java.util.ArrayList#add(int, java.lang.Object)
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public void add(int index, InteractionEvent event)
+  {
+    List<InteractionEvent> remaining = new ArrayList<InteractionEvent>();
+    
+    while (index < super.size())
+    {
+      remaining.add(super.remove(index));
+    }
+    
+    add(event);
+    addAll(remaining);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see java.util.ArrayList#addAll(java.util.Collection)
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public boolean addAll(Collection<? extends InteractionEvent> events)
+  {
+    int initialSize = super.size();
+    
+    for (InteractionEvent event : events)
+    {
+      add(event);
+    }
+    
+    return initialSize != super.size();
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see java.util.ArrayList#addAll(int, java.util.Collection)
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public boolean addAll(int index, Collection<? extends InteractionEvent> events)
+  {
+    int initialSize = super.size();
+    
+    List<InteractionEvent> remaining = new ArrayList<InteractionEvent>();
+    
+    while (index < super.size())
+    {
+      remaining.add(super.remove(index));
+    }
+    
+    addAll(events);
+    addAll(remaining);
+    
+    return initialSize != super.size();
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  private void addEventPair(KeyEventPair eventPair)
+  {
+    super.add(eventPair.mFirst);
+    
+    for (KeyEventPair child : eventPair.mChildren)
+    {
+      addEventPair(child);
+    }
+    
+    super.add(eventPair.mSecond);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  private static class KeyEventPair
+  {
+    /** the first interaction event */
+    private InteractionEvent mFirst;
+    
+    /** the second interaction event */
+    private InteractionEvent mSecond;
+
+    /** the children, this event pair may have */
+    private List<KeyEventPair> mChildren = new ArrayList<KeyEventPair>();
+    
+    //---------------------------------------------------------------------------------------------
+    /**
+     *
+     */
+    //---------------------------------------------------------------------------------------------
+    private KeyEventPair(InteractionEvent first)
+    {
+      if (!(first.getInteraction() instanceof KeyPressed))
+      {
+        throw new IllegalArgumentException
+          ("can only handle key pressed interaction events as first element of an event pair");
+      }
+      mFirst = first;
+    }
+    
+    //---------------------------------------------------------------------------------------------
+    /**
+     * sorts the event as the second of the pair or as the closing of this. Returns true,
+     * if this matched, false else
+     */
+    //---------------------------------------------------------------------------------------------
+    private boolean process(InteractionEvent event)
+    {
+      if (!(event.getInteraction() instanceof KeyInteraction))
+      {
+        throw new IllegalArgumentException("can only handle key interaction events");
+      }
+      
+      if (this.isComplete())
+      {
+        // do not process events, if there are no more events expected
+        return false;
+      }
+      
+      if ((event.getInteraction() instanceof KeyReleased) &&
+          (((KeyInteraction) mFirst.getInteraction()).getKey() ==
+           ((KeyInteraction) event.getInteraction()).getKey()) &&
+          (mSecond == null))
+      {
+        // this is the release of the represented key. Store it and notify the processing.
+        mSecond = event;
+        return true;
+      }
+      else if ((event.getInteraction() instanceof KeyPressed) &&
+               (((KeyInteraction) mFirst.getInteraction()).getKey() ==
+                ((KeyInteraction) event.getInteraction()).getKey()) &&
+               (mSecond == null))
+      {
+        // the key was pressed before it was released again. This happens, if the key
+        // stays pressed for a long time. Generate a key released event but do not mark
+        // the new event as processed
+        mSecond = new InteractionEvent
+          (mFirst.getGUIElement(),
+           new KeyReleased(((KeyInteraction) event.getInteraction()).getKey()));
+        return false;
+      }
+      else if (((KeyInteraction) mFirst.getInteraction()).getKey().isCombinationKey() &&
+               (((KeyInteraction) mFirst.getInteraction()).getKey() !=
+                ((KeyInteraction) event.getInteraction()).getKey()))
+      {
+        // this pair may have children. Let the event be processed by the children. If this
+        // doesn't work, add the event as a new child pair, if it is a new key pressed
+        
+        for (KeyEventPair child : mChildren)
+        {
+          if (child.process(event))
+          {
+            return true;
+          }
+        }
+        
+        if (event.getInteraction() instanceof KeyPressed)
+        {
+          mChildren.add(new KeyEventPair(event));
+          return true;
+        }
+        else
+        {
+          return false;
+        }
+      }
+      else
+      {
+        // this pair may not have children
+        return false;
+      }
+    }
+    
+    //---------------------------------------------------------------------------------------------
+    /**
+     * @return
+     */
+    //---------------------------------------------------------------------------------------------
+    private boolean isComplete()
+    {
+      if ((mFirst != null) && (mSecond != null))
+      {
+        for (KeyEventPair child : mChildren)
+        {
+          if (!child.isComplete())
+          {
+            return false;
+          }
+        }
+        
+        return true;
+      }
+      else
+      {
+        return false;
+      }
+    }
+
+  }
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/KeyInteraction.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/KeyInteraction.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/KeyInteraction.java	(revision 540)
@@ -0,0 +1,47 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: Click.java,v $
+// Version   : $Revision: 0.0 $  $Author: Patrick $  $Date: 06.11.2011 10:28:39 $
+// Project   : TaskTreePerformanceTest
+// Creation  : 2011 by Patrick
+// Copyright : Patrick Harms, 2011
+//-------------------------------------------------------------------------------------------------
+
+package de.ugoe.cs.quest.eventcore.userinteraction;
+
+import de.ugoe.cs.tasktree.keyboardmaps.VirtualKey;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ *
+ * @version $Revision: $ $Date: $
+ * @author  2011, last modified by $Author: $
+ */
+//-------------------------------------------------------------------------------------------------
+public abstract class KeyInteraction implements Interaction
+{
+  /** the key, that was actually pressed */
+  private VirtualKey mKey;
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * @param key
+   */
+  //-----------------------------------------------------------------------------------------------
+  public KeyInteraction(VirtualKey key)
+  {
+    super();
+    mKey = key;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * 
+   */
+  //-----------------------------------------------------------------------------------------------
+  public VirtualKey getKey()
+  {
+    return mKey;
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/KeyPressed.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/KeyPressed.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/KeyPressed.java	(revision 540)
@@ -0,0 +1,94 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: Click.java,v $
+// Version   : $Revision: 0.0 $  $Author: Patrick $  $Date: 06.11.2011 10:28:39 $
+// Project   : TaskTreePerformanceTest
+// Creation  : 2011 by Patrick
+// Copyright : Patrick Harms, 2011
+//-------------------------------------------------------------------------------------------------
+
+package de.ugoe.cs.quest.eventcore.userinteraction;
+
+import de.ugoe.cs.tasktree.keyboardmaps.VirtualKey;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ *
+ * @version $Revision: $ $Date: $
+ * @author  2011, last modified by $Author: $
+ */
+//-------------------------------------------------------------------------------------------------
+public class KeyPressed extends KeyInteraction
+{
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * @param key
+   */
+  //-----------------------------------------------------------------------------------------------
+  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()
+  {
+    // TODO Auto-generated method stub
+    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;
+    }
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/KeyReleased.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/KeyReleased.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/KeyReleased.java	(revision 540)
@@ -0,0 +1,94 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: Click.java,v $
+// Version   : $Revision: 0.0 $  $Author: Patrick $  $Date: 06.11.2011 10:28:39 $
+// Project   : TaskTreePerformanceTest
+// Creation  : 2011 by Patrick
+// Copyright : Patrick Harms, 2011
+//-------------------------------------------------------------------------------------------------
+
+package de.ugoe.cs.quest.eventcore.userinteraction;
+
+import de.ugoe.cs.tasktree.keyboardmaps.VirtualKey;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ *
+ * @version $Revision: $ $Date: $
+ * @author  2011, last modified by $Author: $
+ */
+//-------------------------------------------------------------------------------------------------
+public class KeyReleased extends KeyInteraction
+{
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * @param key
+   */
+  //-----------------------------------------------------------------------------------------------
+  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()
+  {
+    // TODO Auto-generated method stub
+    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;
+    }
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/KeyboardFocusChange.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/KeyboardFocusChange.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/KeyboardFocusChange.java	(revision 540)
@@ -0,0 +1,65 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: FocusChange.java,v $
+// Version   : $Revision: 0.0 $  $Author: Patrick $  $Date: 27.11.2011 18:11:29 $
+// Project   : TaskTreePerformanceTest
+// Creation  : 2011 by Patrick
+// Copyright : Patrick Harms, 2011
+//-------------------------------------------------------------------------------------------------
+
+package de.ugoe.cs.quest.eventcore.userinteraction;
+
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ *
+ * @version $Revision: $ $Date: $
+ * @author  2011, last modified by $Author: $
+ */
+//-------------------------------------------------------------------------------------------------
+
+public class KeyboardFocusChange implements Interaction
+{
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.harms.attef.userinteraction.Interaction#getName()
+   */
+  //-----------------------------------------------------------------------------------------------
+  public String getName()
+  {
+    return "KeyboardFocusChanged";
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (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";
+  }
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/MouseButtonDown.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/MouseButtonDown.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/MouseButtonDown.java	(revision 540)
@@ -0,0 +1,104 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: Click.java,v $
+// Version   : $Revision: 0.0 $  $Author: Patrick $  $Date: 06.11.2011 10:28:39 $
+// Project   : TaskTreePerformanceTest
+// Creation  : 2011 by Patrick
+// Copyright : Patrick Harms, 2011
+//-------------------------------------------------------------------------------------------------
+
+package de.ugoe.cs.quest.eventcore.userinteraction;
+
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ *
+ * @version $Revision: $ $Date: $
+ * @author  2011, last modified by $Author: $
+ */
+//-------------------------------------------------------------------------------------------------
+public class MouseButtonDown extends MouseButtonInteraction
+{
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * @param 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;
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/MouseButtonInteraction.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/MouseButtonInteraction.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/MouseButtonInteraction.java	(revision 540)
@@ -0,0 +1,54 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: MouseButtonInteraction.java,v $
+// Version   : $Revision: 0.0 $  $Author: Patrick $  $Date: 18.12.2011 10:06:29 $
+// Project   : TaskTreePerformanceTest
+// Creation  : 2011 by Patrick
+// Copyright : Patrick Harms, 2011
+//-------------------------------------------------------------------------------------------------
+
+package de.ugoe.cs.quest.eventcore.userinteraction;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ *
+ * @version $Revision: $ $Date: $
+ * @author  2011, last modified by $Author: $
+ */
+//-------------------------------------------------------------------------------------------------
+
+public abstract class MouseButtonInteraction extends MouseInteraction
+{
+
+  /** */
+  public static enum Button
+  {
+    LEFT,
+    MIDDLE,
+    RIGHT;
+  }
+
+  /** the button used for mouse interaction */
+  private Button mButton;
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * 
+   */
+  //-----------------------------------------------------------------------------------------------
+  public MouseButtonInteraction(Button button)
+  {
+    mButton = button;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * @return Returns the button.
+   */
+  //-----------------------------------------------------------------------------------------------
+  public Button getButton()
+  {
+    return mButton;
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/MouseButtonUp.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/MouseButtonUp.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/MouseButtonUp.java	(revision 540)
@@ -0,0 +1,104 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: Click.java,v $
+// Version   : $Revision: 0.0 $  $Author: Patrick $  $Date: 06.11.2011 10:28:39 $
+// Project   : TaskTreePerformanceTest
+// Creation  : 2011 by Patrick
+// Copyright : Patrick Harms, 2011
+//-------------------------------------------------------------------------------------------------
+
+package de.ugoe.cs.quest.eventcore.userinteraction;
+
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ *
+ * @version $Revision: $ $Date: $
+ * @author  2011, last modified by $Author: $
+ */
+//-------------------------------------------------------------------------------------------------
+public class MouseButtonUp extends MouseButtonInteraction
+{
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * @param 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;
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/MouseClick.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/MouseClick.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/MouseClick.java	(revision 540)
@@ -0,0 +1,103 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: Click.java,v $
+// Version   : $Revision: 0.0 $  $Author: Patrick $  $Date: 06.11.2011 10:28:39 $
+// Project   : TaskTreePerformanceTest
+// Creation  : 2011 by Patrick
+// Copyright : Patrick Harms, 2011
+//-------------------------------------------------------------------------------------------------
+
+package de.ugoe.cs.quest.eventcore.userinteraction;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ *
+ * @version $Revision: $ $Date: $
+ * @author  2011, last modified by $Author: $
+ */
+//-------------------------------------------------------------------------------------------------
+public class MouseClick extends MouseButtonInteraction
+{
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * @param 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;
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/MouseInteraction.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/MouseInteraction.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/MouseInteraction.java	(revision 540)
@@ -0,0 +1,22 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: Click.java,v $
+// Version   : $Revision: 0.0 $  $Author: Patrick $  $Date: 06.11.2011 10:28:39 $
+// Project   : TaskTreePerformanceTest
+// Creation  : 2011 by Patrick
+// Copyright : Patrick Harms, 2011
+//-------------------------------------------------------------------------------------------------
+
+package de.ugoe.cs.quest.eventcore.userinteraction;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ *
+ * @version $Revision: $ $Date: $
+ * @author  2011, last modified by $Author: $
+ */
+//-------------------------------------------------------------------------------------------------
+public abstract class MouseInteraction implements Interaction
+{
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/TextInput.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/TextInput.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/TextInput.java	(revision 540)
@@ -0,0 +1,65 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: TextSelection.java,v $
+// Version   : $Revision: 0.0 $  $Author: Patrick $  $Date: 27.11.2011 18:11:29 $
+// Project   : TaskTreePerformanceTest
+// Creation  : 2011 by Patrick
+// Copyright : Patrick Harms, 2011
+//-------------------------------------------------------------------------------------------------
+
+package de.ugoe.cs.quest.eventcore.userinteraction;
+
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ *
+ * @version $Revision: $ $Date: $
+ * @author  2011, last modified by $Author: $
+ */
+//-------------------------------------------------------------------------------------------------
+
+public class TextInput implements Interaction
+{
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.harms.attef.userinteraction.Interaction#getName()
+   */
+  //-----------------------------------------------------------------------------------------------
+  public String getName()
+  {
+    return "TextInput";
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see java.lang.Object#toString()
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public String toString()
+  {
+    return "input text";
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (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;
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/TextSelection.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/TextSelection.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/TextSelection.java	(revision 540)
@@ -0,0 +1,65 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: TextSelection.java,v $
+// Version   : $Revision: 0.0 $  $Author: Patrick $  $Date: 27.11.2011 18:11:29 $
+// Project   : TaskTreePerformanceTest
+// Creation  : 2011 by Patrick
+// Copyright : Patrick Harms, 2011
+//-------------------------------------------------------------------------------------------------
+
+package de.ugoe.cs.quest.eventcore.userinteraction;
+
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ *
+ * @version $Revision: $ $Date: $
+ * @author  2011, last modified by $Author: $
+ */
+//-------------------------------------------------------------------------------------------------
+
+public class TextSelection implements Interaction
+{
+
+  //-----------------------------------------------------------------------------------------------
+  /* (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 "select text";
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (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;
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/UserInteractionProvider.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/UserInteractionProvider.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/UserInteractionProvider.java	(revision 540)
@@ -0,0 +1,44 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: UserInteractionObserver.java,v $
+// Version   : $Revision: 0.0 $  $Author: Patrick $  $Date: 06.11.2011 10:16:33 $
+// Project   : TaskTreePerformanceTest
+// Creation  : 2011 by Patrick
+// Copyright : Patrick Harms, 2011
+//-------------------------------------------------------------------------------------------------
+
+package de.ugoe.cs.quest.eventcore.userinteraction;
+
+import java.util.Observable;
+
+import de.ugoe.cs.quest.eventcore.guimodel.GUIElement;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ *
+ * @version $Revision: $ $Date: $
+ * @author  2011, last modified by $Author: $
+ */
+//-------------------------------------------------------------------------------------------------
+public class UserInteractionProvider extends Observable
+{
+  /** */
+  private static final UserInteractionProvider mInstance = new UserInteractionProvider();
+  
+  /**
+   * 
+   */
+  public static UserInteractionProvider getInstance()
+  {
+    return mInstance;
+  }
+  
+  /**
+   * 
+   */
+  public void notifyUserInteraction(GUIElement guiElement, Interaction interaction)
+  {
+    super.setChanged();
+    super.notifyObservers(new InteractionEvent(guiElement, interaction));
+  }
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/ValueSelection.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/ValueSelection.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/ValueSelection.java	(revision 540)
@@ -0,0 +1,110 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: TextSelection.java,v $
+// Version   : $Revision: 0.0 $  $Author: Patrick $  $Date: 27.11.2011 18:11:29 $
+// Project   : TaskTreePerformanceTest
+// Creation  : 2011 by Patrick
+// Copyright : Patrick Harms, 2011
+//-------------------------------------------------------------------------------------------------
+
+package de.ugoe.cs.quest.eventcore.userinteraction;
+
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ *
+ * @version $Revision: $ $Date: $
+ * @author  2011, last modified by $Author: $
+ */
+//-------------------------------------------------------------------------------------------------
+
+public class ValueSelection<T> implements Interaction
+{
+  /** */
+  private T mSelectedValue;
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param selectedValue
+   */
+  //-----------------------------------------------------------------------------------------------
+  public ValueSelection(T selectedValue)
+  {
+    mSelectedValue = 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;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * @return the selectedValue
+   */
+  //-----------------------------------------------------------------------------------------------
+  public T getSelectedValue()
+  {
+    return mSelectedValue;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (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) &&
+       (((mSelectedValue != null) && (mSelectedValue.equals(otherValueSelection.mSelectedValue))) ||
+        (otherValueSelection.mSelectedValue == null)));
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/test/java/de/ugoe/cs/quest/eventcore/userinteraction/InteractionEventListTest.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/test/java/de/ugoe/cs/quest/eventcore/userinteraction/InteractionEventListTest.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-patrick/src/test/java/de/ugoe/cs/quest/eventcore/userinteraction/InteractionEventListTest.java	(revision 540)
@@ -0,0 +1,360 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: InteractionEventListTest.java,v $
+// Version   : $Revision: 0.0 $  $Author: Patrick $  $Date: 04.12.2011 11:25:24 $
+// Project   : TaskTreePerformanceTest
+// Creation  : 2011 by Patrick
+// Copyright : Patrick Harms, 2011
+//-------------------------------------------------------------------------------------------------
+
+package de.ugoe.cs.quest.eventcore.userinteraction;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+
+import de.ugoe.cs.quest.eventcore.guimodel.AbstractDefaultGUIElement;
+import de.ugoe.cs.quest.eventcore.guimodel.GUIElement;
+import de.ugoe.cs.quest.eventcore.userinteraction.InteractionEvent;
+import de.ugoe.cs.quest.eventcore.userinteraction.InteractionEventList;
+import de.ugoe.cs.quest.eventcore.userinteraction.KeyPressed;
+import de.ugoe.cs.quest.eventcore.userinteraction.KeyReleased;
+import de.ugoe.cs.tasktree.keyboardmaps.VirtualKey;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ *
+ * @version $Revision: $ $Date: $
+ * @author  2011, last modified by $Author: $
+ */
+//-------------------------------------------------------------------------------------------------
+
+public class InteractionEventListTest
+{
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * 
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Test
+  public void testDifferentCombinationKeyCombinations()
+  {
+    List<InteractionEvent> checkList = new ArrayList<InteractionEvent>();
+    InteractionEventList eventList = new InteractionEventList();
+    
+    GUIElement guiElement = new AbstractDefaultGUIElement()
+    {
+      @Override
+      public boolean equals(GUIElement other)
+      {
+        return this == other;
+      }
+    };
+    
+    // check first of all a normal pressing and releasing of A and B
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_A)));
+    eventList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_A)));
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_B)));
+    eventList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_B)));
+    
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_A)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_A)));
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_B)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_B)));
+    
+    assertEquals(checkList.size(), eventList.size());
+    
+    for (int i = 0; i < checkList.size(); i++)
+    {
+      assertEquals(checkList.get(i).getInteraction(), eventList.get(i).getInteraction());
+    }
+    
+    // check what happens if A is pressed and not released before B is pressed
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_C)));
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_D)));
+    eventList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_C)));
+    eventList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_D)));
+    
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_C)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_C)));
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_D)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_D)));
+    
+    assertEquals(checkList.size(), eventList.size());
+    
+    for (int i = 0; i < checkList.size(); i++)
+    {
+      assertEquals(checkList.get(i).getInteraction(), eventList.get(i).getInteraction());
+    }
+    
+    // now SHIFT is pressed and released after all keys are pressed
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.SHIFT)));
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_E)));
+    eventList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_E)));
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_F)));
+    eventList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_F)));
+    eventList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.SHIFT)));
+    
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.SHIFT)));
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_E)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_E)));
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_F)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_F)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.SHIFT)));
+    
+    assertEquals(checkList.size(), eventList.size());
+    
+    for (int i = 0; i < checkList.size(); i++)
+    {
+      assertEquals(checkList.get(i).getInteraction(), eventList.get(i).getInteraction());
+    }
+    
+    // now SHIFT is released before the last key is released
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.SHIFT)));
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_G)));
+    eventList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_G)));
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_H)));
+    eventList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.SHIFT)));
+    eventList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_H)));
+    
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.SHIFT)));
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_G)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_G)));
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_H)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_H)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.SHIFT)));
+    
+    assertEquals(checkList.size(), eventList.size());
+    
+    for (int i = 0; i < checkList.size(); i++)
+    {
+      assertEquals(checkList.get(i).getInteraction(), eventList.get(i).getInteraction());
+    }
+    
+    // now SHIFT is released before all other keys are released
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.SHIFT)));
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_I)));
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_J)));
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_K)));
+    eventList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.SHIFT)));
+    eventList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_J)));
+    eventList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_K)));
+    eventList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_I)));
+    
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.SHIFT)));
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_I)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_I)));
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_J)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_J)));
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_K)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_K)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.SHIFT)));
+    
+    assertEquals(checkList.size(), eventList.size());
+    
+    for (int i = 0; i < checkList.size(); i++)
+    {
+      assertEquals(checkList.get(i).getInteraction(), eventList.get(i).getInteraction());
+    }
+    
+    // now SHIFT, CTRL and ALT are pressed and released after all keys are pressed
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.SHIFT)));
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.CONTROL)));
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.ALT)));
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_L)));
+    eventList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_L)));
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_M)));
+    eventList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_M)));
+    eventList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.ALT)));
+    eventList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.CONTROL)));
+    eventList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.SHIFT)));
+    
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.SHIFT)));
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.CONTROL)));
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.ALT)));
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_L)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_L)));
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_M)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_M)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.ALT)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.CONTROL)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.SHIFT)));
+    
+    assertEquals(checkList.size(), eventList.size());
+    
+    for (int i = 0; i < checkList.size(); i++)
+    {
+      assertEquals(checkList.get(i).getInteraction(), eventList.get(i).getInteraction());
+    }
+    
+    // now SHIFT, CTRL and ALT are released before the last key is released
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.SHIFT)));
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.CONTROL)));
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.ALT)));
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_N)));
+    eventList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_N)));
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_O)));
+    eventList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.ALT)));
+    eventList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.CONTROL)));
+    eventList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.SHIFT)));
+    eventList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_O)));
+    
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.SHIFT)));
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.CONTROL)));
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.ALT)));
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_N)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_N)));
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_O)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_O)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.ALT)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.CONTROL)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.SHIFT)));
+    
+    assertEquals(checkList.size(), eventList.size());
+    
+    for (int i = 0; i < checkList.size(); i++)
+    {
+      assertEquals(checkList.get(i).getInteraction(), eventList.get(i).getInteraction());
+    }
+
+    // now SHIFT, CTRL and ALT are released in another order and before some other keys are released
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.SHIFT)));
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.CONTROL)));
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.ALT)));
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_P)));
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_Q)));
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_R)));
+    eventList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_Q)));
+    eventList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.SHIFT)));
+    eventList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.ALT)));
+    eventList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.CONTROL)));
+    eventList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_R)));
+    eventList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_P)));
+    
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.SHIFT)));
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.CONTROL)));
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.ALT)));
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_P)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_P)));
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_Q)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_Q)));
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_R)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_R)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.ALT)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.CONTROL)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.SHIFT)));
+    
+    assertEquals(checkList.size(), eventList.size());
+    
+    for (int i = 0; i < checkList.size(); i++)
+    {
+      assertEquals(checkList.get(i).getInteraction(), eventList.get(i).getInteraction());
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * 
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Test
+  public void testSeveralSubsequentKeyPressedEvents()
+  {
+    List<InteractionEvent> checkList = new ArrayList<InteractionEvent>();
+    InteractionEventList eventList = new InteractionEventList();
+    
+    GUIElement guiElement = new AbstractDefaultGUIElement()
+    {
+      @Override
+      public boolean equals(GUIElement other)
+      {
+        return this == other;
+      }
+    };
+    
+    // check first of all a normal pressing and releasing of A and B
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_A)));
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_A)));
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_A)));
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_A)));
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_A)));
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_A)));
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_A)));
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_A)));
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_A)));
+    eventList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_A)));
+    
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_A)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_A)));
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_A)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_A)));
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_A)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_A)));
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_A)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_A)));
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_A)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_A)));
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_A)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_A)));
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_A)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_A)));
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_A)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_A)));
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_A)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_A)));
+    
+    assertEquals(checkList.size(), eventList.size());
+    
+    for (int i = 0; i < checkList.size(); i++)
+    {
+      assertEquals(checkList.get(i).getInteraction(), eventList.get(i).getInteraction());
+    }
+
+    // check first of all a normal pressing and releasing of A and B
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.SHIFT)));
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.SHIFT)));
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.SHIFT)));
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.SHIFT)));
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.SHIFT)));
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.SHIFT)));
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.SHIFT)));
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.SHIFT)));
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.SHIFT)));
+    eventList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_A)));
+    eventList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_A)));
+    eventList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.SHIFT)));
+    
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.SHIFT)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.SHIFT)));
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.SHIFT)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.SHIFT)));
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.SHIFT)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.SHIFT)));
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.SHIFT)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.SHIFT)));
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.SHIFT)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.SHIFT)));
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.SHIFT)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.SHIFT)));
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.SHIFT)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.SHIFT)));
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.SHIFT)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.SHIFT)));
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.SHIFT)));
+    checkList.add(new InteractionEvent(guiElement, new KeyPressed(VirtualKey.LETTER_A)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.LETTER_A)));
+    checkList.add(new InteractionEvent(guiElement, new KeyReleased(VirtualKey.SHIFT)));
+    
+    assertEquals(checkList.size(), eventList.size());
+    
+    for (int i = 0; i < checkList.size(); i++)
+    {
+      assertEquals(checkList.get(i).getInteraction(), eventList.get(i).getInteraction());
+    }
+  }
+    
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events-test/.classpath
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-test/.classpath	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-test/.classpath	(revision 540)
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/test-classes" path="src/test/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
Index: /tags/quest-pre-eventrefactoring/quest-core-events-test/.project
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-test/.project	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-test/.project	(revision 540)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>quest-core-events-test</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
Index: /tags/quest-pre-eventrefactoring/quest-core-events-test/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-test/.settings/org.eclipse.jdt.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-test/.settings/org.eclipse.jdt.core.prefs	(revision 540)
@@ -0,0 +1,5 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.6
Index: /tags/quest-pre-eventrefactoring/quest-core-events-test/.settings/org.eclipse.m2e.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-test/.settings/org.eclipse.m2e.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-test/.settings/org.eclipse.m2e.core.prefs	(revision 540)
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
Index: /tags/quest-pre-eventrefactoring/quest-core-events-test/pom.xml
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-test/pom.xml	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-test/pom.xml	(revision 540)
@@ -0,0 +1,138 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>de.ugoe.cs.quest</groupId>
+  <artifactId>quest-core-events-test</artifactId>
+  <version>0.0.1-SNAPSHOT</version>
+  <name>quest-core-events-test</name>
+  <scm>
+    <url>https://quest.informatik.uni-goettingen.de/svn/quest/trunk/quest-core-events-test</url>
+  </scm>
+  <dependencies>
+    <dependency>
+        <groupId>de.ugoe.cs.quest</groupId>
+        <artifactId>quest-core-events</artifactId>
+        <version>0.0.1-SNAPSHOT</version>
+        <scope>test</scope>
+    </dependency>
+    <dependency>
+        <groupId>junit</groupId>
+        <artifactId>junit</artifactId>
+        <version>4.8.1</version>
+        <scope>test</scope>
+    </dependency>
+    <dependency>
+	  <groupId>junit-addons</groupId>
+	  <artifactId>junit-addons</artifactId>
+	  <version>1.4</version>
+    </dependency>
+    <dependency>
+	  <groupId>nl.jqno.equalsverifier</groupId>
+	  <artifactId>equalsverifier</artifactId>
+	  <version>1.1.3</version>
+    </dependency>
+  </dependencies>
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.eclipse.m2e</groupId>
+          <artifactId>lifecycle-mapping</artifactId>
+          <version>1.0.0</version>
+          <configuration>
+            <lifecycleMappingMetadata>
+              <pluginExecutions>
+                <pluginExecution>
+                  <pluginExecutionFilter>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-dependency-plugin</artifactId>
+                    <versionRange>[1.0.0,)</versionRange>
+                    <goals>
+                      <goal>unpack</goal>
+                    </goals>
+                  </pluginExecutionFilter>
+                  <action>
+                    <ignore/>
+                  </action>
+                </pluginExecution>
+                <pluginExecution>
+                  <pluginExecutionFilter>
+                    <groupId>org.codehaus.mojo</groupId>
+                    <artifactId>emma-maven-plugin</artifactId>
+                    <versionRange>[1.0-alpha-3,)</versionRange>
+                    <goals>
+                      <goal>emma</goal>
+                    </goals>
+                  </pluginExecutionFilter>
+                  <action>
+                    <ignore/>
+                  </action>
+                </pluginExecution>
+              </pluginExecutions>
+            </lifecycleMappingMetadata>
+          </configuration>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>2.3.2</version>
+        <configuration>
+          <source>1.6</source>
+          <target>1.6</target>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-dependency-plugin</artifactId>
+        <version>2.4</version>
+        <executions>
+          <execution>
+            <id>unpack</id>
+            <phase>process-classes</phase>
+            <goals>
+              <goal>unpack</goal>
+            </goals>
+            <configuration>
+              <artifactItems>
+                <artifactItem>
+                  <groupId>de.ugoe.cs.quest</groupId>
+                  <artifactId>quest-core-events</artifactId>
+                  <version>0.0.1-SNAPSHOT</version>
+                  <outputDirectory>${project.build.directory}/classes</outputDirectory>
+                </artifactItem>
+              </artifactItems>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>emma-maven-plugin</artifactId>
+        <version>1.0-alpha-3</version>
+        <inherited>true</inherited>          
+        <executions>
+          <execution>
+            <phase>process-classes</phase>
+            <goals>
+              <goal>emma</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <version>2.3.2</version>
+        <executions>
+          <execution>
+            <goals>
+              <goal>test-jar</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>
Index: /tags/quest-pre-eventrefactoring/quest-core-events-test/src/test/java/de/ugoe/cs/quest/SequenceInstanceOfTest.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-test/src/test/java/de/ugoe/cs/quest/SequenceInstanceOfTest.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-test/src/test/java/de/ugoe/cs/quest/SequenceInstanceOfTest.java	(revision 540)
@@ -0,0 +1,100 @@
+package de.ugoe.cs.quest;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.junit.*;
+
+import static org.junit.Assert.*;
+
+import de.ugoe.cs.quest.SequenceInstanceOf;
+import de.ugoe.cs.quest.eventcore.Event;
+
+
+/**
+ * The class <code>SequenceInstanceOfTest</code> contains tests for the
+ * class <code>{@link SequenceInstanceOf}</code>.
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class SequenceInstanceOfTest {
+	
+	@Test
+	public void TestIsCollectionOfSequences_1() throws Exception {
+		Collection<List<? extends Event<?>>> sequences = new LinkedList<List<? extends Event<?>>>();
+		List<Event<?>> sequence1 = new ArrayList<Event<?>>();
+		sequence1.add(new Event<String>("a"));
+		sequences.add(sequence1);
+		
+		boolean result = SequenceInstanceOf.isCollectionOfSequences(sequences);
+		assertTrue(result);
+	}
+	
+	@Test
+	public void TestIsCollectionOfSequences_2() throws Exception {
+		Collection<List<? extends Event<?>>> sequences = new LinkedList<List<? extends Event<?>>>();
+		List<Event<?>> sequence1 = new ArrayList<Event<?>>();
+		sequences.add(sequence1);
+		
+		boolean result = SequenceInstanceOf.isCollectionOfSequences(sequences);
+		assertFalse(result);
+	}
+	
+	@Test
+	public void TestIsCollectionOfSequences_3() throws Exception {
+		Collection<List<? extends Event<?>>> sequences = new LinkedList<List<? extends Event<?>>>();
+		
+		boolean result = SequenceInstanceOf.isCollectionOfSequences(sequences);
+		assertFalse(result);
+	}
+	
+	@Test
+	public void TestIsCollectionOfSequences_4() throws Exception {
+		boolean result = SequenceInstanceOf.isCollectionOfSequences(null);
+		assertFalse(result);
+	}
+	
+	@Test
+	public void TestIsCollectionOfSequences_5() throws Exception {
+		boolean result = SequenceInstanceOf.isCollectionOfSequences(new Object());
+		assertFalse(result);
+	}
+	
+	@Test
+	public void TestIsEventSequence_1() throws Exception {
+		List<Event<?>> sequence = new ArrayList<Event<?>>();
+		sequence.add(new Event<String>("a"));
+		
+		boolean result = SequenceInstanceOf.isEventSequence(sequence);
+		assertTrue(result);
+	}
+	
+	@Test
+	public void TestIsEventSequence_2() throws Exception {
+		List<Event<?>> sequence = new ArrayList<Event<?>>();
+		
+		boolean result = SequenceInstanceOf.isEventSequence(sequence);
+		assertFalse(result);
+	}
+	
+	@Test
+	public void TestIsEventSequence_3() throws Exception {
+		boolean result = SequenceInstanceOf.isEventSequence(null);
+		assertFalse(result);
+	}
+	
+	@Test
+	public void TestIsEventSequence_4() throws Exception {
+		boolean result = SequenceInstanceOf.isEventSequence(new Object());
+		assertFalse(result);
+	}
+	
+	
+	
+	public static void main(String[] args) {
+		new org.junit.runner.JUnitCore().run(SequenceInstanceOfTest.class);
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events-test/src/test/java/de/ugoe/cs/quest/eventcore/EventTest.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-test/src/test/java/de/ugoe/cs/quest/eventcore/EventTest.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-test/src/test/java/de/ugoe/cs/quest/eventcore/EventTest.java	(revision 540)
@@ -0,0 +1,406 @@
+package de.ugoe.cs.quest.eventcore;
+
+import nl.jqno.equalsverifier.EqualsVerifier;
+import nl.jqno.equalsverifier.Warning;
+
+import org.junit.*;
+
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.eventcore.ReplayableEvent;
+
+import static org.junit.Assert.*;
+
+/**
+ * The class <code>EventTest</code> contains tests for the class
+ * <code>{@link Event}</code>.
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class EventTest {
+
+	@Test
+	public void testEvent_1() throws Exception {
+		String type = "typeString";
+
+		Event<String> result = new Event<String>(type);
+
+		assertNotNull(result);
+		assertEquals(type, result.type);
+		assertNull(result.target);
+		assertNull(result.targetShort);
+		assertEquals("", result.idInfo);
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testEvent_2() throws Exception {
+		new Event<String>(null);
+	}
+
+	@Test
+	public void testEquals_1() throws Exception {
+		String type1 = "typeString";
+		String type2 = "typeString";
+		Event<String> fixture = new Event<String>(type1);
+		Event<String> other = new Event<String>(type2);
+
+		boolean result = fixture.equals(other);
+
+		assertTrue(result);
+	}
+
+	@Test
+	public void testEquals_2() throws Exception {
+		String type1 = "typeString1";
+		String type2 = "typeString2";
+		Event<String> fixture = new Event<String>(type1);
+		Event<String> other = new Event<String>(type2);
+
+		boolean result = fixture.equals(other);
+
+		assertFalse(result);
+	}
+
+	@Test
+	public void testEquals_3() throws Exception {
+		String type1 = "typeString";
+		String type2 = "typeString";
+		String target1 = "target";
+		String target2 = "target";
+		Event<String> fixture = new Event<String>(type1);
+		fixture.target = target1;
+		Event<String> other = new Event<String>(type2);
+		other.target = target2;
+
+		boolean result = fixture.equals(other);
+
+		assertTrue(result);
+	}
+
+	@Test
+	public void testEquals_4() throws Exception {
+		String type1 = "typeString1";
+		String type2 = "typeString2";
+		String target1 = "target";
+		String target2 = "target";
+		Event<String> fixture = new Event<String>(type1);
+		fixture.target = target1;
+		Event<String> other = new Event<String>(type2);
+		other.target = target2;
+
+		boolean result = fixture.equals(other);
+
+		assertFalse(result);
+	}
+
+	@Test
+	public void testEquals_5() throws Exception {
+		String type1 = "typeString";
+		String type2 = "typeString";
+		String target1 = "target1";
+		String target2 = "target2";
+		Event<String> fixture = new Event<String>(type1);
+		fixture.target = target1;
+		Event<String> other = new Event<String>(type2);
+		other.target = target2;
+
+		boolean result = fixture.equals(other);
+
+		assertFalse(result);
+	}
+
+	@Test
+	public void testEquals_6() throws Exception {
+		String type = "typeString";
+		Event<String> fixture = new Event<String>(type);
+
+		boolean result = fixture.equals(fixture);
+
+		assertTrue(result);
+	}
+
+	@Test
+	public void testEqualsContract() throws Exception {
+		EqualsVerifier.forClass(Event.class)
+				.suppress(Warning.NONFINAL_FIELDS).withRedefinedSubclass(ReplayableEvent.class)
+				.verify();
+	}
+
+	@Test
+	public void testGetIdInfo_fixture_1() throws Exception {
+		String type = "typeString";
+		String idInfo = "idInfoString";
+		Event<String> fixture = new Event<String>(type);
+		fixture.idInfo = idInfo;
+
+		String result = fixture.getIdInfo();
+
+		assertEquals(idInfo, result);
+	}
+
+	@Test
+	public void testGetShortId_1() throws Exception {
+		String type = "typeString";
+		String targetShort = "targetShortString";
+		Event<String> fixture = new Event<String>(type);
+		fixture.targetShort = targetShort;
+
+		String result = fixture.getShortId();
+
+		assertEquals("targetShortString.typeString", result);
+	}
+
+	@Test
+	public void testGetShortId_2() throws Exception {
+		String type = "typeString";
+		String targetShort = "targetShortString";
+		String idInfo = "idInfoString";
+		Event<String> fixture = new Event<String>(type);
+		fixture.targetShort = targetShort;
+		fixture.idInfo = idInfo;
+
+		String result = fixture.getShortId();
+
+		assertEquals("targetShortString.typeString.idInfoString", result);
+	}
+
+	@Test
+	public void testGetShortId_3() throws Exception {
+		String type = "typeString";
+		String target = "targetString";
+		Event<String> fixture = new Event<String>(type);
+		fixture.target = target;
+
+		String result = fixture.getShortId();
+
+		assertEquals("targetString.typeString", result);
+	}
+
+	@Test
+	public void testGetStandardId_1() throws Exception {
+		String type = "typeString";
+		String target = "targetString";
+		Event<String> fixture = new Event<String>(type);
+		fixture.target = target;
+
+		String result = fixture.getStandardId();
+
+		assertEquals("targetString.typeString", result);
+	}
+
+	@Test
+	public void testGetStandardId_2() throws Exception {
+		String type = "typeString";
+		String target = "targetString";
+		String idInfo = "idInfoString";
+		Event<String> fixture = new Event<String>(type);
+		fixture.target = target;
+		fixture.idInfo = idInfo;
+
+		String result = fixture.getStandardId();
+
+		assertEquals("targetString.typeString.idInfoString", result);
+	}
+
+	@Test
+	public void testGetStandardId_3() throws Exception {
+		String type = "typeString";
+		Event<String> fixture = new Event<String>(type);
+
+		String result = fixture.getStandardId();
+
+		assertEquals("typeString", result);
+	}
+
+	@Test
+	public void testGetStandardId_4() throws Exception {
+		String type = "typeString";
+		String idInfo = "idInfoString";
+		Event<String> fixture = new Event<String>(type);
+		fixture.idInfo = idInfo;
+
+		String result = fixture.getStandardId();
+
+		assertEquals("typeString.idInfoString", result);
+	}
+
+	@Test
+	public void testGetTarget_1() throws Exception {
+		String type = "typeString";
+		String target = "targetString";
+		Event<String> fixture = new Event<String>(type);
+		fixture.target = target;
+
+		String result = fixture.getTarget();
+
+		assertEquals(target, result);
+	}
+
+	@Test
+	public void testGetTarget_2() throws Exception {
+		String type = "typeString";
+		Event<String> fixture = new Event<String>(type);
+
+		String result = fixture.getTarget();
+
+		assertNull(result);
+	}
+
+	@Test
+	public void testGetTargetShort_1() throws Exception {
+		String type = "typeString";
+		String targetShort = "targetShort";
+		Event<String> fixture = new Event<String>(type);
+		fixture.targetShort = targetShort;
+
+		String result = fixture.getTargetShort();
+
+		assertEquals(targetShort, result);
+	}
+
+	@Test
+	public void testGetTargetShort_2() throws Exception {
+		String type = "typeString";
+		Event<String> fixture = new Event<String>(type);
+
+		String result = fixture.getTargetShort();
+
+		assertNull(result);
+	}
+
+	@Test
+	public void testGetType_1() throws Exception {
+		String type = "typeString";
+		Event<String> fixture = new Event<String>(type);
+
+		String result = fixture.getType();
+
+		assertEquals(type, result);
+	}
+
+	@Test
+	public void testSetIdInfo_fixture_1() throws Exception {
+		String type = "typeString";
+		String idInfo = "idInfoString";
+		Event<String> fixture = new Event<String>(type);
+
+		fixture.setIdInfo(idInfo);
+
+		assertEquals(idInfo, fixture.idInfo);
+	}
+
+	@Test
+	public void testSetIdInfo_2() throws Exception {
+		String type = "typeString";
+		String idInfo = null;
+		Event<String> fixture = new Event<String>(type);
+
+		fixture.setIdInfo(idInfo);
+
+		assertEquals(idInfo, fixture.idInfo);
+	}
+
+	@Test
+	public void testSetTarget_1() throws Exception {
+		String type = "typeString";
+		String target = "targetString";
+		Event<String> fixture = new Event<String>(type);
+
+		boolean result = fixture.setTarget(target);
+
+		assertTrue(result);
+		assertEquals(target, fixture.target);
+	}
+
+	@Test
+	public void testSetTarget_2() throws Exception {
+		String type = "typeString";
+		String target1 = "targetString1";
+		String target2 = "targetString2";
+		Event<String> fixture = new Event<String>(type);
+		fixture.target = target1;
+
+		boolean result = fixture.setTarget(target2);
+
+		assertFalse(result);
+		assertEquals(target1, fixture.target);
+	}
+
+	@Test
+	public void testSetTargetShort_1() throws Exception {
+		String type = "typeString";
+		String targetShort = "targetShortString";
+		Event<String> fixture = new Event<String>(type);
+
+		boolean result = fixture.setTargetShort(targetShort);
+
+		assertTrue(result);
+		assertEquals(targetShort, fixture.targetShort);
+	}
+
+	@Test
+	public void testSetTargetShort_2() throws Exception {
+		String type = "typeString";
+		String targetShort1 = "targetShortString1";
+		String targetShort2 = "targetShortString2";
+		Event<String> fixture = new Event<String>(type);
+		fixture.targetShort = targetShort1;
+
+		boolean result = fixture.setTargetShort(targetShort2);
+
+		assertFalse(result);
+		assertEquals(targetShort1, fixture.targetShort);
+	}
+
+	@Test
+	public void testToString_1() throws Exception {
+		String type = "typeString";
+		String target = "targetString";
+		Event<String> fixture = new Event<String>(type);
+		fixture.target = target;
+
+		String result = fixture.toString();
+
+		assertEquals("targetString.typeString", result);
+	}
+
+	@Test
+	public void testToString_2() throws Exception {
+		String type = "typeString";
+		String target = "targetString";
+		String idInfo = "idInfoString";
+		Event<String> fixture = new Event<String>(type);
+		fixture.target = target;
+		fixture.idInfo = idInfo;
+
+		String result = fixture.toString();
+
+		assertEquals("targetString.typeString.idInfoString", result);
+	}
+
+	@Test
+	public void testToString_3() throws Exception {
+		String type = "typeString";
+		Event<String> fixture = new Event<String>(type);
+
+		String result = fixture.toString();
+
+		assertEquals("typeString", result);
+	}
+
+	@Test
+	public void testToString_4() throws Exception {
+		String type = "typeString";
+		String idInfo = "idInfoString";
+		Event<String> fixture = new Event<String>(type);
+		fixture.idInfo = idInfo;
+
+		String result = fixture.toString();
+
+		assertEquals("typeString.idInfoString", result);
+	}
+
+	public static void main(String[] args) {
+		new org.junit.runner.JUnitCore().run(EventTest.class);
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events-test/src/test/java/de/ugoe/cs/quest/eventcore/ReplayableEventTest.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-test/src/test/java/de/ugoe/cs/quest/eventcore/ReplayableEventTest.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-test/src/test/java/de/ugoe/cs/quest/eventcore/ReplayableEventTest.java	(revision 540)
@@ -0,0 +1,474 @@
+package de.ugoe.cs.quest.eventcore;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import junitx.framework.ListAssert;
+import de.ugoe.cs.quest.IReplayDecorator;
+import de.ugoe.cs.quest.eventcore.ReplayableEvent;
+import de.ugoe.cs.quest.eventcore.mock.MockReplayable;
+
+import org.junit.*;
+import static org.junit.Assert.*;
+
+/**
+ * The class <code>ReplayableEventTest</code> contains tests for the class
+ * <code>{@link ReplayableEvent}</code>.
+ * 
+ * @generatedBy CodePro at 12/20/11 10:17 AM
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class ReplayableEventTest {
+
+	private static class StubReplayDecorator implements IReplayDecorator {
+
+		private static final long serialVersionUID = 1L;
+
+		@Override
+		public String getHeader() {
+			return null;
+		}
+
+		@Override
+		public String getFooter() {
+			return null;
+		}
+
+		@Override
+		public String getSessionHeader(int sessionId) {
+			return null;
+		}
+
+		@Override
+		public String getSessionFooter(int sessionId) {
+			return null;
+		}
+		
+	}
+
+	@Test
+	public void testReplayableEvent_1() throws Exception {
+		String type = "typeString";
+
+		ReplayableEvent<MockReplayable> result = new ReplayableEvent<MockReplayable>(
+				type);
+
+		assertNotNull(result);
+		assertNotNull(result.replayEvents);
+		assertTrue(result.replayEvents.isEmpty());
+		assertEquals(true, result.replayValid);
+		assertEquals(null, result.decorator);
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testReplayableEvent_2() throws Exception {
+		new ReplayableEvent<MockReplayable>(null);
+	}
+
+	@Test
+	public void testAddReplayEvent_1() throws Exception {
+		String type = "typeString";
+		String replayableReplay = "replayString";
+		String replaybleTarget = "replayTargetString";
+		MockReplayable replayable = new MockReplayable(replayableReplay,
+				replaybleTarget);
+		ReplayableEvent<MockReplayable> fixture = new ReplayableEvent<MockReplayable>(
+				type);
+		fixture.addReplayEvent(replayable);
+		
+		
+		assertEquals(1, fixture.replayEvents.size());
+		assertEquals(replayable, fixture.replayEvents.get(0));
+	}
+	
+	@Test
+	public void testAddReplayEvent_2() throws Exception {
+		String type = "typeString";
+		String replayableReplay1 = "replayString1";
+		String replayableReplay2 = "replayString2";
+		String replaybleTarget1 = "replayTargetString1";
+		String replaybleTarget2 = "replayTargetString2";
+		MockReplayable replayable1 = new MockReplayable(replayableReplay1,
+				replaybleTarget1);
+		MockReplayable replayable2 = new MockReplayable(replayableReplay2, replaybleTarget2);
+		ReplayableEvent<MockReplayable> fixture = new ReplayableEvent<MockReplayable>(
+				type);
+		fixture.addReplayEvent(replayable1);
+		fixture.addReplayEvent(replayable2);
+		
+		
+		assertEquals(2, fixture.replayEvents.size());
+		assertEquals(replayable1, fixture.replayEvents.get(0));
+		assertEquals(replayable2, fixture.replayEvents.get(1));
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class )
+	public void testAddReplayEvent_fixture_3() throws Exception {
+		String type = "typeString";
+		ReplayableEvent<MockReplayable> fixture = new ReplayableEvent<MockReplayable>(
+				type);
+		fixture.addReplayEvent(null);
+	}
+
+	@Test
+	public void testAddReplaySequence_1() throws Exception {
+		String type = "typeString";
+		String replayableReplay1 = "replayString1";
+		String replayableReplay2 = "replayString2";
+		String replaybleTarget1 = "replayTargetString1";
+		String replaybleTarget2 = "replayTargetString2";
+		MockReplayable replayable1 = new MockReplayable(replayableReplay1,
+				replaybleTarget1);
+		MockReplayable replayable2 = new MockReplayable(replayableReplay2, replaybleTarget2);
+		List<MockReplayable> replaySequence = new LinkedList<MockReplayable>();
+		replaySequence.add(replayable1);
+		replaySequence.add(replayable2);
+		ReplayableEvent<MockReplayable> fixture = new ReplayableEvent<MockReplayable>(
+				type);
+		
+		fixture.addReplaySequence(replaySequence);		
+		
+		assertEquals(2, fixture.replayEvents.size());
+		assertEquals(replayable1, fixture.replayEvents.get(0));
+		assertEquals(replayable2, fixture.replayEvents.get(1));
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class )
+	public void testAddReplaySequence_2() throws Exception {
+		String type = "typeString";
+		ReplayableEvent<MockReplayable> fixture = new ReplayableEvent<MockReplayable>(
+				type);
+		
+		fixture.addReplaySequence(null);	
+	}
+
+	@Test
+	public void testEquals_1() throws Exception {
+		String type = "typeString";
+		boolean replayValid = true;
+		String replayableReplay1 = "replayString1";
+		String replayableReplay2 = "replayString2";
+		String replayableTarget1 = "replayTargetString1";
+		String replayableTarget2 = "replayTargetString2";
+		MockReplayable replayable1 = new MockReplayable(replayableReplay1,
+				replayableTarget1);
+		MockReplayable replayable2 = new MockReplayable(replayableReplay2, replayableTarget2);
+		List<MockReplayable> replaySequence = new LinkedList<MockReplayable>();
+		replaySequence.add(replayable1);
+		replaySequence.add(replayable2);
+		ReplayableEvent<MockReplayable> fixture = new ReplayableEvent<MockReplayable>(
+				type);
+		fixture.replayEvents = replaySequence;
+		fixture.replayValid = replayValid;
+		
+		String typeOther = "typeString";
+		boolean replayValidOther = true;
+		String replayableReplayOther1 = "replayString1";
+		String replayableReplayOther2 = "replayString2";
+		String replaybleTargetOther1 = "replayTargetString1";
+		String replaybleTargetOther2 = "replayTargetString2";
+		MockReplayable replayableOther1 = new MockReplayable(replayableReplayOther1,
+				replaybleTargetOther1);
+		MockReplayable replayableOther2 = new MockReplayable(replayableReplayOther2, replaybleTargetOther2);
+		List<MockReplayable> replaySequenceOther = new LinkedList<MockReplayable>();
+		replaySequenceOther.add(replayableOther1);
+		replaySequenceOther.add(replayableOther2);
+		ReplayableEvent<MockReplayable> other = new ReplayableEvent<MockReplayable>(
+				typeOther);
+		other.replayEvents = replaySequenceOther;
+		other.replayValid = replayValidOther;
+
+		boolean result = fixture.equals(other);
+
+		assertEquals(true, result);
+	}
+	
+	@Test
+	public void testEquals_2() throws Exception {
+		String type = "typeString";
+		boolean replayValid = true;
+		String replayableReplay1 = "replayString1";
+		String replayableReplay2 = "replayString2";
+		String replayableTarget1 = "replayTargetString1";
+		String replayableTarget2 = "replayTargetString2";
+		MockReplayable replayable1 = new MockReplayable(replayableReplay1,
+				replayableTarget1);
+		MockReplayable replayable2 = new MockReplayable(replayableReplay2, replayableTarget2);
+		List<MockReplayable> replaySequence = new LinkedList<MockReplayable>();
+		replaySequence.add(replayable1);
+		replaySequence.add(replayable2);
+		ReplayableEvent<MockReplayable> fixture = new ReplayableEvent<MockReplayable>(
+				type);
+		fixture.replayEvents = replaySequence;
+		fixture.replayValid = replayValid;
+		
+		String typeOther = "typeString2";
+		boolean replayValidOther = true;
+		String replayableReplayOther1 = "replayString1";
+		String replayableReplayOther2 = "replayString2";
+		String replaybleTargetOther1 = "replayTargetString1";
+		String replaybleTargetOther2 = "replayTargetString2";
+		MockReplayable replayableOther1 = new MockReplayable(replayableReplayOther1,
+				replaybleTargetOther1);
+		MockReplayable replayableOther2 = new MockReplayable(replayableReplayOther2, replaybleTargetOther2);
+		List<MockReplayable> replaySequenceOther = new LinkedList<MockReplayable>();
+		replaySequenceOther.add(replayableOther1);
+		replaySequenceOther.add(replayableOther2);
+		ReplayableEvent<MockReplayable> other = new ReplayableEvent<MockReplayable>(
+				typeOther);
+		other.replayEvents = replaySequenceOther;
+		other.replayValid = replayValidOther;
+
+		boolean result = fixture.equals(other);
+
+		assertEquals(false, result);
+	}
+	
+	@Test
+	public void testEquals_3() throws Exception {
+		String type = "typeString";
+		boolean replayValid = true;
+		String replayableReplay1 = "replayString1";
+		String replayableReplay2 = "replayString2";
+		String replayableTarget1 = "replayTargetString1";
+		String replayableTarget2 = "replayTargetString2";
+		MockReplayable replayable1 = new MockReplayable(replayableReplay1,
+				replayableTarget1);
+		MockReplayable replayable2 = new MockReplayable(replayableReplay2, replayableTarget2);
+		List<MockReplayable> replaySequence = new LinkedList<MockReplayable>();
+		replaySequence.add(replayable1);
+		replaySequence.add(replayable2);
+		ReplayableEvent<MockReplayable> fixture = new ReplayableEvent<MockReplayable>(
+				type);
+		fixture.replayEvents = replaySequence;
+		fixture.replayValid = replayValid;
+		
+		String typeOther = "typeString";
+		boolean replayValidOther = true;
+		String replayableReplayOther1 = "replayString3";
+		String replayableReplayOther2 = "replayString2";
+		String replaybleTargetOther1 = "replayTargetString1";
+		String replaybleTargetOther2 = "replayTargetString2";
+		MockReplayable replayableOther1 = new MockReplayable(replayableReplayOther1,
+				replaybleTargetOther1);
+		MockReplayable replayableOther2 = new MockReplayable(replayableReplayOther2, replaybleTargetOther2);
+		List<MockReplayable> replaySequenceOther = new LinkedList<MockReplayable>();
+		replaySequenceOther.add(replayableOther1);
+		replaySequenceOther.add(replayableOther2);
+		ReplayableEvent<MockReplayable> other = new ReplayableEvent<MockReplayable>(
+				typeOther);
+		other.replayEvents = replaySequenceOther;
+		other.replayValid = replayValidOther;
+
+		boolean result = fixture.equals(other);
+
+		assertEquals(true, result);
+	}
+	
+	@Test
+	public void testEquals_4() throws Exception {
+		String type = "typeString";
+		boolean replayValid = true;
+		String replayableReplay1 = "replayString1";
+		String replayableReplay2 = "replayString2";
+		String replayableTarget1 = "replayTargetString1";
+		String replayableTarget2 = "replayTargetString2";
+		MockReplayable replayable1 = new MockReplayable(replayableReplay1,
+				replayableTarget1);
+		MockReplayable replayable2 = new MockReplayable(replayableReplay2, replayableTarget2);
+		List<MockReplayable> replaySequence = new LinkedList<MockReplayable>();
+		replaySequence.add(replayable1);
+		replaySequence.add(replayable2);
+		ReplayableEvent<MockReplayable> fixture = new ReplayableEvent<MockReplayable>(
+				type);
+		fixture.replayEvents = replaySequence;
+		fixture.replayValid = replayValid;
+		
+		String typeOther = "typeString";
+		boolean replayValidOther = true;
+		String replayableReplayOther1 = "replayString1";
+		String replayableReplayOther2 = "replayString3";
+		String replaybleTargetOther1 = "replayTargetString1";
+		String replaybleTargetOther2 = "replayTargetString2";
+		MockReplayable replayableOther1 = new MockReplayable(replayableReplayOther1,
+				replaybleTargetOther1);
+		MockReplayable replayableOther2 = new MockReplayable(replayableReplayOther2, replaybleTargetOther2);
+		List<MockReplayable> replaySequenceOther = new LinkedList<MockReplayable>();
+		replaySequenceOther.add(replayableOther1);
+		replaySequenceOther.add(replayableOther2);
+		ReplayableEvent<MockReplayable> other = new ReplayableEvent<MockReplayable>(
+				typeOther);
+		other.replayEvents = replaySequenceOther;
+		other.replayValid = replayValidOther;
+
+		boolean result = fixture.equals(other);
+
+		assertEquals(true, result);
+	}
+	
+	@Test
+	public void testEquals_5() throws Exception {
+		String type = "typeString";
+		boolean replayValid = true;
+		String replayableReplay1 = "replayString1";
+		String replayableReplay2 = "replayString2";
+		String replayableTarget1 = "replayTargetString1";
+		String replayableTarget2 = "replayTargetString2";
+		MockReplayable replayable1 = new MockReplayable(replayableReplay1,
+				replayableTarget1);
+		MockReplayable replayable2 = new MockReplayable(replayableReplay2, replayableTarget2);
+		List<MockReplayable> replaySequence = new LinkedList<MockReplayable>();
+		replaySequence.add(replayable1);
+		replaySequence.add(replayable2);
+		ReplayableEvent<MockReplayable> fixture = new ReplayableEvent<MockReplayable>(
+				type);
+		fixture.replayEvents = replaySequence;
+		fixture.replayValid = replayValid;
+		
+		String typeOther = "typeString";
+		boolean replayValidOther = false;
+		String replayableReplayOther1 = "replayString1";
+		String replayableReplayOther2 = "replayString2";
+		String replaybleTargetOther1 = "replayTargetString1";
+		String replaybleTargetOther2 = "replayTargetString2";
+		MockReplayable replayableOther1 = new MockReplayable(replayableReplayOther1,
+				replaybleTargetOther1);
+		MockReplayable replayableOther2 = new MockReplayable(replayableReplayOther2, replaybleTargetOther2);
+		List<MockReplayable> replaySequenceOther = new LinkedList<MockReplayable>();
+		replaySequenceOther.add(replayableOther1);
+		replaySequenceOther.add(replayableOther2);
+		ReplayableEvent<MockReplayable> other = new ReplayableEvent<MockReplayable>(
+				typeOther);
+		other.replayEvents = replaySequenceOther;
+		other.replayValid = replayValidOther;
+
+		boolean result = fixture.equals(other);
+
+		assertEquals(true, result);
+	}
+	
+	@Test
+	public void testEquals_6() throws Exception {
+		String type = "typeString";
+		boolean replayValid = true;
+		String replayableReplay1 = "replayString1";
+		String replayableReplay2 = "replayString2";
+		String replayableTarget1 = "replayTargetString1";
+		String replayableTarget2 = "replayTargetString2";
+		MockReplayable replayable1 = new MockReplayable(replayableReplay1,
+				replayableTarget1);
+		MockReplayable replayable2 = new MockReplayable(replayableReplay2, replayableTarget2);
+		List<MockReplayable> replaySequence = new LinkedList<MockReplayable>();
+		replaySequence.add(replayable1);
+		replaySequence.add(replayable2);
+		ReplayableEvent<MockReplayable> fixture = new ReplayableEvent<MockReplayable>(
+				type);
+		fixture.replayEvents = replaySequence;
+		fixture.replayValid = replayValid;
+
+		boolean result = fixture.equals(fixture);
+
+		assertEquals(true, result);
+	}
+
+	@Test
+	public void testGetReplayDecorator_1() throws Exception {
+		String type = "typeString";
+		StubReplayDecorator decorator = new StubReplayDecorator();
+		ReplayableEvent<MockReplayable> fixture = new ReplayableEvent<MockReplayable>(
+				type);
+		fixture.decorator = decorator; 
+
+		IReplayDecorator result = fixture.getReplayDecorator();
+
+		assertEquals(decorator, result);
+	}
+
+	@Test
+	public void testGetReplayMessages_1() throws Exception {
+		String type = "typeString";
+		String replayableReplay1 = "replayString1";
+		String replayableReplay2 = "replayString2";
+		String replayableTarget1 = "replayTargetString1";
+		String replayableTarget2 = "replayTargetString2";
+		MockReplayable replayable1 = new MockReplayable(replayableReplay1,
+				replayableTarget1);
+		MockReplayable replayable2 = new MockReplayable(replayableReplay2, replayableTarget2);
+		List<MockReplayable> replaySequence = new LinkedList<MockReplayable>();
+		replaySequence.add(replayable1);
+		replaySequence.add(replayable2);
+		ReplayableEvent<MockReplayable> fixture = new ReplayableEvent<MockReplayable>(
+				type);
+		fixture.replayEvents = replaySequence;
+
+		List<MockReplayable> result = fixture.getReplayMessages();
+
+		ListAssert.assertEquals(replaySequence, result);
+	}
+
+	@Test
+	public void testHasValidReplay_1() throws Exception {
+		String type = "typeString";
+		boolean replayValid = true;
+		ReplayableEvent<MockReplayable> fixture = new ReplayableEvent<MockReplayable>(
+				type);
+		fixture.replayValid = replayValid;
+
+		boolean result = fixture.hasValidReplay();
+
+		assertEquals(replayValid, result);
+	}
+	
+	@Test
+	public void testHasValidReplay_2() throws Exception {
+		String type = "typeString";
+		boolean replayValid = false;
+		ReplayableEvent<MockReplayable> fixture = new ReplayableEvent<MockReplayable>(
+				type);
+		fixture.replayValid = replayValid;
+
+		boolean result = fixture.hasValidReplay();
+
+		assertEquals(replayValid, result);
+	}
+
+	@Test
+	public void testInvalidateReplay_1() throws Exception {
+		String type = "typeString";
+		ReplayableEvent<MockReplayable> fixture = new ReplayableEvent<MockReplayable>(
+				type);
+		
+		fixture.invalidateReplay();
+
+		assertFalse(fixture.replayValid);
+	}
+	
+	@Test
+	public void testInvalidateReplay_2() throws Exception {
+		String type = "typeString";
+		ReplayableEvent<MockReplayable> fixture = new ReplayableEvent<MockReplayable>(
+				type);
+		
+		fixture.invalidateReplay();
+		fixture.invalidateReplay();
+
+		assertFalse(fixture.replayValid);
+	}
+
+	@Test
+	public void testSetDecorator_fixture_1() throws Exception {
+		String type = "typeString";
+		StubReplayDecorator decorator = new StubReplayDecorator();
+		ReplayableEvent<MockReplayable> fixture = new ReplayableEvent<MockReplayable>(
+				type);
+
+		fixture.setDecorator(decorator);
+
+		assertEquals(decorator, fixture.decorator);
+	}
+
+	public static void main(String[] args) {
+		new org.junit.runner.JUnitCore().run(ReplayableEventTest.class);
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events-test/src/test/java/de/ugoe/cs/quest/eventcore/TestAll.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-test/src/test/java/de/ugoe/cs/quest/eventcore/TestAll.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-test/src/test/java/de/ugoe/cs/quest/eventcore/TestAll.java	(revision 540)
@@ -0,0 +1,25 @@
+package de.ugoe.cs.quest.eventcore;
+
+import org.junit.runner.JUnitCore;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+/**
+ * The class <code>TestAll</code> builds a suite that can be used to run all
+ * of the tests within its package as well as within any subpackages of its
+ * package.
+ *
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+	EventTest.class,
+	ReplayableEventTest.class
+})
+public class TestAll {
+
+	public static void main(String[] args) {
+		JUnitCore.runClasses(new Class[] { TestAll.class });
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events-test/src/test/java/de/ugoe/cs/quest/eventcore/mock/MockReplayable.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events-test/src/test/java/de/ugoe/cs/quest/eventcore/mock/MockReplayable.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events-test/src/test/java/de/ugoe/cs/quest/eventcore/mock/MockReplayable.java	(revision 540)
@@ -0,0 +1,61 @@
+package de.ugoe.cs.quest.eventcore.mock;
+
+import de.ugoe.cs.quest.eventcore.IReplayable;
+
+public class MockReplayable implements IReplayable {
+
+	private static final long serialVersionUID = 1L;
+
+	final String replay;
+	final String target;
+
+	public MockReplayable(String replay, String target) {
+		this.replay = replay;
+		this.target = target;
+	}
+
+	@Override
+	public String getReplay() {
+		return replay;
+	}
+
+	@Override
+	public String getTarget() {
+		return target;
+	}
+
+	@Override
+	public boolean equals(Object other) {
+		if (this == other) {
+			return true;
+		}
+		if (other instanceof MockReplayable) {
+			if (replay != null && target != null) {
+				return replay.equals(((MockReplayable) other).replay)
+						&& target.equals(((MockReplayable) other).target);
+			} else if (replay != null && target == null) {
+				return replay.equals(((MockReplayable) other).replay)
+						&& ((MockReplayable) other).target == null;
+			} else if (replay == null && target != null) {
+				return ((MockReplayable) other).replay == null
+						&& target.equals(((MockReplayable) other).target);
+			} else {
+				return ((MockReplayable) other).replay == null
+						&& ((MockReplayable) other).target == null;
+			}
+		}
+		return false;
+	}
+	
+	@Override
+	public int hashCode() {
+		int hashCode = 17;
+		if( replay!=null ) {
+			hashCode *= replay.hashCode();
+		}
+		if( target!=null ) {
+			hashCode *= target.hashCode();
+		}
+		return hashCode;
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events/.classpath
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events/.classpath	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events/.classpath	(revision 540)
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/classes" path="src/main/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
Index: /tags/quest-pre-eventrefactoring/quest-core-events/.project
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events/.project	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events/.project	(revision 540)
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>quest-core-events</name>
+	<comment></comment>
+	<projects>
+		<project>Build</project>
+		<project>JavaHelperLib</project>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
Index: /tags/quest-pre-eventrefactoring/quest-core-events/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events/.settings/org.eclipse.jdt.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events/.settings/org.eclipse.jdt.core.prefs	(revision 540)
@@ -0,0 +1,12 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.6
Index: /tags/quest-pre-eventrefactoring/quest-core-events/.settings/org.eclipse.m2e.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events/.settings/org.eclipse.m2e.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events/.settings/org.eclipse.m2e.core.prefs	(revision 540)
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
Index: /tags/quest-pre-eventrefactoring/quest-core-events/pom.xml
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events/pom.xml	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events/pom.xml	(revision 540)
@@ -0,0 +1,51 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>de.ugoe.cs.quest</groupId>
+	<artifactId>quest-core-events</artifactId>
+	<version>0.0.1-SNAPSHOT</version>
+	<name>quest-core-events</name>
+	<scm>
+		<url>https://quest.informatik.uni-goettingen.de/svn/quest/trunk/quest-core-events</url>
+	</scm>
+	<repositories>
+		<repository>
+			<id>mbari</id>
+			<url>http://mbari-maven-repository.googlecode.com/svn/repository</url>
+		</repository>
+	</repositories>
+	<dependencies>
+		<dependency>
+			<groupId>de.ugoe.cs</groupId>
+			<artifactId>java-utils</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+		</dependency>
+		<dependency>
+			<groupId>net.sf.jung</groupId>
+			<artifactId>jung-visualization</artifactId>
+			<version>2.0.1</version>
+		</dependency>
+		<dependency>
+			<groupId>net.sf.jung</groupId>
+			<artifactId>jung-graph-impl</artifactId>
+			<version>2.0.1</version>
+		</dependency>
+		<dependency>
+			<groupId>jama</groupId>
+			<artifactId>jama</artifactId>
+			<version>1.0.2</version>
+		</dependency>
+	</dependencies>
+	<build>
+		<plugins>
+			<plugin>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>2.3.2</version>
+				<configuration>
+					<source>1.6</source>
+					<target>1.6</target>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+</project>
Index: /tags/quest-pre-eventrefactoring/quest-core-events/src/main/java/de/ugoe/cs/quest/IReplayDecorator.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events/src/main/java/de/ugoe/cs/quest/IReplayDecorator.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events/src/main/java/de/ugoe/cs/quest/IReplayDecorator.java	(revision 540)
@@ -0,0 +1,55 @@
+package de.ugoe.cs.quest;
+
+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: /tags/quest-pre-eventrefactoring/quest-core-events/src/main/java/de/ugoe/cs/quest/SequenceInstanceOf.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events/src/main/java/de/ugoe/cs/quest/SequenceInstanceOf.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events/src/main/java/de/ugoe/cs/quest/SequenceInstanceOf.java	(revision 540)
@@ -0,0 +1,79 @@
+package de.ugoe.cs.quest;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+import de.ugoe.cs.quest.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: /tags/quest-pre-eventrefactoring/quest-core-events/src/main/java/de/ugoe/cs/quest/eventcore/Event.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events/src/main/java/de/ugoe/cs/quest/eventcore/Event.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events/src/main/java/de/ugoe/cs/quest/eventcore/Event.java	(revision 540)
@@ -0,0 +1,327 @@
+package de.ugoe.cs.quest.eventcore;
+
+import java.io.Serializable;
+import java.security.InvalidParameterException;
+
+/**
+ * <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<T> implements Serializable {
+
+	/**
+	 * Id for object serialization.
+	 */
+	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<Object> STARTEVENT = new Event<Object>("START");
+
+	/**
+	 * <p>
+	 * Global end event that can be used to indicate the end of a sequence.
+	 */
+	public static final Event<Object> ENDEVENT = new Event<Object>("END");
+
+	/**
+	 * <p>
+	 * Type of the event.
+	 * </p>
+	 */
+	protected String type;
+
+	/**
+	 * </p> Target of the event.
+	 */
+	protected String target = null;
+
+	/**
+	 * <p>
+	 * Short description of the event target.
+	 * </p>
+	 */
+	protected String targetShort = null;
+
+	/**
+	 * Further information about the event that shall be included in its Id.
+	 */
+	protected String idInfo = "";
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new Event with a given type.
+	 * </p>
+	 * 
+	 * @param type
+	 *            type of the event
+	 */
+	public Event(String type) {
+		if (type == null) {
+			throw new InvalidParameterException("Event type must not be null");
+		}
+		this.type = type;
+	}
+
+	/**
+	 * <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 (otherEvent.canEqual(this)) {
+				if (type != null) {
+					return targetEquals(otherEvent.target)
+							&& type.equals(otherEvent.type);
+				} else {
+					return targetEquals(otherEvent.target)
+							&& otherEvent.type == null;
+				}
+			} else {
+				return false;
+			}
+		} else {
+			return false;
+		}
+	}
+
+	public boolean canEqual(Object other) {
+		return (other instanceof Event<?>);
+	}
+
+	/**
+	 * <p>
+	 * Returns {@link #getStandardId()} as String representation of the event.
+	 * </p>
+	 * 
+	 * @return String represenation of the event
+	 */
+	@Override
+	public String toString() {
+		return getStandardId();
+	}
+
+	/**
+	 * Informations about the event important for its Id that is neither target
+	 * nor type.
+	 * 
+	 * @return {@link #idInfo} of the event
+	 */
+	public String getIdInfo() {
+		return idInfo;
+	}
+
+	/**
+	 * <p>
+	 * If {@link #targetShort} is set, a shortend version of the Id is returned
+	 * of the form {@link #targetShort}.{@link #type}.{@link #idInfo} is
+	 * returned. Otherwise the standard Id is returned (see
+	 * {@link #getStandardId()}).
+	 * </p>
+	 * 
+	 * @return if available, shortend Id string; {@link #getStandardId()}
+	 *         otherwise
+	 */
+	public String getShortId() {
+		String shortId = null;
+		if (targetShort != null) {
+			shortId = targetShort + "." + getType();
+			if (!"".equals(idInfo)) {
+				shortId += "." + idInfo;
+			}
+		} else {
+			shortId = getStandardId();
+		}
+		return shortId;
+	}
+
+	/**
+	 * <p>
+	 * Returns the Id string of the event. It has the form {@link #target}.
+	 * {@link #type}.{@link #idInfo};
+	 * <p>
+	 * 
+	 * @return Id string of the event
+	 */
+	public String getStandardId() {
+		String id = "";
+		if (target != null) {
+			id += target + ".";
+		}
+		id += getType();
+		if (!"".equals(idInfo)) {
+			id += "." + idInfo;
+		}
+		return id;
+	}
+
+	/**
+	 * <p>
+	 * Returns the {@link #target} of the event.
+	 * </p>
+	 * 
+	 * @return {@link #target} of the event
+	 */
+	public String getTarget() {
+		return target;
+	}
+
+	/**
+	 * <p>
+	 * Returns the {@link #targetShort} of the event.
+	 * </p>
+	 * 
+	 * @return {@link #targetShort} of the event
+	 */
+	protected String getTargetShort() {
+		return targetShort;
+	}
+
+	/**
+	 * <p>
+	 * Returns the {@link #type} of the event.
+	 * </p>
+	 * 
+	 * @return {@link #type} of the event
+	 */
+	public String getType() {
+		return type;
+	}
+
+	/*
+	 * (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();
+		}
+		hash = multiplier * hash + targetHashCode();
+
+		return hash;
+	}
+
+	/**
+	 * <p>
+	 * Sets the {@link #idInfo} of the event. The idInfo is optional and
+	 * contains information important for the event's Id that is neither target
+	 * nor type.
+	 * </p>
+	 * 
+	 * @param info
+	 *            {@link #idInfo} of the event
+	 */
+	public void setIdInfo(String info) {
+		idInfo = info;
+	}
+
+	/**
+	 * <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(String target) {
+		if (this.target != null) {
+			return false;
+		}
+		this.target = target;
+		return true;
+	}
+
+	/**
+	 * <p>
+	 * Sets the short description of the event target. Once set, the target
+	 * cannot be changed.
+	 * </p>
+	 * 
+	 * @param targetShort
+	 *            short target description
+	 * @return true, if target was changed, false otherwise
+	 */
+	public boolean setTargetShort(String targetShort) {
+		if (this.targetShort != null) {
+			return false;
+		}
+		this.targetShort = targetShort;
+		return true;
+	}
+
+	/**
+	 * <p>
+	 * This function is used by {@link #equals(Object)} to determine if the
+	 * targets of both events are equal. The standard implementation provided by
+	 * this class performs a String comparison between the target strings.
+	 * </p>
+	 * <p>
+	 * Subclasses can override this method to implemented more sophisticated
+	 * means for the target comparison, e.g., to account for changes in the
+	 * title of a widget.
+	 * </p>
+	 * 
+	 * @param otherTarget
+	 *            other target string to which the target if this event is
+	 *            compared to
+	 * @return true if the targets are equals; false otherwise
+	 */
+	protected boolean targetEquals(String otherTarget) {
+		boolean retVal;
+		if (target != null) {
+			retVal = target.equals(otherTarget);
+		} else {
+			retVal = (otherTarget == null);
+		}
+		return retVal;
+	}
+
+	/**
+	 * <p>
+	 * This function is used by {@link #hashCode()} to determine how the hash of
+	 * the {@link #target}. It has to be overridden by subclasses that implement
+	 * {@link #targetEquals(String)}, to ensure that the equals/hashCode
+	 * contract remains valid.
+	 * </p>
+	 * 
+	 * @return hash of the target
+	 */
+	protected int targetHashCode() {
+		if (target != null) {
+			return target.hashCode();
+		} else {
+			return 0;
+		}
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events/src/main/java/de/ugoe/cs/quest/eventcore/IReplayable.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events/src/main/java/de/ugoe/cs/quest/eventcore/IReplayable.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events/src/main/java/de/ugoe/cs/quest/eventcore/IReplayable.java	(revision 540)
@@ -0,0 +1,35 @@
+package de.ugoe.cs.quest.eventcore;
+
+import java.io.Serializable;
+
+/**
+ * <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 target of the replayable.
+	 * </p>
+	 * 
+	 * @return target of the replayable
+	 */
+	String getTarget();
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-events/src/main/java/de/ugoe/cs/quest/eventcore/ReplayableEvent.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-events/src/main/java/de/ugoe/cs/quest/eventcore/ReplayableEvent.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-events/src/main/java/de/ugoe/cs/quest/eventcore/ReplayableEvent.java	(revision 540)
@@ -0,0 +1,167 @@
+package de.ugoe.cs.quest.eventcore;
+
+import java.security.InvalidParameterException;
+import java.util.LinkedList;
+import java.util.List;
+
+import de.ugoe.cs.quest.IReplayDecorator;
+
+/**
+ * <p>
+ * Subclass of {@link Event} for events that contain all informations required
+ * for replaying them, i.e., generating scripts that can used for automated
+ * software execution.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ * 
+ * @param <T>
+ *            Allows only types that extend {@link IReplayable} and is used to
+ *            define a list of replayables that describe the replay of the
+ *            event.
+ */
+public class ReplayableEvent<T extends IReplayable> extends Event<T> {
+
+	/**
+	 * Id for object serialization.
+	 */
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * <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<T> replayEvents = new LinkedList<T>();;
+
+	/**
+	 * <p>
+	 * Defines whether the replay is valid or invalid. It may be invalid, e.g.,
+	 * due to errors during the generation of the event or lack of vital
+	 * information.
+	 * </p>
+	 */
+	protected boolean replayValid = true;
+
+	/**
+	 * <p>
+	 * {@link IReplayDecorator} used when replays of this type are written.
+	 * </p>
+	 */
+	protected IReplayDecorator decorator = null;
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new event with the given type.
+	 * <p>
+	 * 
+	 * @param type
+	 *            type of the event
+	 * @see Event#Event(String)
+	 */
+	public ReplayableEvent(String type) {
+		super(type);
+	}
+
+	/**
+	 * <p>
+	 * Adds a new {@link IReplayable} of type T to the replay sequence.
+	 * </p>
+	 * 
+	 * @param replayable
+	 *            element that is added to the sequence
+	 * @throws InvalidParameterException
+	 *             thrown is replayable is null
+	 */
+	public void addReplayEvent(T replayable) {
+		if (replayable == null) {
+			throw new InvalidParameterException("replayble must not be null");
+		}
+		replayEvents.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 InvalidParameterException
+	 *             thrown if generatedReplaySeq is null
+	 */
+	public void addReplaySequence(List<T> generatedReplaySeq) {
+		if (generatedReplaySeq == null) {
+			throw new InvalidParameterException(
+					"generatedReplaySeq must not be null");
+		}
+		replayEvents.addAll(generatedReplaySeq);
+	}
+
+	/**
+	 * <p>
+	 * Returns the {@link IReplayDecorator} of the event.
+	 * </p>
+	 * 
+	 * @return {@link IReplayDecorator} of the event; null if no decorator has
+	 *         been set
+	 */
+	public IReplayDecorator getReplayDecorator() {
+		return decorator;
+	}
+
+	/**
+	 * <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<T> getReplayMessages() {
+		return new LinkedList<T>(replayEvents);
+	}
+
+	/**
+	 * <p>
+	 * Returns whether the replay is valid or not.
+	 * </p>
+	 * 
+	 * @return true, if replay is valid; false otherwise.
+	 */
+	public boolean hasValidReplay() {
+		return replayValid;
+	}
+
+	/**
+	 * <p>
+	 * Marks the replay as invalid. Once marked as invalid, it remains so and
+	 * cannot be changed back to valid.
+	 * </p>
+	 */
+	public void invalidateReplay() {
+		replayValid = false;
+	}
+
+	/**
+	 * <p>
+	 * Sets the {@link IReplayDecorator} associated with the event.
+	 * </p>
+	 * 
+	 * @param decorator
+	 *            decorator associated with the event
+	 */
+	public void setDecorator(IReplayDecorator decorator) {
+		this.decorator = decorator;
+	}
+	
+	@Override
+	public boolean canEqual(Object other) {
+		return (other instanceof ReplayableEvent<?>);
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/.classpath
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/.classpath	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/.classpath	(revision 540)
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/test-classes" path="src/test/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/.project
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/.project	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/.project	(revision 540)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>quest-core-tasktrees-test</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/.settings/org.eclipse.jdt.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/.settings/org.eclipse.jdt.core.prefs	(revision 540)
@@ -0,0 +1,5 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.6
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/.settings/org.eclipse.m2e.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/.settings/org.eclipse.m2e.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/.settings/org.eclipse.m2e.core.prefs	(revision 540)
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/pom.xml
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/pom.xml	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/pom.xml	(revision 540)
@@ -0,0 +1,128 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>de.ugoe.cs.quest</groupId>
+  <artifactId>quest-core-tasktrees-test</artifactId>
+  <version>0.0.1-SNAPSHOT</version>
+  <name>quest-core-tasktrees-test</name>
+  <scm>
+    <url>https://quest.informatik.uni-goettingen.de/svn/quest/trunk/quest-core-tasktrees-test</url>
+  </scm>
+  <dependencies>
+    <dependency>
+        <groupId>de.ugoe.cs.quest</groupId>
+        <artifactId>quest-core-tasktrees</artifactId>
+        <version>0.0.1-SNAPSHOT</version>
+        <scope>test</scope>
+    </dependency>
+    <dependency>
+        <groupId>junit</groupId>
+        <artifactId>junit</artifactId>
+        <version>4.8.1</version>
+        <scope>test</scope>
+    </dependency>
+  </dependencies>
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.eclipse.m2e</groupId>
+          <artifactId>lifecycle-mapping</artifactId>
+          <version>1.0.0</version>
+          <configuration>
+            <lifecycleMappingMetadata>
+              <pluginExecutions>
+                <pluginExecution>
+                  <pluginExecutionFilter>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-dependency-plugin</artifactId>
+                    <versionRange>[1.0.0,)</versionRange>
+                    <goals>
+                      <goal>unpack</goal>
+                    </goals>
+                  </pluginExecutionFilter>
+                  <action>
+                    <ignore/>
+                  </action>
+                </pluginExecution>
+                <pluginExecution>
+                  <pluginExecutionFilter>
+                    <groupId>org.codehaus.mojo</groupId>
+                    <artifactId>emma-maven-plugin</artifactId>
+                    <versionRange>[1.0-alpha-3,)</versionRange>
+                    <goals>
+                      <goal>emma</goal>
+                    </goals>
+                  </pluginExecutionFilter>
+                  <action>
+                    <ignore/>
+                  </action>
+                </pluginExecution>
+              </pluginExecutions>
+            </lifecycleMappingMetadata>
+          </configuration>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>2.3.2</version>
+        <configuration>
+          <source>1.6</source>
+          <target>1.6</target>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-dependency-plugin</artifactId>
+        <version>2.4</version>
+        <executions>
+          <execution>
+            <id>unpack</id>
+            <phase>process-classes</phase>
+            <goals>
+              <goal>unpack</goal>
+            </goals>
+            <configuration>
+              <artifactItems>
+                <artifactItem>
+                  <groupId>de.ugoe.cs.quest</groupId>
+                  <artifactId>quest-core-tasktrees</artifactId>
+                  <version>0.0.1-SNAPSHOT</version>
+                  <outputDirectory>${project.build.directory}/classes</outputDirectory>
+                </artifactItem>
+              </artifactItems>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>emma-maven-plugin</artifactId>
+        <version>1.0-alpha-3</version>
+        <inherited>true</inherited>          
+        <executions>
+          <execution>
+            <phase>process-classes</phase>
+            <goals>
+              <goal>emma</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <version>2.3.2</version>
+        <executions>
+          <execution>
+            <goals>
+              <goal>test-jar</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/src/test/java/de/ugoe/cs/quest/tasktrees/manager/TaskTreeManagerTest.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/src/test/java/de/ugoe/cs/quest/tasktrees/manager/TaskTreeManagerTest.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/src/test/java/de/ugoe/cs/quest/tasktrees/manager/TaskTreeManagerTest.java	(revision 540)
@@ -0,0 +1,576 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: TaskTreeManagerTest.java,v $
+// Version   : $Revision: 0.0 $  $Author: Patrick $  $Date: 08.11.2011 21:32:36 $
+// Project   : TaskTreePerformanceTest
+// Creation  : 2011 by Patrick
+// Copyright : Patrick Harms, 2011
+//-------------------------------------------------------------------------------------------------
+
+package de.ugoe.cs.quest.tasktrees.manager;
+
+import java.util.logging.Logger;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import de.ugoe.cs.quest.eventcore.guimodel.GUIElement;
+import de.ugoe.cs.quest.eventcore.userinteraction.Interaction;
+import de.ugoe.cs.quest.eventcore.userinteraction.InteractionEvent;
+import de.ugoe.cs.quest.tasktrees.testutils.DummyGUIElement;
+import de.ugoe.cs.quest.tasktrees.testutils.DummyInteraction;
+import de.ugoe.cs.quest.tasktrees.testutils.SimpleLogFormatter;
+import de.ugoe.cs.quest.tasktrees.testutils.TaskTreeChecker;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ *
+ * @version $Revision: $ $Date: $
+ * @author  2011, last modified by $Author: $
+ */
+//-------------------------------------------------------------------------------------------------
+
+public class TaskTreeManagerTest
+{
+  /** */
+  TaskTreeManager mManager;
+  
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Before
+  public void setUp()
+  {
+    Logger.getLogger("").getHandlers()[0].setFormatter(new SimpleLogFormatter());
+    
+    mManager = new TaskTreeManager();
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  @After
+  public void tearDown()
+  {
+    mManager = null;
+    ComponentManager.clearInstance();
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Test
+  public void testOneInteractionOnOneElement()
+  {
+    simulateInteraction(new DummyGUIElement("elem1"), new DummyInteraction("bla", 1));
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence {" +
+       "  Interaction bla {}" +
+       "}", mManager.getTaskTree());
+  }
+  
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Test
+  public void testManyInteractionsOnOneElement()
+  {
+    GUIElement element = new DummyGUIElement("elem1");
+    simulateInteraction(element, new DummyInteraction("bla", 1));
+    simulateInteraction(element, new DummyInteraction("bli", 1));
+    simulateInteraction(element, new DummyInteraction("blo", 1));
+    simulateInteraction(element, new DummyInteraction("blu", 1));
+    simulateInteraction(element, new DummyInteraction("bla", 1));
+
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence {" +
+       "  Interaction bla {}" +
+       "  Interaction bli {}" +
+       "  Interaction blo {}" +
+       "  Interaction blu {}" +
+       "  Interaction bla {}" +
+       "}", mManager.getTaskTree());
+  }
+  
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Test
+  public void testOneInteractionOnManyElements()
+  {
+    GUIElement element1 = new DummyGUIElement("elem1");
+    GUIElement element2 = new DummyGUIElement("elem2");
+    GUIElement element3 = new DummyGUIElement("elem3");
+    GUIElement element4 = new DummyGUIElement("elem4");
+    GUIElement element5 = new DummyGUIElement("elem5");
+    GUIElement element6 = new DummyGUIElement("elem6");
+    simulateInteraction(element1, new DummyInteraction("bla", 1));
+    simulateInteraction(element2, new DummyInteraction("bli", 1));
+    simulateInteraction(element3, new DummyInteraction("bla", 1));
+    simulateInteraction(element4, new DummyInteraction("bli", 1));
+    simulateInteraction(element5, new DummyInteraction("blo", 1));
+    simulateInteraction(element6, new DummyInteraction("bla", 1));
+    
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence0 {" +
+       "  Sequence sequence1 {" +
+       "    Interaction bla {}" +
+       "  }" +
+       "  Sequence sequence2 {" +
+       "    Interaction bli {}" +
+       "  }" +
+       "  Sequence sequence3 {" +
+       "    Interaction bla {}" +
+       "  }" +
+       "  Sequence sequence4 {" +
+       "    Interaction bli {}" +
+       "  }" +
+       "  Sequence sequence5 {" +
+       "    Interaction blo {}" +
+       "  }" +
+       "  Sequence sequence6 {" +
+       "    Interaction bla {}" +
+       "  }" +
+       "}", mManager.getTaskTree());
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Test
+  public void testManyInteractionsOnManyElements()
+  {
+    GUIElement element1 = new DummyGUIElement("elem1");
+    GUIElement element2 = new DummyGUIElement("elem2");
+    GUIElement element3 = new DummyGUIElement("elem3");
+    GUIElement element4 = new DummyGUIElement("elem4");
+    GUIElement element5 = new DummyGUIElement("elem5");
+    GUIElement element6 = new DummyGUIElement("elem6");
+    simulateInteraction(element1, new DummyInteraction("bla", 1));
+    simulateInteraction(element1, new DummyInteraction("bli", 1));
+    simulateInteraction(element1, new DummyInteraction("bla", 1));
+    simulateInteraction(element2, new DummyInteraction("bli", 1));
+    simulateInteraction(element2, new DummyInteraction("blo", 1));
+    simulateInteraction(element3, new DummyInteraction("bla", 1));
+    simulateInteraction(element4, new DummyInteraction("bli", 1));
+    simulateInteraction(element4, new DummyInteraction("bla", 1));
+    simulateInteraction(element4, new DummyInteraction("bli", 1));
+    simulateInteraction(element4, new DummyInteraction("blo", 1));
+    simulateInteraction(element5, new DummyInteraction("bla", 1));
+    simulateInteraction(element6, new DummyInteraction("bli", 1));
+    simulateInteraction(element6, new DummyInteraction("bla", 1));
+    simulateInteraction(element6, new DummyInteraction("bli", 1));
+    simulateInteraction(element6, new DummyInteraction("blo", 1));
+
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence0 {" +
+       "  Sequence sequence1 {" +
+       "    Interaction bla {}" +
+       "    Interaction bli {}" +
+       "    Interaction bla {}" +
+       "  }" +
+       "  Sequence sequence2 {" +
+       "    Interaction bli {}" +
+       "    Interaction blo {}" +
+       "  }" +
+       "  Sequence sequence3 {" +
+       "    Interaction bla {}" +
+       "  }" +
+       "  Sequence sequence4 {" +
+       "    Interaction bli {}" +
+       "    Interaction bla {}" +
+       "    Interaction bli {}" +
+       "    Interaction blo {}" +
+       "  }" +
+       "  Sequence sequence5 {" +
+       "    Interaction bla {}" +
+       "  }" +
+       "  Sequence sequence6 {" +
+       "    Interaction bli {}" +
+       "    Interaction bla {}" +
+       "    Interaction bli {}" +
+       "    Interaction blo {}" +
+       "  }" +
+       "}", mManager.getTaskTree());
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Test
+  public void testInteractionIterationDetection() throws Exception
+  {
+    GUIElement element1 = new DummyGUIElement("elem1");
+    Interaction interaction1 = new DummyInteraction("bla", 1);
+    simulateInteraction(element1, interaction1);
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence1 {" +
+       "  Interaction bla {}" +
+       "}", mManager.getTaskTree());    
+
+    simulateInteraction(element1, interaction1);
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence1 {" +
+       "  Iteration iteration1 {" +
+       "    Interaction bla {}" +
+       "  }" +
+       "}", mManager.getTaskTree());    
+
+    simulateInteraction(element1, interaction1);
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence1 {" +
+       "  Iteration iteration1 {" +
+       "    Interaction bla {}" +
+       "  }" +
+       "}", mManager.getTaskTree());    
+
+    for (int i = 0; i < 10; i++)
+    {
+      simulateInteraction(element1, interaction1);
+    }
+    
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence1 {" +
+       "  Iteration iteration1 {" +
+       "    Interaction bla {}" +
+       "  }" +
+       "}", mManager.getTaskTree());    
+    
+    // now test with preceding and trailing other interactions
+    Interaction interaction2 = new DummyInteraction("bli", 1);
+    Interaction interaction3 = new DummyInteraction("blup", 1);
+
+    simulateInteraction(element1, interaction2);
+    simulateInteraction(element1, interaction3);
+    for (int i = 0; i < 10; i++)
+    {
+      simulateInteraction(element1, interaction1);
+    }
+    simulateInteraction(element1, interaction3);
+    simulateInteraction(element1, interaction2);
+    
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence1 {" +
+       "  Iteration iteration1 {" +
+       "    Interaction bla {}" +
+       "  }" +
+       "  Interaction bli {}" +
+       "  Interaction blup {}" +
+       "  Iteration iteration2 {" +
+       "    Interaction bla {}" +
+       "  }" +
+       "  Interaction blup {}" +
+       "  Interaction bli {}" +
+       "}", mManager.getTaskTree());    
+  
+    // now test with iterations of iterations
+
+    for (int i = 0; i < 10; i++)
+    {
+      for (int j = 0; j < 5; j++)
+      {
+        simulateInteraction(element1, interaction1);
+      }
+      for (int j = 0; j < 5; j++)
+      {
+        simulateInteraction(element1, interaction2);
+      }
+      for (int j = 0; j < 5; j++)
+      {
+        simulateInteraction(element1, interaction3);
+      }
+    }
+    
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence0 {" +
+       "  Iteration iteration0 {" +
+       "    Interaction bla {}" +
+       "  }" +
+       "  Interaction bli {}" +
+       "  Interaction blup {}" +
+       "  Iteration iteration1 {" +
+       "    Interaction bla {}" +
+       "  }" +
+       "  Interaction blup {}" +
+       "  Interaction bli {}" +
+       "  Iteration iteration2 {" +
+       "    Sequence sequence1 {" +
+       "      Iteration iteration3 {" +
+       "        Interaction bla {}" +
+       "      }" +
+       "      Iteration iteration4 {" +
+       "        Interaction bli {}" +
+       "      }" +
+       "      Iteration iteration5 {" +
+       "        Interaction blup {}" +
+       "      }" +
+       "    }" +
+       "  }" +
+       "}", mManager.getTaskTree());    
+  
+  }
+  
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Test
+  public void testSequenceIterationDetection() throws Exception
+  {
+    GUIElement element1 = new DummyGUIElement("elem1");
+    Interaction interaction1 = new DummyInteraction("bla", 1);
+    Interaction interaction2 = new DummyInteraction("bli", 1);
+    Interaction interaction3 = new DummyInteraction("blup", 1);
+    simulateInteraction(element1, interaction1);
+    simulateInteraction(element1, interaction2);
+    simulateInteraction(element1, interaction3);
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence1 {" +
+       "  Interaction bla {}" +
+       "  Interaction bli {}" +
+       "  Interaction blup {}" +
+       "}", mManager.getTaskTree());    
+
+    simulateInteraction(element1, interaction1);
+    simulateInteraction(element1, interaction2);
+    simulateInteraction(element1, interaction3);
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence1 {" +
+       "  Iteration iteration1 {" +
+       "    Sequence sequence2 {" +
+       "      Interaction bla {}" +
+       "      Interaction bli {}" +
+       "      Interaction blup {}" +
+       "    }" +
+       "  }" +
+       "}", mManager.getTaskTree());    
+
+    simulateInteraction(element1, interaction1);
+    simulateInteraction(element1, interaction2);
+    simulateInteraction(element1, interaction3);
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence1 {" +
+       "  Iteration iteration1 {" +
+       "    Sequence sequence2 {" +
+       "      Interaction bla {}" +
+       "      Interaction bli {}" +
+       "      Interaction blup {}" +
+       "    }" +
+       "  }" +
+       "}", mManager.getTaskTree());    
+
+    for (int i = 0; i < 10; i++)
+    {
+      simulateInteraction(element1, interaction1);
+      simulateInteraction(element1, interaction2);
+      simulateInteraction(element1, interaction3);
+    }
+    
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence1 {" +
+       "  Iteration iteration1 {" +
+       "    Sequence sequence2 {" +
+       "      Interaction bla {}" +
+       "      Interaction bli {}" +
+       "      Interaction blup {}" +
+       "    }" +
+       "  }" +
+       "}", mManager.getTaskTree());    
+    
+    // now test with preceding and trailing other interactions
+    Interaction interaction4 = new DummyInteraction("ble", 1);
+    Interaction interaction5 = new DummyInteraction("blo", 1);
+    Interaction interaction6 = new DummyInteraction("blu", 1);
+    simulateInteraction(element1, interaction4);
+    simulateInteraction(element1, interaction5);
+    simulateInteraction(element1, interaction6);
+    for (int i = 0; i < 10; i++)
+    {
+      simulateInteraction(element1, interaction1);
+      simulateInteraction(element1, interaction2);
+      simulateInteraction(element1, interaction3);
+    }
+    simulateInteraction(element1, interaction6);
+    simulateInteraction(element1, interaction5);
+    simulateInteraction(element1, interaction4);
+    
+    new TaskTreeChecker().assertTaskTree
+    ("Sequence sequence1 {" +
+     "  Iteration iteration1 {" +
+     "    Sequence sequence2 {" +
+     "      Interaction bla {}" +
+     "      Interaction bli {}" +
+     "      Interaction blup {}" +
+     "    }" +
+     "  }" +
+     "  Interaction ble {}" +
+     "  Interaction blo {}" +
+     "  Interaction blu {}" +
+     "  Iteration iteration2 {" +
+     "    Sequence sequence3 {" +
+     "      Interaction bla {}" +
+     "      Interaction bli {}" +
+     "      Interaction blup {}" +
+     "    }" +
+     "  }" +
+     "  Interaction blu {}" +
+     "  Interaction blo {}" +
+     "  Interaction ble {}" +
+     "}", mManager.getTaskTree());    
+  
+    // now test with iterations of iterations
+    for (int i = 0; i < 10; i++)
+    {
+      for (int j = 0; j < 5; j++)
+      {
+        simulateInteraction(element1, interaction1);
+        simulateInteraction(element1, interaction2);
+        simulateInteraction(element1, interaction3);
+      }
+      for (int j = 0; j < 5; j++)
+      {
+        simulateInteraction(element1, interaction2);
+        simulateInteraction(element1, interaction1);
+        simulateInteraction(element1, interaction3);
+      }
+      for (int j = 0; j < 5; j++)
+      {
+        simulateInteraction(element1, interaction1);
+        simulateInteraction(element1, interaction2);
+        simulateInteraction(element1, interaction3);
+      }
+    }
+    
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence1 {" +
+       "  Iteration iteration1 {" +
+       "    Sequence sequence2 {" +
+       "      Interaction bla {}" +
+       "      Interaction bli {}" +
+       "      Interaction blup {}" +
+       "    }" +
+       "  }" +
+       "  Interaction ble {}" +
+       "  Interaction blo {}" +
+       "  Interaction blu {}" +
+       "  Iteration iteration2 {" +
+       "    Sequence sequence3 {" +
+       "      Interaction bla {}" +
+       "      Interaction bli {}" +
+       "      Interaction blup {}" +
+       "    }" +
+       "  }" +
+       "  Interaction blu {}" +
+       "  Interaction blo {}" +
+       "  Interaction ble {}" +
+       "  Iteration iteration3 {" +
+       "    Sequence sequence4 {" +
+       "      Iteration iteration4 {" +
+       "        Sequence sequence4 {" +
+       "          Interaction bla {}" +
+       "          Interaction bli {}" +
+       "          Interaction blup {}" +
+       "        }" +
+       "      }" +
+       "      Iteration iteration5 {" +
+       "        Sequence sequence5 {" +
+       "          Interaction bli {}" +
+       "          Interaction bla {}" +
+       "          Interaction blup {}" +
+       "        }" +
+       "      }" +
+       "      Iteration iteration6 {" +
+       "        Sequence sequence6 {" +
+       "          Interaction bla {}" +
+       "          Interaction bli {}" +
+       "          Interaction blup {}" +
+       "        }" +
+       "      }" +
+       "    }" +
+       "  }" +
+       "}", mManager.getTaskTree());    
+  }
+  
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Test
+  public void testGUIElementHierarchyChanges() throws Exception
+  {
+    GUIElement element1 = new DummyGUIElement("elem1");
+    GUIElement element2 = new DummyGUIElement("elem2");
+    GUIElement element3 = new DummyGUIElement("elem3");
+    GUIElement parent1 = new DummyGUIElement("parent1");
+    GUIElement parent2 = new DummyGUIElement("parent2");
+    GUIElement parent3 = new DummyGUIElement("parent3");
+    
+    element1.setParent(parent1);
+    element2.setParent(parent2);
+    element3.setParent(parent3);
+    
+    parent1.setParent(parent2);
+    parent2.setParent(parent3);
+    
+    Interaction interaction1 = new DummyInteraction("bla", 1);
+    simulateInteraction(element1, interaction1);
+    simulateInteraction(element2, interaction1);
+    simulateInteraction(element3, interaction1);
+    simulateInteraction(element2, interaction1);
+    simulateInteraction(element3, interaction1);
+    simulateInteraction(element2, interaction1);
+    simulateInteraction(element1, interaction1);
+   
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence0 {" +
+       "  Sequence sequence1 {" +
+       "    Interaction bla {}" +
+       "  }" +
+       "  Sequence sequence2 {" +
+       "    Interaction bla {}" +
+       "  }" +
+       "  Iteration iteration0 {" +
+       "    Sequence sequence3 {" +
+       "      Sequence sequence4 {" +
+       "        Interaction bla {}" +
+       "      }" +
+       "      Sequence sequence5 {" +
+       "        Interaction bla {}" +
+       "      }" +
+       "    }" +
+       "  }" +
+       "  Sequence sequence6 {" +
+       "    Interaction bla {}" +
+       "  }" +
+       "}", mManager.getTaskTree());    
+
+  }
+  
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * @param interactionsDoNotOverwriteElement
+   */
+  //-----------------------------------------------------------------------------------------------
+  private void simulateInteraction(GUIElement GUIElement, Interaction interaction)
+  {
+    mManager.handleNewInteractionEvent(new InteractionEvent(GUIElement, interaction));
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/src/test/java/de/ugoe/cs/quest/tasktrees/temporalrelation/AbstractTemporalRelationshipTC.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/src/test/java/de/ugoe/cs/quest/tasktrees/temporalrelation/AbstractTemporalRelationshipTC.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/src/test/java/de/ugoe/cs/quest/tasktrees/temporalrelation/AbstractTemporalRelationshipTC.java	(revision 540)
@@ -0,0 +1,100 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: AbstractTemporalRelationshipTC.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 28.04.2012 $
+// Project   : TaskTreeTemporalRelationship
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.temporalrelation;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Logger;
+
+import org.junit.Before;
+
+import de.ugoe.cs.quest.eventcore.guimodel.GUIElement;
+import de.ugoe.cs.quest.eventcore.userinteraction.Interaction;
+import de.ugoe.cs.quest.tasktrees.nodeequality.NodeEqualityRuleManager;
+import de.ugoe.cs.quest.tasktrees.testutils.SimpleLogFormatter;
+import de.ugoe.cs.quest.tasktrees.testutils.Utilities;
+import de.ugoe.cs.quest.tasktrees.treeifc.InteractionTask;
+import de.ugoe.cs.quest.tasktrees.treeifc.Sequence;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTree;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeBuilder;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNodeFactory;
+import de.ugoe.cs.quest.tasktrees.treeimpl.TaskTreeBuilderImpl;
+import de.ugoe.cs.quest.tasktrees.treeimpl.TaskTreeNodeFactoryImpl;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 28.04.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public class AbstractTemporalRelationshipTC
+{
+
+  /** */
+  private List<InteractionTask> mInteractions;
+  
+  /** */
+  private TaskTreeBuilder mTaskTreeBuilder = new TaskTreeBuilderImpl();
+
+  /** */
+  private TaskTreeNodeFactory mTaskTreeNodeFactory = new TaskTreeNodeFactoryImpl();
+  
+  /** */
+  private NodeEqualityRuleManager mNodeEqualityRuleManager =
+    Utilities.getNodeEqualityRuleManagerForTests();
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Before
+  public void setUp()
+  {
+    Logger.getLogger("").getHandlers()[0].setFormatter(new SimpleLogFormatter());
+    mInteractions = new ArrayList<InteractionTask>();
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * @param interactionsDoNotOverwriteElement
+   */
+  //-----------------------------------------------------------------------------------------------
+  protected void simulateInteraction(GUIElement GUIElement, Interaction interaction)
+  {
+    mInteractions.add
+      (mTaskTreeNodeFactory.createNewInteractionTask(GUIElement, interaction));
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * @param interactionsDoNotOverwriteElement
+   * @return 
+   */
+  //-----------------------------------------------------------------------------------------------
+  protected TaskTree getTaskTree()
+  {
+    Sequence sequence = mTaskTreeNodeFactory.createNewSequence();
+    
+    for (InteractionTask task : mInteractions)
+    {
+      mTaskTreeBuilder.addChild(sequence, task);
+    }
+    
+    TemporalRelationshipRuleManager ruleManager =
+      new TemporalRelationshipRuleManager(mNodeEqualityRuleManager);
+    
+    ruleManager.init();
+    ruleManager.applyRules(sequence, mTaskTreeBuilder, mTaskTreeNodeFactory, true);
+    
+    return mTaskTreeNodeFactory.createTaskTree(sequence);
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/src/test/java/de/ugoe/cs/quest/tasktrees/temporalrelation/DefaultGUIElementSequenceDetectionRuleTest.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/src/test/java/de/ugoe/cs/quest/tasktrees/temporalrelation/DefaultGUIElementSequenceDetectionRuleTest.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/src/test/java/de/ugoe/cs/quest/tasktrees/temporalrelation/DefaultGUIElementSequenceDetectionRuleTest.java	(revision 540)
@@ -0,0 +1,232 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: TaskTreeManagerTest.java,v $
+// Version   : $Revision: 0.0 $  $Author: Patrick $  $Date: 08.11.2011 21:32:36 $
+// Project   : TaskTreePerformanceTest
+// Creation  : 2011 by Patrick
+// Copyright : Patrick Harms, 2011
+//-------------------------------------------------------------------------------------------------
+
+package de.ugoe.cs.quest.tasktrees.temporalrelation;
+
+import org.junit.Test;
+
+import de.ugoe.cs.quest.eventcore.guimodel.GUIElement;
+import de.ugoe.cs.quest.eventcore.userinteraction.Interaction;
+import de.ugoe.cs.quest.tasktrees.testutils.DummyGUIElement;
+import de.ugoe.cs.quest.tasktrees.testutils.DummyInteraction;
+import de.ugoe.cs.quest.tasktrees.testutils.TaskTreeChecker;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ *
+ * @version $Revision: $ $Date: $
+ * @author  2011, last modified by $Author: $
+ */
+//-------------------------------------------------------------------------------------------------
+public class DefaultGUIElementSequenceDetectionRuleTest extends AbstractTemporalRelationshipTC
+{
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Test
+  public void testOneInteractionOnOneElement()
+  {
+    simulateInteraction(new DummyGUIElement("elem1"), new DummyInteraction("bla", 1));
+    
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence {" +
+       "  Interaction bla {}" +
+       "}", getTaskTree());
+  }
+  
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Test
+  public void testManyInteractionsOnOneElement()
+  {
+    GUIElement element = new DummyGUIElement("elem1");
+    simulateInteraction(element, new DummyInteraction("bla", 1));
+    simulateInteraction(element, new DummyInteraction("bli", 1));
+    simulateInteraction(element, new DummyInteraction("blo", 1));
+    simulateInteraction(element, new DummyInteraction("blu", 1));
+    simulateInteraction(element, new DummyInteraction("bla", 1));
+    
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence {" +
+       "  Interaction bla {}" +
+       "  Interaction bli {}" +
+       "  Interaction blo {}" +
+       "  Interaction blu {}" +
+       "  Interaction bla {}" +
+       "}", getTaskTree());
+  }
+  
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Test
+  public void testOneInteractionOnManyElements()
+  {
+    GUIElement element1 = new DummyGUIElement("elem1");
+    GUIElement element2 = new DummyGUIElement("elem2");
+    GUIElement element3 = new DummyGUIElement("elem3");
+    GUIElement element4 = new DummyGUIElement("elem4");
+    GUIElement element5 = new DummyGUIElement("elem5");
+    GUIElement element6 = new DummyGUIElement("elem6");
+    simulateInteraction(element1, new DummyInteraction("bla", 1));
+    simulateInteraction(element2, new DummyInteraction("bli", 1));
+    simulateInteraction(element3, new DummyInteraction("bla", 1));
+    simulateInteraction(element4, new DummyInteraction("bli", 1));
+    simulateInteraction(element5, new DummyInteraction("blo", 1));
+    simulateInteraction(element6, new DummyInteraction("bla", 1));
+
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence0 {" +
+       "  Sequence sequence1 {" +
+       "    Interaction bla {}" +
+       "  }" +
+       "  Sequence sequence2 {" +
+       "    Interaction bli {}" +
+       "  }" +
+       "  Sequence sequence3 {" +
+       "    Interaction bla {}" +
+       "  }" +
+       "  Sequence sequence4 {" +
+       "    Interaction bli {}" +
+       "  }" +
+       "  Sequence sequence5 {" +
+       "    Interaction blo {}" +
+       "  }" +
+       "  Sequence sequence6 {" +
+       "    Interaction bla {}" +
+       "  }" +
+       "}", getTaskTree());
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Test
+  public void testManyInteractionsOnManyElements()
+  {
+    GUIElement element1 = new DummyGUIElement("elem1");
+    GUIElement element2 = new DummyGUIElement("elem2");
+    GUIElement element3 = new DummyGUIElement("elem3");
+    GUIElement element4 = new DummyGUIElement("elem4");
+    GUIElement element5 = new DummyGUIElement("elem5");
+    GUIElement element6 = new DummyGUIElement("elem6");
+    simulateInteraction(element1, new DummyInteraction("bla", 1));
+    simulateInteraction(element1, new DummyInteraction("bli", 1));
+    simulateInteraction(element1, new DummyInteraction("bla", 1));
+    simulateInteraction(element2, new DummyInteraction("bli", 1));
+    simulateInteraction(element2, new DummyInteraction("blo", 1));
+    simulateInteraction(element3, new DummyInteraction("bla", 1));
+    simulateInteraction(element4, new DummyInteraction("bli", 1));
+    simulateInteraction(element4, new DummyInteraction("bla", 1));
+    simulateInteraction(element4, new DummyInteraction("bli", 1));
+    simulateInteraction(element4, new DummyInteraction("blo", 1));
+    simulateInteraction(element5, new DummyInteraction("bla", 1));
+    simulateInteraction(element6, new DummyInteraction("bli", 1));
+    simulateInteraction(element6, new DummyInteraction("bla", 1));
+    simulateInteraction(element6, new DummyInteraction("bli", 1));
+    simulateInteraction(element6, new DummyInteraction("blo", 1));
+    
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence0 {" +
+       "  Sequence sequence1 {" +
+       "    Interaction bla {}" +
+       "    Interaction bli {}" +
+       "    Interaction bla {}" +
+       "  }" +
+       "  Sequence sequence2 {" +
+       "    Interaction bli {}" +
+       "    Interaction blo {}" +
+       "  }" +
+       "  Sequence sequence3 {" +
+       "    Interaction bla {}" +
+       "  }" +
+       "  Sequence sequence4 {" +
+       "    Interaction bli {}" +
+       "    Interaction bla {}" +
+       "    Interaction bli {}" +
+       "    Interaction blo {}" +
+       "  }" +
+       "  Sequence sequence5 {" +
+       "    Interaction bla {}" +
+       "  }" +
+       "  Sequence sequence6 {" +
+       "    Interaction bli {}" +
+       "    Interaction bla {}" +
+       "    Interaction bli {}" +
+       "    Interaction blo {}" +
+       "  }" +
+       "}", getTaskTree());
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Test
+  public void testGUIElementHierarchyChanges() throws Exception
+  {
+    GUIElement element1 = new DummyGUIElement("elem1");
+    GUIElement element2 = new DummyGUIElement("elem2");
+    GUIElement element3 = new DummyGUIElement("elem3");
+    GUIElement parent1 = new DummyGUIElement("parent1");
+    GUIElement parent2 = new DummyGUIElement("parent2");
+    GUIElement parent3 = new DummyGUIElement("parent3");
+    
+    element1.setParent(parent1);
+    element2.setParent(parent2);
+    element3.setParent(parent3);
+    
+    parent1.setParent(parent2);
+    parent2.setParent(parent3);
+    
+    Interaction interaction1 = new DummyInteraction("bla", 1);
+    simulateInteraction(element1, interaction1);
+    simulateInteraction(element2, interaction1);
+    simulateInteraction(element3, interaction1);
+    simulateInteraction(element2, interaction1);
+    simulateInteraction(element3, interaction1);
+    simulateInteraction(element2, interaction1);
+    simulateInteraction(element1, interaction1);
+   
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence0 {" +
+       "  Sequence sequence1 {" +
+       "    Interaction bla {}" +
+       "  }" +
+       "  Sequence sequence2 {" +
+       "    Interaction bla {}" +
+       "  }" +
+       "  Iteration iteration0 {" +
+       "    Sequence sequence3 {" +
+       "      Sequence sequence4 {" +
+       "        Interaction bla {}" +
+       "      }" +
+       "      Sequence sequence5 {" +
+       "        Interaction bla {}" +
+       "      }" +
+       "    }" +
+       "  }" +
+       "  Sequence sequence6 {" +
+       "    Interaction bla {}" +
+       "  }" +
+       "}", getTaskTree());    
+
+  }
+  
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/src/test/java/de/ugoe/cs/quest/tasktrees/temporalrelation/DefaultIterationDetectionRuleTest.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/src/test/java/de/ugoe/cs/quest/tasktrees/temporalrelation/DefaultIterationDetectionRuleTest.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/src/test/java/de/ugoe/cs/quest/tasktrees/temporalrelation/DefaultIterationDetectionRuleTest.java	(revision 540)
@@ -0,0 +1,329 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: DefaultIterationDetectionRuleTest.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 28.04.2012 $
+// Project   : TaskTreeTemporalRelationship
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.temporalrelation;
+
+import org.junit.Test;
+
+import de.ugoe.cs.quest.eventcore.guimodel.GUIElement;
+import de.ugoe.cs.quest.eventcore.userinteraction.Interaction;
+import de.ugoe.cs.quest.tasktrees.testutils.DummyGUIElement;
+import de.ugoe.cs.quest.tasktrees.testutils.DummyInteraction;
+import de.ugoe.cs.quest.tasktrees.testutils.TaskTreeChecker;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 28.04.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public class DefaultIterationDetectionRuleTest extends AbstractTemporalRelationshipTC
+{
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Test
+  public void testInteractionIterationDetection() throws Exception
+  {
+    GUIElement element1 = new DummyGUIElement("elem1");
+    Interaction interaction1 = new DummyInteraction("bla", 1);
+    simulateInteraction(element1, interaction1);
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence1 {" +
+       "  Interaction bla {}" +
+       "}", getTaskTree());    
+
+    simulateInteraction(element1, interaction1);
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence1 {" +
+       "  Iteration iteration1 {" +
+       "    Interaction bla {}" +
+       "  }" +
+       "}", getTaskTree());    
+
+    simulateInteraction(element1, interaction1);
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence1 {" +
+       "  Iteration iteration1 {" +
+       "    Interaction bla {}" +
+       "  }" +
+       "}", getTaskTree());    
+
+    for (int i = 0; i < 10; i++)
+    {
+      simulateInteraction(element1, interaction1);
+    }
+    
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence1 {" +
+       "  Iteration iteration1 {" +
+       "    Interaction bla {}" +
+       "  }" +
+       "}", getTaskTree());    
+    
+    // now test with preceding and trailing other interactions
+    Interaction interaction2 = new DummyInteraction("bli", 1);
+    Interaction interaction3 = new DummyInteraction("blup", 1);
+
+    simulateInteraction(element1, interaction2);
+    simulateInteraction(element1, interaction3);
+    for (int i = 0; i < 10; i++)
+    {
+      simulateInteraction(element1, interaction1);
+    }
+    simulateInteraction(element1, interaction3);
+    simulateInteraction(element1, interaction2);
+    
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence1 {" +
+       "  Iteration iteration1 {" +
+       "    Interaction bla {}" +
+       "  }" +
+       "  Interaction bli {}" +
+       "  Interaction blup {}" +
+       "  Iteration iteration2 {" +
+       "    Interaction bla {}" +
+       "  }" +
+       "  Interaction blup {}" +
+       "  Interaction bli {}" +
+       "}", getTaskTree());    
+  
+    // now test with iterations of iterations
+
+    for (int i = 0; i < 10; i++)
+    {
+      for (int j = 0; j < 5; j++)
+      {
+        simulateInteraction(element1, interaction1);
+      }
+      for (int j = 0; j < 5; j++)
+      {
+        simulateInteraction(element1, interaction2);
+      }
+      for (int j = 0; j < 5; j++)
+      {
+        simulateInteraction(element1, interaction3);
+      }
+    }
+    
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence1 {" +
+       "  Iteration iteration1 {" +
+       "    Interaction bla {}" +
+       "  }" +
+       "  Interaction bli {}" +
+       "  Interaction blup {}" +
+       "  Iteration iteration2 {" +
+       "    Interaction bla {}" +
+       "  }" +
+       "  Interaction blup {}" +
+       "  Interaction bli {}" +
+       "  Iteration iteration3 {" +
+       "    Sequence sequence2 {" +
+       "      Iteration iteration4 {" +
+       "        Interaction bla {}" +
+       "      }" +
+       "      Iteration iteration5 {" +
+       "        Interaction bli {}" +
+       "      }" +
+       "      Iteration iteration6 {" +
+       "        Interaction blup {}" +
+       "      }" +
+       "    }" +
+       "  }" +
+       "}", getTaskTree());    
+  
+  }
+  
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Test
+  public void testSequenceIterationDetection() throws Exception
+  {
+    GUIElement element1 = new DummyGUIElement("elem1");
+    Interaction interaction1 = new DummyInteraction("bla", 1);
+    Interaction interaction2 = new DummyInteraction("bli", 1);
+    Interaction interaction3 = new DummyInteraction("blup", 1);
+    simulateInteraction(element1, interaction1);
+    simulateInteraction(element1, interaction2);
+    simulateInteraction(element1, interaction3);
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence1 {" +
+       "  Interaction bla {}" +
+       "  Interaction bli {}" +
+       "  Interaction blup {}" +
+       "}", getTaskTree());    
+
+    simulateInteraction(element1, interaction1);
+    simulateInteraction(element1, interaction2);
+    simulateInteraction(element1, interaction3);
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence1 {" +
+       "  Iteration iteration1 {" +
+       "    Sequence sequence2 {" +
+       "      Interaction bla {}" +
+       "      Interaction bli {}" +
+       "      Interaction blup {}" +
+       "    }" +
+       "  }" +
+       "}", getTaskTree());    
+
+    simulateInteraction(element1, interaction1);
+    simulateInteraction(element1, interaction2);
+    simulateInteraction(element1, interaction3);
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence1 {" +
+       "  Iteration iteration1 {" +
+       "    Sequence sequence2 {" +
+       "      Interaction bla {}" +
+       "      Interaction bli {}" +
+       "      Interaction blup {}" +
+       "    }" +
+       "  }" +
+       "}", getTaskTree());    
+
+    for (int i = 0; i < 10; i++)
+    {
+      simulateInteraction(element1, interaction1);
+      simulateInteraction(element1, interaction2);
+      simulateInteraction(element1, interaction3);
+    }
+    
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence1 {" +
+       "  Iteration iteration1 {" +
+       "    Sequence sequence2 {" +
+       "      Interaction bla {}" +
+       "      Interaction bli {}" +
+       "      Interaction blup {}" +
+       "    }" +
+       "  }" +
+       "}", getTaskTree());    
+    
+    // now test with preceding and trailing other interactions
+    Interaction interaction4 = new DummyInteraction("ble", 1);
+    Interaction interaction5 = new DummyInteraction("blo", 1);
+    Interaction interaction6 = new DummyInteraction("blu", 1);
+    simulateInteraction(element1, interaction4);
+    simulateInteraction(element1, interaction5);
+    simulateInteraction(element1, interaction6);
+    for (int i = 0; i < 10; i++)
+    {
+      simulateInteraction(element1, interaction1);
+      simulateInteraction(element1, interaction2);
+      simulateInteraction(element1, interaction3);
+    }
+    simulateInteraction(element1, interaction6);
+    simulateInteraction(element1, interaction5);
+    simulateInteraction(element1, interaction4);
+    
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence1 {" +
+       "  Iteration iteration1 {" +
+       "    Sequence sequence2 {" +
+       "      Interaction bla {}" +
+       "      Interaction bli {}" +
+       "      Interaction blup {}" +
+       "    }" +
+       "  }" +
+       "  Interaction ble {}" +
+       "  Interaction blo {}" +
+       "  Interaction blu {}" +
+       "  Iteration iteration2 {" +
+       "    Sequence sequence3 {" +
+       "      Interaction bla {}" +
+       "      Interaction bli {}" +
+       "      Interaction blup {}" +
+       "    }" +
+       "  }" +
+       "  Interaction blu {}" +
+       "  Interaction blo {}" +
+       "  Interaction ble {}" +
+       "}", getTaskTree());    
+  
+    // now test with iterations of iterations
+    for (int i = 0; i < 10; i++)
+    {
+      for (int j = 0; j < 5; j++)
+      {
+        simulateInteraction(element1, interaction1);
+        simulateInteraction(element1, interaction2);
+        simulateInteraction(element1, interaction3);
+      }
+      for (int j = 0; j < 5; j++)
+      {
+        simulateInteraction(element1, interaction2);
+        simulateInteraction(element1, interaction1);
+        simulateInteraction(element1, interaction3);
+      }
+      for (int j = 0; j < 5; j++)
+      {
+        simulateInteraction(element1, interaction1);
+        simulateInteraction(element1, interaction2);
+        simulateInteraction(element1, interaction3);
+      }
+    }
+    
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence1 {" +
+       "  Iteration iteration1 {" +
+       "    Sequence sequence2 {" +
+       "      Interaction bla {}" +
+       "      Interaction bli {}" +
+       "      Interaction blup {}" +
+       "    }" +
+       "  }" +
+       "  Interaction ble {}" +
+       "  Interaction blo {}" +
+       "  Interaction blu {}" +
+       "  Iteration iteration2 {" +
+       "    Sequence sequence3 {" +
+       "      Interaction bla {}" +
+       "      Interaction bli {}" +
+       "      Interaction blup {}" +
+       "    }" +
+       "  }" +
+       "  Interaction blu {}" +
+       "  Interaction blo {}" +
+       "  Interaction ble {}" +
+       "  Iteration iteration3 {" +
+       "    Sequence sequence4 {" +
+       "      Iteration iteration4 {" +
+       "        Sequence sequence4 {" +
+       "          Interaction bla {}" +
+       "          Interaction bli {}" +
+       "          Interaction blup {}" +
+       "        }" +
+       "      }" +
+       "      Iteration iteration5 {" +
+       "        Sequence sequence5 {" +
+       "          Interaction bli {}" +
+       "          Interaction bla {}" +
+       "          Interaction blup {}" +
+       "        }" +
+       "      }" +
+       "      Iteration iteration6 {" +
+       "        Sequence sequence6 {" +
+       "          Interaction bla {}" +
+       "          Interaction bli {}" +
+       "          Interaction blup {}" +
+       "        }" +
+       "      }" +
+       "    }" +
+       "  }" +
+       "}", getTaskTree());    
+  }
+  
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/src/test/java/de/ugoe/cs/quest/tasktrees/temporalrelation/DefaultMouseClickReductionRuleTest.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/src/test/java/de/ugoe/cs/quest/tasktrees/temporalrelation/DefaultMouseClickReductionRuleTest.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/src/test/java/de/ugoe/cs/quest/tasktrees/temporalrelation/DefaultMouseClickReductionRuleTest.java	(revision 540)
@@ -0,0 +1,174 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: TaskTreeManagerTest.java,v $
+// Version   : $Revision: 0.0 $  $Author: Patrick $  $Date: 08.11.2011 21:32:36 $
+// Project   : TaskTreePerformanceTest
+// Creation  : 2011 by Patrick
+// Copyright : Patrick Harms, 2011
+//-------------------------------------------------------------------------------------------------
+
+package de.ugoe.cs.quest.tasktrees.temporalrelation;
+
+import org.junit.Test;
+
+import de.ugoe.cs.quest.eventcore.guimodel.GUIElement;
+import de.ugoe.cs.quest.eventcore.userinteraction.MouseButtonDown;
+import de.ugoe.cs.quest.eventcore.userinteraction.MouseButtonInteraction;
+import de.ugoe.cs.quest.eventcore.userinteraction.MouseButtonUp;
+import de.ugoe.cs.quest.eventcore.userinteraction.MouseClick;
+import de.ugoe.cs.quest.tasktrees.testutils.DummyGUIElement;
+import de.ugoe.cs.quest.tasktrees.testutils.DummyInteraction;
+import de.ugoe.cs.quest.tasktrees.testutils.TaskTreeChecker;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ *
+ * @version $Revision: $ $Date: $
+ * @author  2011, last modified by $Author: $
+ */
+//-------------------------------------------------------------------------------------------------
+public class DefaultMouseClickReductionRuleTest extends AbstractTemporalRelationshipTC
+{
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Test
+  public void testMouseClickInOneSequenceElement()
+  {
+    MouseButtonInteraction.Button leftBtn = MouseButtonInteraction.Button.LEFT;
+    MouseButtonInteraction.Button middleBtn = MouseButtonInteraction.Button.MIDDLE;
+    MouseButtonInteraction.Button rightBtn = MouseButtonInteraction.Button.RIGHT;
+    
+    GUIElement element1 = new DummyGUIElement("elem1");
+    GUIElement element2 = new DummyGUIElement("elem1");
+    
+    simulateInteraction(element1, new MouseButtonDown(leftBtn));
+    simulateInteraction(element1, new MouseButtonUp(leftBtn));
+    simulateInteraction(element1, new MouseClick(leftBtn));
+
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence {" +
+       "  Interaction LeftMouseClick {}" +
+       "}", getTaskTree());
+    
+    simulateInteraction(element1, new DummyInteraction("bla", 1));
+    simulateInteraction(element1, new DummyInteraction("bli", 1));
+    simulateInteraction(element1, new MouseButtonDown(middleBtn));
+    simulateInteraction(element1, new MouseButtonUp(middleBtn));
+    simulateInteraction(element1, new MouseClick(middleBtn));
+    simulateInteraction(element1, new DummyInteraction("blo", 1));
+    simulateInteraction(element1, new DummyInteraction("blu", 1));
+
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence {" +
+       "  Interaction LeftMouseClick {}" +
+       "  Interaction bla {}" +
+       "  Interaction bli {}" +
+       "  Interaction MiddleMouseClick {}" +
+       "  Interaction blo {}" +
+       "  Interaction blu {}" +
+       "}", getTaskTree());
+
+    simulateInteraction(element2, new DummyInteraction("bla", 1));
+    simulateInteraction(element2, new DummyInteraction("bli", 1));
+    simulateInteraction(element2, new MouseButtonDown(rightBtn));
+    simulateInteraction(element2, new MouseButtonUp(rightBtn));
+    simulateInteraction(element2, new MouseClick(rightBtn));
+    simulateInteraction(element2, new DummyInteraction("blo", 1));
+    simulateInteraction(element2, new DummyInteraction("blu", 1));
+
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence0 {" +
+       "  Sequence sequence1 {" +
+       "    Interaction LeftMouseClick {}" +
+       "    Interaction bla {}" +
+       "    Interaction bli {}" +
+       "    Interaction MiddleMouseClick {}" +
+       "    Interaction blo {}" +
+       "    Interaction blu {}" +
+       "  }" +
+       "  Sequence sequence2 {" +
+       "    Interaction bla {}" +
+       "    Interaction bli {}" +
+       "    Interaction RightMouseClick {}" +
+       "    Interaction blo {}" +
+       "    Interaction blu {}" +
+       "  }" +
+       "}", getTaskTree());
+
+    simulateInteraction(element1, new MouseButtonDown(leftBtn));
+    simulateInteraction(element1, new MouseButtonUp(leftBtn));
+    simulateInteraction(element2, new MouseClick(leftBtn));
+
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence0 {" +
+       "  Sequence sequence1 {" +
+       "    Interaction LeftMouseClick {}" +
+       "    Interaction bla {}" +
+       "    Interaction bli {}" +
+       "    Interaction MiddleMouseClick {}" +
+       "    Interaction blo {}" +
+       "    Interaction blu {}" +
+       "  }" +
+       "  Sequence sequence2 {" +
+       "    Interaction bla {}" +
+       "    Interaction bli {}" +
+       "    Interaction RightMouseClick {}" +
+       "    Interaction blo {}" +
+       "    Interaction blu {}" +
+       "  }" +
+       "  Sequence sequence3 {" +
+       "    Interaction LeftMouseButtonDown {}" +
+       "    Interaction LeftMouseButtonUp {}" +
+       "  }" +
+       "  Sequence sequence4 {" +
+       "    Interaction LeftMouseClick {}" +
+       "  }" +
+       "}", getTaskTree());
+
+    simulateInteraction(element1, new MouseButtonDown(middleBtn));
+    simulateInteraction(element1, new MouseButtonUp(middleBtn));
+    simulateInteraction(element1, new MouseClick(rightBtn));
+    simulateInteraction(element2, new DummyInteraction("bla", 1));
+
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence0 {" +
+       "  Sequence sequence1 {" +
+       "    Interaction LeftMouseClick {}" +
+       "    Interaction bla {}" +
+       "    Interaction bli {}" +
+       "    Interaction MiddleMouseClick {}" +
+       "    Interaction blo {}" +
+       "    Interaction blu {}" +
+       "  }" +
+       "  Sequence sequence2 {" +
+       "    Interaction bla {}" +
+       "    Interaction bli {}" +
+       "    Interaction RightMouseClick {}" +
+       "    Interaction blo {}" +
+       "    Interaction blu {}" +
+       "  }" +
+       "  Sequence sequence3 {" +
+       "    Interaction LeftMouseButtonDown {}" +
+       "    Interaction LeftMouseButtonUp {}" +
+       "  }" +
+       "  Sequence sequence4 {" +
+       "    Interaction LeftMouseClick {}" +
+       "  }" +
+       "  Sequence sequence5 {" +
+       "    Sequence sequence6 {" +
+       "      Interaction MiddleMouseButtonDown {}" +
+       "      Interaction MiddleMouseButtonUp {}" +
+       "    }" +
+       "    Interaction RightMouseClick {}" +
+       "  }" +
+       "  Sequence sequence7 {" +
+       "    Interaction bla {}" +
+       "  }" +
+       "}", getTaskTree());
+
+  }
+  
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/src/test/java/de/ugoe/cs/quest/tasktrees/temporalrelation/DefaultTextInputReductionRuleTest.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/src/test/java/de/ugoe/cs/quest/tasktrees/temporalrelation/DefaultTextInputReductionRuleTest.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/src/test/java/de/ugoe/cs/quest/tasktrees/temporalrelation/DefaultTextInputReductionRuleTest.java	(revision 540)
@@ -0,0 +1,411 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: DefaultIterationDetectionRuleTest.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 28.04.2012 $
+// Project   : TaskTreeTemporalRelationship
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.temporalrelation;
+
+import org.junit.Test;
+
+import de.ugoe.cs.quest.eventcore.guimodel.GUIElement;
+import de.ugoe.cs.quest.eventcore.guimodel.TextField;
+import de.ugoe.cs.quest.eventcore.userinteraction.KeyPressed;
+import de.ugoe.cs.quest.eventcore.userinteraction.KeyReleased;
+import de.ugoe.cs.quest.tasktrees.testutils.DummyGUIElement;
+import de.ugoe.cs.quest.tasktrees.testutils.TaskTreeChecker;
+import de.ugoe.cs.tasktree.keyboardmaps.VirtualKey;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 28.04.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public class DefaultTextInputReductionRuleTest extends AbstractTemporalRelationshipTC
+{
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Test
+  public void testSimpleTextEntry()
+  {
+    GUIElement element1 = new DummyTextField("elem1");
+    simulateInteraction(element1, new KeyPressed(VirtualKey.LETTER_A));
+    simulateInteraction(element1, new KeyReleased(VirtualKey.LETTER_A));
+    new TaskTreeChecker(true).assertTaskTree
+      ("Sequence sequence0 {" +
+       "  TextInputInteraction TextInput a {" +
+       "    Interaction KeyPressed LETTER_A {}" +
+       "    Interaction KeyReleased LETTER_A {}" +
+       "  }" +
+       "}", getTaskTree());    
+
+    simulateInteraction(element1, new KeyPressed(VirtualKey.LETTER_B));
+    simulateInteraction(element1, new KeyReleased(VirtualKey.LETTER_B));
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence0 {" +
+       "  TextInputInteraction TextInput ab {" +
+       "    Interaction KeyPressed LETTER_A {}" +
+       "    Interaction KeyReleased LETTER_A {}" +
+       "    Interaction KeyPressed LETTER_B {}" +
+       "    Interaction KeyReleased LETTER_B {}" +
+       "  }" +
+       "}", getTaskTree());    
+
+    simulateInteraction(element1, new KeyPressed(VirtualKey.SHIFT));
+    simulateInteraction(element1, new KeyPressed(VirtualKey.LETTER_C));
+    simulateInteraction(element1, new KeyReleased(VirtualKey.LETTER_C));
+    simulateInteraction(element1, new KeyReleased(VirtualKey.SHIFT));
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence0 {" +
+       "  TextInputInteraction TextInput abC {" +
+       "    Interaction KeyPressed LETTER_A {}" +
+       "    Interaction KeyReleased LETTER_A {}" +
+       "    Interaction KeyPressed LETTER_B {}" +
+       "    Interaction KeyReleased LETTER_B {}" +
+       "    Interaction KeyPressed SHIFT {}" +
+       "    Interaction KeyPressed LETTER_C {}" +
+       "    Interaction KeyReleased LETTER_C {}" +
+       "    Interaction KeyReleased SHIFT {}" +
+       "  }" +
+       "}", getTaskTree());    
+
+    simulateInteraction(element1, new KeyPressed(VirtualKey.SHIFT));
+    simulateInteraction(element1, new KeyPressed(VirtualKey.LETTER_D));
+    simulateInteraction(element1, new KeyReleased(VirtualKey.LETTER_D));
+    simulateInteraction(element1, new KeyPressed(VirtualKey.LETTER_E));
+    simulateInteraction(element1, new KeyReleased(VirtualKey.LETTER_E));
+    simulateInteraction(element1, new KeyPressed(VirtualKey.LETTER_F));
+    simulateInteraction(element1, new KeyReleased(VirtualKey.LETTER_F));
+    simulateInteraction(element1, new KeyReleased(VirtualKey.SHIFT));
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence0 {" +
+       "  TextInputInteraction TextInput abCDEF {" +
+       "    Interaction KeyPressed LETTER_A {}" +
+       "    Interaction KeyReleased LETTER_A {}" +
+       "    Interaction KeyPressed LETTER_B {}" +
+       "    Interaction KeyReleased LETTER_B {}" +
+       "    Interaction KeyPressed SHIFT {}" +
+       "    Interaction KeyPressed LETTER_C {}" +
+       "    Interaction KeyReleased LETTER_C {}" +
+       "    Interaction KeyReleased SHIFT {}" +
+       "    Interaction KeyPressed SHIFT {}" +
+       "    Interaction KeyPressed LETTER_D {}" +
+       "    Interaction KeyReleased LETTER_D {}" +
+       "    Interaction KeyPressed LETTER_E {}" +
+       "    Interaction KeyReleased LETTER_E {}" +
+       "    Interaction KeyPressed LETTER_F {}" +
+       "    Interaction KeyReleased LETTER_F {}" +
+       "    Interaction KeyReleased SHIFT {}" +
+       "  }" +
+       "}", getTaskTree());    
+
+
+    simulateInteraction(element1, new KeyPressed(VirtualKey.SHIFT));
+    simulateInteraction(element1, new KeyPressed(VirtualKey.SHIFT));
+    simulateInteraction(element1, new KeyPressed(VirtualKey.LETTER_G));
+    simulateInteraction(element1, new KeyReleased(VirtualKey.LETTER_G));
+    simulateInteraction(element1, new KeyReleased(VirtualKey.SHIFT));
+    simulateInteraction(element1, new KeyReleased(VirtualKey.SHIFT));
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence0 {" +
+       "  TextInputInteraction TextInput abCDEFg {" +
+       "    Interaction KeyPressed LETTER_A {}" +
+       "    Interaction KeyReleased LETTER_A {}" +
+       "    Interaction KeyPressed LETTER_B {}" +
+       "    Interaction KeyReleased LETTER_B {}" +
+       "    Interaction KeyPressed SHIFT {}" +
+       "    Interaction KeyPressed LETTER_C {}" +
+       "    Interaction KeyReleased LETTER_C {}" +
+       "    Interaction KeyReleased SHIFT {}" +
+       "    Interaction KeyPressed SHIFT {}" +
+       "    Interaction KeyPressed LETTER_D {}" +
+       "    Interaction KeyReleased LETTER_D {}" +
+       "    Interaction KeyPressed LETTER_E {}" +
+       "    Interaction KeyReleased LETTER_E {}" +
+       "    Interaction KeyPressed LETTER_F {}" +
+       "    Interaction KeyReleased LETTER_F {}" +
+       "    Interaction KeyReleased SHIFT {}" +
+       "    Interaction KeyPressed SHIFT {}" +
+       "    Interaction KeyPressed SHIFT {}" +
+       "    Interaction KeyPressed LETTER_G {}" +
+       "    Interaction KeyReleased LETTER_G {}" +
+       "    Interaction KeyReleased SHIFT {}" +
+       "    Interaction KeyReleased SHIFT {}" +
+       "  }" +
+       "}", getTaskTree());    
+
+  }
+  
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Test
+  public void testTextEntryOnDifferentGuiElements()
+  {
+    GUIElement element1 = new DummyTextField("elem1");
+    GUIElement element2 = new DummyTextField("elem2");
+    simulateInteraction(element1, new KeyPressed(VirtualKey.LETTER_A));
+    simulateInteraction(element1, new KeyReleased(VirtualKey.LETTER_A));
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence0 {" +
+       "  TextInputInteraction TextInput a {" +
+       "    Interaction KeyPressed LETTER_A {}" +
+       "    Interaction KeyReleased LETTER_A {}" +
+       "  }" +
+       "}", getTaskTree());    
+
+    simulateInteraction(element2, new KeyPressed(VirtualKey.LETTER_B));
+    simulateInteraction(element2, new KeyReleased(VirtualKey.LETTER_B));
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence0 {" +
+       "  Sequence sequence1 {" +
+       "    TextInputInteraction TextInput a {" +
+       "      Interaction KeyPressed LETTER_A {}" +
+       "      Interaction KeyReleased LETTER_A {}" +
+       "    }" +
+       "  }" +
+       "  Sequence sequence2 {" +
+       "    TextInputInteraction TextInput b {" +
+       "      Interaction KeyPressed LETTER_B {}" +
+       "      Interaction KeyReleased LETTER_B {}" +
+       "    }" +
+       "  }" +
+       "}", getTaskTree());    
+
+    simulateInteraction(element1, new KeyPressed(VirtualKey.SHIFT));
+    simulateInteraction(element1, new KeyPressed(VirtualKey.LETTER_C));
+    simulateInteraction(element1, new KeyReleased(VirtualKey.LETTER_C));
+    simulateInteraction(element1, new KeyReleased(VirtualKey.SHIFT));
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence0 {" +
+       "  Sequence sequence1 {" +
+       "    TextInputInteraction TextInput a {" +
+       "      Interaction KeyPressed LETTER_A {}" +
+       "      Interaction KeyReleased LETTER_A {}" +
+       "    }" +
+       "  }" +
+       "  Sequence sequence2 {" +
+       "    TextInputInteraction TextInput b {" +
+       "      Interaction KeyPressed LETTER_B {}" +
+       "      Interaction KeyReleased LETTER_B {}" +
+       "    }" +
+       "  }" +
+       "  Sequence sequence3 {" +
+       "    TextInputInteraction TextInput C {" +
+       "      Interaction KeyPressed SHIFT {}" +
+       "      Interaction KeyPressed LETTER_C {}" +
+       "      Interaction KeyReleased LETTER_C {}" +
+       "      Interaction KeyReleased SHIFT {}" +
+       "    }" +
+       "  }" +
+       "}", getTaskTree());    
+
+    simulateInteraction(element2, new KeyPressed(VirtualKey.SHIFT));
+    simulateInteraction(element2, new KeyPressed(VirtualKey.LETTER_D));
+    simulateInteraction(element2, new KeyReleased(VirtualKey.LETTER_D));
+    simulateInteraction(element2, new KeyPressed(VirtualKey.LETTER_E));
+    simulateInteraction(element2, new KeyReleased(VirtualKey.LETTER_E));
+    simulateInteraction(element2, new KeyPressed(VirtualKey.LETTER_F));
+    simulateInteraction(element2, new KeyReleased(VirtualKey.LETTER_F));
+    simulateInteraction(element2, new KeyReleased(VirtualKey.SHIFT));
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence0 {" +
+       "  Sequence sequence1 {" +
+       "    TextInputInteraction TextInput a {" +
+       "      Interaction KeyPressed LETTER_A {}" +
+       "      Interaction KeyReleased LETTER_A {}" +
+       "    }" +
+       "  }" +
+       "  Sequence sequence2 {" +
+       "    TextInputInteraction TextInput b {" +
+       "      Interaction KeyPressed LETTER_B {}" +
+       "      Interaction KeyReleased LETTER_B {}" +
+       "    }" +
+       "  }" +
+       "  Sequence sequence3 {" +
+       "    TextInputInteraction TextInput C {" +
+       "      Interaction KeyPressed SHIFT {}" +
+       "      Interaction KeyPressed LETTER_C {}" +
+       "      Interaction KeyReleased LETTER_C {}" +
+       "      Interaction KeyReleased SHIFT {}" +
+       "    }" +
+       "  }" +
+       "  Sequence sequence4 {" +
+       "    TextInputInteraction TextInput DEF {" +
+       "      Interaction KeyPressed SHIFT {}" +
+       "      Interaction KeyPressed LETTER_D {}" +
+       "      Interaction KeyReleased LETTER_D {}" +
+       "      Interaction KeyPressed LETTER_E {}" +
+       "      Interaction KeyReleased LETTER_E {}" +
+       "      Interaction KeyPressed LETTER_F {}" +
+       "      Interaction KeyReleased LETTER_F {}" +
+       "      Interaction KeyReleased SHIFT {}" +
+       "    }" +
+       "  }" +
+       "}", getTaskTree());    
+
+
+    simulateInteraction(element1, new KeyPressed(VirtualKey.SHIFT));
+    simulateInteraction(element1, new KeyPressed(VirtualKey.SHIFT));
+    simulateInteraction(element1, new KeyPressed(VirtualKey.LETTER_G));
+    simulateInteraction(element1, new KeyReleased(VirtualKey.LETTER_G));
+    simulateInteraction(element1, new KeyReleased(VirtualKey.SHIFT));
+    simulateInteraction(element1, new KeyReleased(VirtualKey.SHIFT));
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence0 {" +
+       "  Sequence sequence1 {" +
+       "    TextInputInteraction TextInput a {" +
+       "      Interaction KeyPressed LETTER_A {}" +
+       "      Interaction KeyReleased LETTER_A {}" +
+       "    }" +
+       "  }" +
+       "  Sequence sequence2 {" +
+       "    TextInputInteraction TextInput b {" +
+       "      Interaction KeyPressed LETTER_B {}" +
+       "      Interaction KeyReleased LETTER_B {}" +
+       "    }" +
+       "  }" +
+       "  Sequence sequence3 {" +
+       "    TextInputInteraction TextInput C {" +
+       "      Interaction KeyPressed SHIFT {}" +
+       "      Interaction KeyPressed LETTER_C {}" +
+       "      Interaction KeyReleased LETTER_C {}" +
+       "      Interaction KeyReleased SHIFT {}" +
+       "    }" +
+       "  }" +
+       "  Sequence sequence4 {" +
+       "    TextInputInteraction TextInput DEF {" +
+       "      Interaction KeyPressed SHIFT {}" +
+       "      Interaction KeyPressed LETTER_D {}" +
+       "      Interaction KeyReleased LETTER_D {}" +
+       "      Interaction KeyPressed LETTER_E {}" +
+       "      Interaction KeyReleased LETTER_E {}" +
+       "      Interaction KeyPressed LETTER_F {}" +
+       "      Interaction KeyReleased LETTER_F {}" +
+       "      Interaction KeyReleased SHIFT {}" +
+       "    }" +
+       "  }" +
+       "  Sequence sequence5 {" +
+       "    TextInputInteraction TextInput g {" +
+       "      Interaction KeyPressed SHIFT {}" +
+       "      Interaction KeyPressed SHIFT {}" +
+       "      Interaction KeyPressed LETTER_G {}" +
+       "      Interaction KeyReleased LETTER_G {}" +
+       "      Interaction KeyReleased SHIFT {}" +
+       "      Interaction KeyReleased SHIFT {}" +
+       "    }" +
+       "  }" +
+       "}", getTaskTree());    
+
+  }
+  
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Test
+  public void testUsageOfBackspace()
+  {
+    GUIElement element1 = new DummyTextField("elem1");
+    simulateInteraction(element1, new KeyPressed(VirtualKey.LETTER_A));
+    simulateInteraction(element1, new KeyReleased(VirtualKey.LETTER_A));
+    simulateInteraction(element1, new KeyPressed(VirtualKey.LETTER_B));
+    simulateInteraction(element1, new KeyReleased(VirtualKey.LETTER_B));
+    simulateInteraction(element1, new KeyPressed(VirtualKey.LETTER_C));
+    simulateInteraction(element1, new KeyReleased(VirtualKey.LETTER_C));
+    simulateInteraction(element1, new KeyPressed(VirtualKey.LETTER_D));
+    simulateInteraction(element1, new KeyReleased(VirtualKey.LETTER_D));
+    simulateInteraction(element1, new KeyPressed(VirtualKey.BACK_SPACE));
+    simulateInteraction(element1, new KeyReleased(VirtualKey.BACK_SPACE));
+    simulateInteraction(element1, new KeyPressed(VirtualKey.LETTER_E));
+    simulateInteraction(element1, new KeyReleased(VirtualKey.LETTER_E));
+    simulateInteraction(element1, new KeyPressed(VirtualKey.LETTER_F));
+    simulateInteraction(element1, new KeyReleased(VirtualKey.LETTER_F));
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence0 {" +
+       "  TextInputInteraction TextInput abcef {" +
+       "    Interaction KeyPressed LETTER_A {}" +
+       "    Interaction KeyReleased LETTER_A {}" +
+       "    Interaction KeyPressed LETTER_B {}" +
+       "    Interaction KeyReleased LETTER_B {}" +
+       "    Interaction KeyPressed LETTER_C {}" +
+       "    Interaction KeyReleased LETTER_C {}" +
+       "    Interaction KeyPressed LETTER_D {}" +
+       "    Interaction KeyReleased LETTER_D {}" +
+       "    Interaction KeyPressed BACK_SPACE {}" +
+       "    Interaction KeyReleased BACK_SPACE {}" +
+       "    Interaction KeyPressed LETTER_E {}" +
+       "    Interaction KeyReleased LETTER_E {}" +
+       "    Interaction KeyPressed LETTER_F {}" +
+       "    Interaction KeyReleased LETTER_F {}" +
+       "  }" +
+       "}", getTaskTree());    
+
+    simulateInteraction(element1, new KeyPressed(VirtualKey.BACK_SPACE));
+    simulateInteraction(element1, new KeyReleased(VirtualKey.BACK_SPACE));
+    simulateInteraction(element1, new KeyPressed(VirtualKey.BACK_SPACE));
+    simulateInteraction(element1, new KeyReleased(VirtualKey.BACK_SPACE));
+    simulateInteraction(element1, new KeyPressed(VirtualKey.BACK_SPACE));
+    simulateInteraction(element1, new KeyReleased(VirtualKey.BACK_SPACE));
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence0 {" +
+       "  TextInputInteraction TextInput ab {" +
+       "    Interaction KeyPressed LETTER_A {}" +
+       "    Interaction KeyReleased LETTER_A {}" +
+       "    Interaction KeyPressed LETTER_B {}" +
+       "    Interaction KeyReleased LETTER_B {}" +
+       "    Interaction KeyPressed LETTER_C {}" +
+       "    Interaction KeyReleased LETTER_C {}" +
+       "    Interaction KeyPressed LETTER_D {}" +
+       "    Interaction KeyReleased LETTER_D {}" +
+       "    Interaction KeyPressed BACK_SPACE {}" +
+       "    Interaction KeyReleased BACK_SPACE {}" +
+       "    Interaction KeyPressed LETTER_E {}" +
+       "    Interaction KeyReleased LETTER_E {}" +
+       "    Interaction KeyPressed LETTER_F {}" +
+       "    Interaction KeyReleased LETTER_F {}" +
+       "    Interaction KeyPressed BACK_SPACE {}" +
+       "    Interaction KeyReleased BACK_SPACE {}" +
+       "    Interaction KeyPressed BACK_SPACE {}" +
+       "    Interaction KeyReleased BACK_SPACE {}" +
+       "    Interaction KeyPressed BACK_SPACE {}" +
+       "    Interaction KeyReleased BACK_SPACE {}" +
+       "  }" +
+       "}", getTaskTree());    
+
+  }
+  
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  private static class DummyTextField extends DummyGUIElement implements TextField
+  {
+
+    //---------------------------------------------------------------------------------------------
+    /**
+     * TODO: comment
+     *
+     * @param name
+     */
+    //---------------------------------------------------------------------------------------------
+    public DummyTextField(String name)
+    {
+      super(name);
+    }
+
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/src/test/java/de/ugoe/cs/quest/tasktrees/temporalrelation/TrackBarSelectionDetectionRuleTest.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/src/test/java/de/ugoe/cs/quest/tasktrees/temporalrelation/TrackBarSelectionDetectionRuleTest.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/src/test/java/de/ugoe/cs/quest/tasktrees/temporalrelation/TrackBarSelectionDetectionRuleTest.java	(revision 540)
@@ -0,0 +1,180 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: DefaultIterationDetectionRuleTest.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 28.04.2012 $
+// Project   : TaskTreeTemporalRelationship
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.temporalrelation;
+
+import org.junit.Test;
+
+import de.ugoe.cs.quest.eventcore.guimodel.GUIElement;
+import de.ugoe.cs.quest.eventcore.guimodel.TrackBar;
+import de.ugoe.cs.quest.eventcore.userinteraction.ValueSelection;
+import de.ugoe.cs.quest.tasktrees.testutils.DummyGUIElement;
+import de.ugoe.cs.quest.tasktrees.testutils.DummyInteraction;
+import de.ugoe.cs.quest.tasktrees.testutils.TaskTreeChecker;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 28.04.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public class TrackBarSelectionDetectionRuleTest extends AbstractTemporalRelationshipTC
+{
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Test
+  public void testSimpleDetection() throws Exception
+  {
+    GUIElement element1 = new DummyTrackBar();
+    simulateInteraction(element1, new ValueSelection<Integer>(1));
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence1 {" +
+       "  Iteration interation1 {" +
+       "    Selection selection1 {" +
+       "      Interaction ValueSelection {}" +
+       "    }" +
+       "  }" +
+       "}", getTaskTree());    
+
+    simulateInteraction(element1, new ValueSelection<Integer>(2));
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence1 {" +
+       "  Iteration interation1 {" +
+       "    Selection selection1 {" +
+       "      Interaction ValueSelection {}" +
+       "      Interaction ValueSelection {}" +
+       "    }" +
+       "  }" +
+       "}", getTaskTree());    
+
+    simulateInteraction(element1, new ValueSelection<Integer>(3));
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence1 {" +
+       "  Iteration interation1 {" +
+       "    Selection selection1 {" +
+       "      Interaction ValueSelection {}" +
+       "      Interaction ValueSelection {}" +
+       "      Interaction ValueSelection {}" +
+       "    }" +
+       "  }" +
+       "}", getTaskTree());    
+
+    simulateInteraction(element1, new ValueSelection<Integer>(2));
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence1 {" +
+       "  Iteration interation1 {" +
+       "    Selection selection1 {" +
+       "      Interaction ValueSelection {}" +
+       "      Interaction ValueSelection {}" +
+       "      Interaction ValueSelection {}" +
+       "    }" +
+       "  }" +
+       "}", getTaskTree());    
+
+    simulateInteraction(element1, new ValueSelection<Integer>(3));
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence1 {" +
+       "  Iteration interation1 {" +
+       "    Selection selection1 {" +
+       "      Interaction ValueSelection {}" +
+       "      Interaction ValueSelection {}" +
+       "      Interaction ValueSelection {}" +
+       "    }" +
+       "  }" +
+       "}", getTaskTree());
+
+  }
+  
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Test
+  public void testComplexDetection() throws Exception
+  {
+    GUIElement element1 = new DummyTrackBar();
+    simulateInteraction(element1, new ValueSelection<Integer>(1));
+    simulateInteraction(element1, new ValueSelection<Integer>(2));
+    simulateInteraction(element1, new ValueSelection<Integer>(3));
+    simulateInteraction(element1, new ValueSelection<Integer>(1));
+    simulateInteraction(element1, new DummyInteraction("bla", 1));
+    simulateInteraction(element1, new DummyInteraction("bla", 2));
+    simulateInteraction(element1, new ValueSelection<Integer>(2));
+    simulateInteraction(element1, new ValueSelection<Integer>(1));
+    simulateInteraction(element1, new DummyInteraction("bla", 3));
+    simulateInteraction(element1, new ValueSelection<Integer>(3));
+    simulateInteraction(element1, new ValueSelection<Integer>(2));
+    simulateInteraction(element1, new ValueSelection<Integer>(3));
+    simulateInteraction(element1, new DummyInteraction("bla", 1));
+    simulateInteraction(element1, new DummyInteraction("bla", 2));
+    simulateInteraction(element1, new ValueSelection<Integer>(1));
+    simulateInteraction(element1, new ValueSelection<Integer>(1));
+    
+    new TaskTreeChecker().assertTaskTree
+      ("Sequence sequence1 {" +
+       "  Iteration interation1 {" +
+       "    Selection selection1 {" +
+       "      Interaction ValueSelection {}" +
+       "      Interaction ValueSelection {}" +
+       "      Interaction ValueSelection {}" +
+       "    }" +
+       "  }" +
+       "  Interaction bla {}" +
+       "  Interaction bla {}" +
+       "  Iteration interation2 {" +
+       "    Selection selection2 {" +
+       "      Interaction ValueSelection {}" +
+       "      Interaction ValueSelection {}" +
+       "    }" +
+       "  }" +
+       "  Interaction bla {}" +
+       "  Iteration interation3 {" +
+       "    Selection selection3 {" +
+       "      Interaction ValueSelection {}" +
+       "      Interaction ValueSelection {}" +
+       "    }" +
+       "  }" +
+       "  Interaction bla {}" +
+       "  Interaction bla {}" +
+       "  Iteration interation4 {" +
+       "    Selection selection4 {" +
+       "      Interaction ValueSelection {}" +
+       "    }" +
+       "  }" +
+       "}", getTaskTree());    
+  }
+  
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO comment
+   * 
+   * @version $Revision: $ $Date: 28.04.2012$
+   * @author 2012, last modified by $Author: patrick$
+   */
+  //-----------------------------------------------------------------------------------------------
+  public class DummyTrackBar extends DummyGUIElement implements TrackBar
+  {
+
+    //---------------------------------------------------------------------------------------------
+    /**
+     *
+     */
+    //---------------------------------------------------------------------------------------------
+    public DummyTrackBar()
+    {
+      super("DummyTrackBar");
+    }
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/src/test/java/de/ugoe/cs/quest/tasktrees/testutils/DummyGUIElement.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/src/test/java/de/ugoe/cs/quest/tasktrees/testutils/DummyGUIElement.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/src/test/java/de/ugoe/cs/quest/tasktrees/testutils/DummyGUIElement.java	(revision 540)
@@ -0,0 +1,59 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: DummyGUIElement.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 02.04.2012 $
+// Project   : TaskTreeTestUtils
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.testutils;
+
+import de.ugoe.cs.quest.eventcore.guimodel.AbstractDefaultGUIElement;
+import de.ugoe.cs.quest.eventcore.guimodel.GUIElement;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 02.04.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public class DummyGUIElement extends AbstractDefaultGUIElement
+  implements GUIElement
+{
+  /** */
+  private String mName;
+
+  //---------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //---------------------------------------------------------------------------------------------
+  public DummyGUIElement(String name)
+  {
+    super();
+    mName = name;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see java.lang.Object#toString()
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public String toString()
+  {
+    return mName;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.harms.attef.userinteraction.GUIElement#equals(GUIElement)
+   */
+  //-----------------------------------------------------------------------------------------------
+  public boolean equals(GUIElement other)
+  {
+    return this == other;
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/src/test/java/de/ugoe/cs/quest/tasktrees/testutils/DummyInteraction.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/src/test/java/de/ugoe/cs/quest/tasktrees/testutils/DummyInteraction.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/src/test/java/de/ugoe/cs/quest/tasktrees/testutils/DummyInteraction.java	(revision 540)
@@ -0,0 +1,102 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: DummyInteraction.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 02.04.2012 $
+// Project   : TaskTreeTestUtils
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.testutils;
+
+import de.ugoe.cs.quest.eventcore.userinteraction.Interaction;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 02.04.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public class DummyInteraction implements Interaction
+{
+  /** */
+  private int mInteractionNumber;
+  
+  /** */
+  private String mInteractionType;
+  
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * @param interactionNumber
+   * @param interactionType
+   */
+  //-----------------------------------------------------------------------------------------------
+  public DummyInteraction(String interactionType, int interactionNumber)
+  {
+    super();
+    mInteractionNumber = interactionNumber;
+    mInteractionType = interactionType;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.harms.attef.userinteraction.Interaction#getName()
+   */
+  //-----------------------------------------------------------------------------------------------
+  public String getName()
+  {
+    return mInteractionType;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see java.lang.Object#toString()
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public String toString()
+  {
+    return mInteractionType;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (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;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * @return the interactionType
+   */
+  //-----------------------------------------------------------------------------------------------
+  public String getInteractionType()
+  {
+    return mInteractionType;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * @return the interactionNumber
+   */
+  //-----------------------------------------------------------------------------------------------
+  public int getInteractionNumber()
+  {
+    return mInteractionNumber;
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/src/test/java/de/ugoe/cs/quest/tasktrees/testutils/DummyTextField.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/src/test/java/de/ugoe/cs/quest/tasktrees/testutils/DummyTextField.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/src/test/java/de/ugoe/cs/quest/tasktrees/testutils/DummyTextField.java	(revision 540)
@@ -0,0 +1,34 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: DummyGUIElement.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 02.04.2012 $
+// Project   : TaskTreeTestUtils
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.testutils;
+
+import de.ugoe.cs.quest.eventcore.guimodel.TextField;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 02.04.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public class DummyTextField extends DummyGUIElement
+  implements TextField
+{
+
+  //---------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //---------------------------------------------------------------------------------------------
+  public DummyTextField(String name)
+  {
+    super("text field \"" + name + "\"");
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/src/test/java/de/ugoe/cs/quest/tasktrees/testutils/SimpleLogFormatter.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/src/test/java/de/ugoe/cs/quest/tasktrees/testutils/SimpleLogFormatter.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/src/test/java/de/ugoe/cs/quest/tasktrees/testutils/SimpleLogFormatter.java	(revision 540)
@@ -0,0 +1,89 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: TestLogger.java,v $
+// Version   : $Revision: 0.0 $  $Author: Patrick $  $Date: 26.11.2011 15:26:38 $
+// Project   : TaskTreePerformanceTest
+// Creation  : 2011 by Patrick
+// Copyright : Patrick Harms, 2011
+//-------------------------------------------------------------------------------------------------
+
+package de.ugoe.cs.quest.tasktrees.testutils;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.text.SimpleDateFormat;
+import java.util.logging.Formatter;
+import java.util.logging.LogRecord;
+
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ *
+ * @version $Revision: $ $Date: $
+ * @author  2011, last modified by $Author: $
+ */
+//-------------------------------------------------------------------------------------------------
+
+public class SimpleLogFormatter extends Formatter
+{
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public String format(LogRecord record)
+  {
+    StringBuffer result = new StringBuffer();
+    result.append(record.getLevel().getName().charAt(0));
+    result.append(" | ");
+    result.append(new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss,SSS").format(record.getMillis()));
+    result.append(" | ");
+    tailValue("" + record.getThreadID(), 6, result);
+    result.append(" | ");
+    tailValue(record.getLoggerName(), 30, result);
+    result.append(" | ");
+    result.append(record.getMessage());
+    
+    if (record.getThrown() != null)
+    {
+      ByteArrayOutputStream out = new ByteArrayOutputStream();
+      record.getThrown().printStackTrace(new PrintStream(out));
+      result.append("\n");
+      result.append(out.toString());
+      try
+      {
+        out.close();
+      }
+      catch (IOException e)
+      {
+        // ignore
+      }
+    }
+    
+    result.append("\n");
+    
+    return result.toString();
+  }
+  
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  private void tailValue(String value, int length, StringBuffer output)
+  {
+    for (int i = value.length() - length - 1; i < value.length(); i++)
+    {
+      if (i < 0)
+      {
+        output.append(" ");
+      }
+      else
+      {
+        output.append(value.charAt(i));
+      }
+    }
+  }
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/src/test/java/de/ugoe/cs/quest/tasktrees/testutils/TaskTreeChecker.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/src/test/java/de/ugoe/cs/quest/tasktrees/testutils/TaskTreeChecker.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/src/test/java/de/ugoe/cs/quest/tasktrees/testutils/TaskTreeChecker.java	(revision 540)
@@ -0,0 +1,573 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: TaskTreeChecker.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 01.04.2012 $
+// Project   : TestUtils
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.testutils;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import de.ugoe.cs.quest.tasktrees.treeifc.InteractionTask;
+import de.ugoe.cs.quest.tasktrees.treeifc.Iteration;
+import de.ugoe.cs.quest.tasktrees.treeifc.NodeInfo;
+import de.ugoe.cs.quest.tasktrees.treeifc.Selection;
+import de.ugoe.cs.quest.tasktrees.treeifc.Sequence;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTree;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNode;
+import de.ugoe.cs.quest.tasktrees.treeifc.TextInputInteractionTask;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 01.04.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public class TaskTreeChecker
+{
+  /** */
+  private boolean mDoTrace;
+  
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  public TaskTreeChecker()
+  {
+    this(false);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  public TaskTreeChecker(boolean doTrace)
+  {
+    mDoTrace = doTrace;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  public void assertTaskTree(String taskTreeSpec, TaskTree taskTree)
+  {
+    Map<TaskTreeNode, Integer> taskMapCopy = new HashMap<TaskTreeNode, Integer>();
+    
+    for (Map.Entry<TaskTreeNode, NodeInfo> entry : taskTree.getTaskMap().entrySet())
+    {
+      if (entry.getValue().getNoOfOccurencesInTree() > 0)
+      {
+        taskMapCopy.put(entry.getKey(), entry.getValue().getNoOfOccurencesInTree());
+      }
+      else
+      {
+        taskMapCopy.put(entry.getKey(), 1);
+      }
+    }
+    
+    if (mDoTrace)
+    {
+      dumpTaskMap(taskMapCopy);
+    }
+
+    TaskSpec task = null;
+
+    Matcher matcher =
+      Pattern.compile("(\\s*(\\w+)\\s+(\\w+)\\s+((\\w*\\s)*)(\\{))|((\\}))").matcher(taskTreeSpec);
+    
+    do
+    {
+      if (!matcher.find())
+      {
+        if (!matcher.hitEnd())
+        {
+          throw new IllegalArgumentException("could not parse task specification");
+        }
+        else
+        {
+          break;
+        }
+      }
+      
+      task = parseTask(matcher);
+      if (task != null)
+      {
+        assertTaskAndChildrenInMapAndRemove(task, taskMapCopy);
+      }
+    }
+    while (task != null);
+    
+    assertTrue("more tasks in map, than expected", taskMapCopy.isEmpty());
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param taskTree
+   */
+  //-----------------------------------------------------------------------------------------------
+  public void dumpAsCheckString(TaskTree taskTree)
+  {
+    dumpNodeAsCheckString(taskTree.getRoot(), new int[4], "");
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param root
+   * @param string
+   */
+  //-----------------------------------------------------------------------------------------------
+  private void dumpNodeAsCheckString(TaskTreeNode node,
+                                     int[]        typeCounters,
+                                     String       indent)
+  {
+    System.err.print("       \"");
+    System.err.print(indent);
+    
+    if (node instanceof Sequence)
+    {
+      System.err.print("Sequence sequence");
+      System.err.print(typeCounters[0]++);
+      System.err.println(" {\" +");
+    }
+    else if (node instanceof Iteration)
+    {
+      System.err.print("Iteration iteration");
+      System.err.print(typeCounters[1]++);
+      System.err.println(" {\" +");
+    }
+    else if (node instanceof Selection)
+    {
+      System.err.print("Selection selection");
+      System.err.print(typeCounters[2]++);
+      System.err.println(" {\" +");
+    }
+    else if (node instanceof TextInputInteractionTask)
+    {
+      System.err.print("TextInputInteraction textInput");
+      System.err.print(typeCounters[3]++);
+      System.err.print(" ");
+      System.err.print(((TextInputInteractionTask) node).getEnteredText());
+      System.err.println(" {\" +");
+    }
+    else if (node instanceof InteractionTask)
+    {
+      System.err.print("Interaction ");
+      System.err.print(((InteractionTask) node).getInteraction().getName());
+      System.err.print(" {}\" +");
+    }
+    else
+    {
+      fail("unknown type of node in task tree " + node);
+    }
+    
+    for (TaskTreeNode child : node.getChildren())
+    {
+      dumpNodeAsCheckString(child, typeCounters, indent + "  ");
+    }
+    
+    if (!(node instanceof InteractionTask) ||
+        (node instanceof TextInputInteractionTask))
+    {
+      System.err.print("       \"");
+      System.err.print(indent);
+      System.err.print("}\" +");
+    }
+    
+    System.err.println();
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param taskTree
+   */
+  //-----------------------------------------------------------------------------------------------
+  public void dumpFullTaskTree(TaskTree taskTree) throws FileNotFoundException
+  {
+    PrintWriter out = null;
+    try
+    {
+      out = new PrintWriter(new FileOutputStream("taskTree.txt"));
+      dumpFullNode(taskTree.getRoot(), out, "");
+    }
+    finally
+    {
+      if (out != null)
+      {
+        out.close();
+      }
+    }
+    
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  private void dumpFullNode(TaskTreeNode node, PrintWriter out, String indent)
+  {
+    out.print(indent);
+    if (node instanceof Sequence)
+    {
+      out.println("Sequence");
+      out.print(indent);
+      out.println("{");
+    }
+    else if (node instanceof Iteration)
+    {
+      out.println("Iteration");
+      out.print(indent);
+      out.println("{");
+    }
+    else if (node instanceof Selection)
+    {
+      out.println("Selection");
+      out.print(indent);
+      out.println("{");
+    }
+    else if (node instanceof TextInputInteractionTask)
+    {
+      out.print("TextInputInteraction");
+      out.print(" ");
+      out.println(((TextInputInteractionTask) node).getEnteredText());
+      out.print(indent);
+      out.println("{");
+    }
+    else if (node instanceof InteractionTask)
+    {
+      out.print(((InteractionTask) node).getInteraction().getName());
+      out.print(" ");
+      out.print(((InteractionTask) node).getGUIElement());
+      out.print(" ");
+      out.print(((InteractionTask) node).getGUIElement().getOriginalTypeInfo());
+    }
+    else
+    {
+      fail("unknown type of node in task tree " + node);
+    }
+    
+    for (TaskTreeNode child : node.getChildren())
+    {
+      dumpFullNode(child, out, indent + "  ");
+    }
+    
+    if (!(node instanceof InteractionTask) ||
+        (node instanceof TextInputInteractionTask))
+    {
+      out.print(indent);
+      out.print("}");
+    }
+    
+    out.println();
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * 
+   */
+  //-----------------------------------------------------------------------------------------------
+  private TaskSpec parseTask(Matcher tokenMatcher)
+  {
+    String firstToken = tokenMatcher.group();
+    
+    if ("}".equals(firstToken))
+    {
+      throw new IllegalArgumentException("found a closing bracket at an unexpected place");
+    }
+    
+    TaskSpec task = new TaskSpec();
+    task.type = tokenMatcher.group(2);
+    task.interactionName = tokenMatcher.group(3);
+    task.additionalInfo = tokenMatcher.group(4).trim();
+    
+    if ("".equals(task.interactionName))
+    {
+      task.interactionName = null;
+    }
+    
+    if (!tokenMatcher.find())
+    {
+      throw new IllegalArgumentException("could not parse task specification");
+    }
+    
+    firstToken = tokenMatcher.group();
+    
+    if (!"}".equals(firstToken))
+    {
+      ArrayList<TaskSpec> children = new ArrayList<TaskSpec>();
+    
+      TaskSpec child = null;
+    
+      do
+      {
+        child = parseTask(tokenMatcher);
+        
+        if (child != null)
+        {
+          children.add(child);
+          
+          if (!tokenMatcher.find())
+          {
+            throw new IllegalArgumentException("could not parse task specification");
+          }
+          
+          firstToken = tokenMatcher.group();
+          
+          if ("}".equals(firstToken))
+          {
+            break;
+          }
+        }
+        
+      }
+      while (child != null);
+      
+      task.children = children.toArray(new TaskSpec[children.size()]);
+    }
+    
+    return task;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * @param task
+   * @param taskMapCopy
+   */
+  //-----------------------------------------------------------------------------------------------
+  private void assertTaskAndChildrenInMapAndRemove(TaskSpec                   task,
+                                                   Map<TaskTreeNode, Integer> taskMap)
+  {
+    for (Map.Entry<TaskTreeNode, Integer> entry : taskMap.entrySet())
+    {
+      if (taskSpecEqualsTask(task, entry.getKey()))
+      {
+        if (task.children != null)
+        {
+          for (TaskSpec child : task.children)
+          {
+            assertTaskAndChildrenInMapAndRemove(child, taskMap);
+          }
+        }
+        
+        int count = taskMap.get(entry.getKey());
+        if (count == 1)
+        {
+          taskMap.remove(entry.getKey());
+        }
+        else
+        {
+          taskMap.put(entry.getKey(), count - 1);
+        }
+        return;
+      }
+    }
+    
+    fail("expected task " + task.type + " " + task.interactionName + " not included in task map");
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  private boolean taskSpecEqualsTask(TaskSpec taskSpec, TaskTreeNode task)
+  {
+    if (mDoTrace)
+    {
+      System.err.println("comparing " + taskSpec.interactionName + " with");
+      dumpTask(task, 0, "");
+    }
+    
+    if (("Interaction".equals(taskSpec.type) && (!(task instanceof InteractionTask))) ||
+        ("TextInputInteraction".equals(taskSpec.type) &&
+            (!(task instanceof TextInputInteractionTask))) ||
+        ("Sequence".equals(taskSpec.type) && (!(task instanceof Sequence))) ||
+        ("Selection".equals(taskSpec.type) && (!(task instanceof Selection))) ||
+        ("Iteration".equals(taskSpec.type) && (!(task instanceof Iteration))))
+    {
+      if (mDoTrace)
+      {
+        System.err.println("task types do not match: " + taskSpec.type + " != " +
+                           task.getClass().getSimpleName() + "\n");
+      }
+      return false;
+    }
+    else if (!"Interaction".equals(taskSpec.type) &&
+             !"TextInputInteraction".equals(taskSpec.type) &&
+             !"Sequence".equals(taskSpec.type) &&
+             !"Selection".equals(taskSpec.type) &&
+             !"Iteration".equals(taskSpec.type))
+    {
+      fail("unknown task type " + taskSpec.type + " --> please extend test case");
+    }
+    
+    if ("TextInputInteraction".equals(taskSpec.type))
+    {
+      if (!"".equals(taskSpec.additionalInfo) &&
+          !(taskSpec.additionalInfo.equals(((TextInputInteractionTask) task).getEnteredText())))
+      {
+        if (mDoTrace)
+        {
+          System.err.println
+            ("expected text \"" + taskSpec.additionalInfo + "\" is not equal to the text " +
+             "provided by the task \"" + ((TextInputInteractionTask) task).getEnteredText() +
+             "\"\n");
+        }
+        return false;
+      }
+    }
+    else if ((task instanceof InteractionTask) &&
+        (((InteractionTask) task).getInteraction() != null) &&
+        (!taskSpec.interactionName.equals(((InteractionTask) task).getInteraction().getName())))
+    {
+      // simple interaction names do not match. But what about the interaction name in combination
+      // with the additional info
+      String complexInteractionName = taskSpec.interactionName +
+        (!"".equals(taskSpec.additionalInfo) ? " " + taskSpec.additionalInfo : "");
+      
+      if (!complexInteractionName.equals(((InteractionTask) task).getInteraction().getName()))
+      {
+        if (mDoTrace)
+        {
+          System.err.println("interaction names do not match: " + taskSpec.interactionName +
+                             " != " + ((InteractionTask) task).getInteraction().getName() + "\n");
+        }
+        return false;
+      }
+    }
+    
+    if (((taskSpec.children == null) && (task.getChildren().size() > 0)) ||
+        ((taskSpec.children != null) && (taskSpec.children.length != task.getChildren().size())))
+    {
+      if (mDoTrace)
+      {
+        System.err.println("numbers of children do not match: " +
+                           (taskSpec.children == null ? "0" : taskSpec.children.length) + " != " +
+                           (task.getChildren() == null ? "0" : task.getChildren().size()) + "\n");
+      }
+      return false;
+    }
+    
+    Iterator<TaskTreeNode> children = task.getChildren().iterator();
+    if (taskSpec.children != null)
+    {
+      for (TaskSpec child : taskSpec.children)
+      {
+        if (!taskSpecEqualsTask(child, children.next()))
+        {
+          if (mDoTrace)
+          {
+            System.err.println("one of the children does not match\n");
+          }
+          return false;
+        }
+      }
+    }
+        
+    if (!children.hasNext())
+    {
+      if (mDoTrace)
+      {
+        System.err.println("nodes match\n");
+      }
+      return true;
+    }
+    else
+    {
+      if (mDoTrace)
+      {
+        System.err.println("number of children does not match\n");
+      }
+      return false;
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  private void dumpTaskMap(Map<TaskTreeNode, Integer> taskMap)
+  {
+    System.err.println();
+    for (Map.Entry<TaskTreeNode, Integer> entry : taskMap.entrySet())
+    {
+      dumpTask(entry.getKey(), entry.getValue(), "");
+      System.err.println();
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  private void dumpTask(TaskTreeNode task, int count, String indent)
+  {
+    System.err.print(indent);
+    System.err.print(task);
+    System.err.print(" ");
+    System.err.print(task.getDescription());
+    System.err.print(" ");
+    
+    if (count > 0)
+    {
+      System.err.print("(");
+      System.err.print(count);
+      System.err.print(" occurrences)");
+    }
+    
+    System.err.println();
+    
+    if ((task.getChildren() != null) && (task.getChildren().size() > 0))
+    {
+      for (TaskTreeNode child : task.getChildren())
+      {
+        dumpTask(child, 0, indent + "  ");
+      }
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO comment
+   *
+   * @version $Revision: $ $Date: $
+   * @author  2011, last modified by $Author: $
+   */
+  //-----------------------------------------------------------------------------------------------
+  private class TaskSpec
+  {
+    public String type;
+    public String interactionName;
+    public String additionalInfo;
+    public TaskSpec[] children;
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/src/test/java/de/ugoe/cs/quest/tasktrees/testutils/Utilities.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/src/test/java/de/ugoe/cs/quest/tasktrees/testutils/Utilities.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/src/test/java/de/ugoe/cs/quest/tasktrees/testutils/Utilities.java	(revision 540)
@@ -0,0 +1,43 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: TestUtils.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 02.04.2012 $
+// Project   : TaskTreeTestUtils
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.testutils;
+
+import de.ugoe.cs.quest.tasktrees.nodeequality.NodeEqualityRuleManager;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 02.04.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public class Utilities
+{
+  /** */
+  private static final NodeEqualityRuleManager NODE_EQUALITY_RULE_MANAGER =
+    new NodeEqualityRuleManager();
+  
+  static
+  {
+    NODE_EQUALITY_RULE_MANAGER.init();
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  public static NodeEqualityRuleManager getNodeEqualityRuleManagerForTests()
+  {
+    return NODE_EQUALITY_RULE_MANAGER;
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/src/test/java/de/ugoe/cs/quest/tasktrees/treeimpl/TaskTreeImplTest.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/src/test/java/de/ugoe/cs/quest/tasktrees/treeimpl/TaskTreeImplTest.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees-test/src/test/java/de/ugoe/cs/quest/tasktrees/treeimpl/TaskTreeImplTest.java	(revision 540)
@@ -0,0 +1,546 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: TaskTreeImplTest.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 02.04.2012 $
+// Project   : TaskTreeImpl
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.treeimpl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Test;
+
+import de.ugoe.cs.quest.tasktrees.testutils.DummyGUIElement;
+import de.ugoe.cs.quest.tasktrees.testutils.DummyInteraction;
+import de.ugoe.cs.quest.tasktrees.treeifc.InteractionTask;
+import de.ugoe.cs.quest.tasktrees.treeifc.Iteration;
+import de.ugoe.cs.quest.tasktrees.treeifc.NodeInfo;
+import de.ugoe.cs.quest.tasktrees.treeifc.Selection;
+import de.ugoe.cs.quest.tasktrees.treeifc.Sequence;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTree;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeBuilder;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNode;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNodeFactory;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 02.04.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public class TaskTreeImplTest
+{
+  /** */
+  private static final int MAX_TREE_DEPTH = 15;
+  
+  /** */
+  private TaskTreeBuilder mTaskTreeBuilder = new TaskTreeBuilderImpl();
+  
+  /** */
+  private TaskTreeNodeFactory mTaskTreeNodeFactory = new TaskTreeNodeFactoryImpl();
+  
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * @throws Exception 
+   * 
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Test
+  public void testRandomTrees() throws Exception
+  {
+    int noOfTrees = 10;
+    int noOfMaxChildren = 8;
+    int maxDepth = MAX_TREE_DEPTH;
+    
+    for (int i = 0; i < noOfTrees; i++)
+    {
+      System.err.println("iteration " + (i + 1) + ":");
+      System.err.println("  creating tree");
+      Map<TaskTreeNode, NodeInfo> treeInfos = new HashMap<TaskTreeNode, NodeInfo>();
+      TaskTreeNode rootNode = createTree(noOfMaxChildren, maxDepth, treeInfos);
+      System.err.println("  creating task tree");
+      TaskTree taskTree = mTaskTreeNodeFactory.createTaskTree(rootNode);
+      
+      System.err.println("  validating task tree");
+      assertEquals(rootNode, taskTree.getRoot());
+      assertMapsEqual(treeInfos, taskTree.getTaskMap());
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param treeInfos
+   * @param taskMap
+   */
+  //-----------------------------------------------------------------------------------------------
+  private void assertMapsEqual(Map<TaskTreeNode, NodeInfo> map1,
+                               Map<TaskTreeNode, NodeInfo> map2)
+  {
+    try
+    {
+      if (map1 == null)
+      {
+        assertNull(map2);
+        return;
+      }
+      
+      assertEquals(map1.size(), map2.size());
+      
+      for (Map.Entry<TaskTreeNode, NodeInfo> entry : map1.entrySet())
+      {
+        NodeInfo value2 = map2.get(entry.getKey());
+        assertNotNull(value2);
+        assertEquals(entry.getValue().getTask(), value2.getTask());
+        assertEquals(entry.getValue().getNoOfOccurencesInTree(), value2.getNoOfOccurencesInTree());
+      }
+    }
+    catch (AssertionError e)
+    {
+      dumpMap(map1);
+      dumpMap(map2);
+      throw e;
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param map2
+   */
+  //-----------------------------------------------------------------------------------------------
+  private void dumpMap(Map<TaskTreeNode, NodeInfo> map)
+  {
+    System.err.println();
+    
+    if (map == null)
+    {
+      System.err.println("map is null");
+    }
+    else
+    {
+      System.err.println("map:");
+      for (Map.Entry<TaskTreeNode, NodeInfo> entry : map.entrySet())
+      {
+        System.err.print("  ");
+        System.err.print(entry.getKey());
+        for (int i = entry.getKey().toString().length(); i < 49; i++)
+        {
+          System.err.print(" ");
+        }
+        System.err.print(" : ");
+        System.err.println(entry.getValue());
+      }
+    }
+    
+    System.err.println();
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param noOfMaxChildren
+   * @param maxDepth
+   * @param treeInfos
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  private TaskTreeNode createTree(int                         maxNoOfChildren,
+                                  int                         maxDepth,
+                                  Map<TaskTreeNode, NodeInfo> treeInfos)
+    throws Exception
+  {
+    /*for (int i = 0; i < (MAX_TREE_DEPTH + 1 - maxDepth); i++)
+    {
+      System.err.print("  ");
+    }*/
+    
+    TaskTreeNode tree;
+    
+    // integrating the maximum depth here assures, that either something between 0 and 8 will
+    // be the type, or if the max depth decreases near 0 only interaction tasks will be created
+    // to finish the tree creation
+    int type = (int) (Math.random() * (Math.min(8, maxDepth)));
+    
+    switch (type)
+    {
+      case 0:
+      {
+        //System.err.print("creating new interaction task ");
+        tree = createNewInteractionTask(treeInfos);
+        break;
+      }
+      case 1:
+      {
+        //System.err.print("reusing interaction task ");
+        tree = reuseInteractionTask(treeInfos);
+        break;
+      }
+      case 2:
+      {
+        //System.err.println("creating new sequence {");
+        tree = createNewSequence(maxNoOfChildren, maxDepth, treeInfos);
+        break;
+      }
+      case 3:
+      {
+        //System.err.println("reusing sequence {");
+        tree = reuseSequence(maxNoOfChildren, maxDepth, treeInfos);
+        break;
+      }
+      case 4:
+      {
+        //System.err.println("creating new selection {");
+        tree = createNewSelection(maxNoOfChildren, maxDepth, treeInfos);
+        break;
+      }
+      case 5:
+      {
+        //System.err.println("reusing selection {");
+        tree = reuseSelection(maxNoOfChildren, maxDepth, treeInfos);
+        break;
+      }
+      case 6:
+      {
+        //System.err.println("creating new iteration {");
+        tree = createNewIteration(maxNoOfChildren, maxDepth, treeInfos);
+        break;
+      }
+      case 7:
+      {
+        //System.err.println("reusing iteration {");
+        tree = reuseIteration(maxNoOfChildren, maxDepth, treeInfos);
+        break;
+      }
+      default:
+      {
+        //System.err.print("creating new interaction task per default ");
+        tree = createNewInteractionTask(treeInfos);
+      }
+    }
+    
+    /*
+    if (!(tree instanceof InteractionTask))
+    {
+      for (int i = 0; i < (MAX_TREE_DEPTH + 1 - maxDepth); i++)
+      {
+        System.err.print("  ");
+      }
+      
+      System.err.print("} ");
+    }
+    
+    System.err.println(tree);*/
+    
+    return tree;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param treeInfos
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  private InteractionTask createNewInteractionTask(Map<TaskTreeNode, NodeInfo> treeInfos)
+    throws Exception
+  {
+    Thread.sleep(2);
+    long id = System.currentTimeMillis();
+    InteractionTask task = mTaskTreeNodeFactory.createNewInteractionTask
+      (new DummyGUIElement("elem" + id), new DummyInteraction("interaction" + id, 1));
+    
+    treeInfos.put(task, new NodeInfoImpl(task));
+    
+    return task;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param treeInfos
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  private InteractionTask reuseInteractionTask(Map<TaskTreeNode, NodeInfo> treeInfos)
+    throws Exception
+  {
+    int noOfInteractionTasks = 0;
+    
+    for (Map.Entry<TaskTreeNode, NodeInfo> entry : treeInfos.entrySet())
+    {
+      if (entry.getKey() instanceof InteractionTask)
+      {
+        noOfInteractionTasks++;
+      }
+    }
+    
+    if (noOfInteractionTasks > 0)
+    {
+      noOfInteractionTasks = (int) (Math.random() * noOfInteractionTasks);
+      
+      for (Map.Entry<TaskTreeNode, NodeInfo> entry : treeInfos.entrySet())
+      {
+        if (entry.getKey() instanceof InteractionTask)
+        {
+          if (--noOfInteractionTasks <= 0)
+          {
+            return (InteractionTask) entry.getKey();
+          }
+        }
+      }
+    }
+    else
+    {
+      return createNewInteractionTask(treeInfos); 
+    }
+    
+    throw new RuntimeException("this is an implementation error");
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param treeInfos
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  private Sequence createNewSequence(int                         maxNoOfChildren,
+                                     int                         maxDepth,
+                                     Map<TaskTreeNode, NodeInfo> treeInfos)
+    throws Exception
+  {
+    Sequence sequence = mTaskTreeNodeFactory.createNewSequence();
+    
+    int noOfChildren = (int) (Math.random() * maxNoOfChildren);
+    
+    for (int i = 0; i < noOfChildren; i++)
+    {
+      TaskTreeNode child = createTree(maxNoOfChildren, maxDepth - 1, treeInfos);
+      
+      // through first removing an existing parent it is assured, that a parent is recorded
+      // only once. This is needed, because parent may be reused in a tree as well, but we always
+      // iterate the whole tree
+      ((NodeInfoImpl) treeInfos.get(child)).removeParent(sequence);
+      ((NodeInfoImpl) treeInfos.get(child)).addParent(sequence);
+      mTaskTreeBuilder.addChild(sequence, child);
+    }
+    
+    treeInfos.put(sequence, new NodeInfoImpl(sequence));
+    return sequence;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param treeInfos
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  private Sequence reuseSequence(int                         maxNoOfChildren,
+                                 int                         maxDepth,
+                                 Map<TaskTreeNode, NodeInfo> treeInfos)
+    throws Exception
+  {
+    int noOfSequences = 0;
+    
+    for (Map.Entry<TaskTreeNode, NodeInfo> entry : treeInfos.entrySet())
+    {
+      if (entry.getKey() instanceof Sequence)
+      {
+        noOfSequences++;
+      }
+    }
+    
+    if (noOfSequences > 0)
+    {
+      noOfSequences = (int) (Math.random() * noOfSequences);
+      
+      for (Map.Entry<TaskTreeNode, NodeInfo> entry : treeInfos.entrySet())
+      {
+        if (entry.getKey() instanceof Sequence)
+        {
+          if (--noOfSequences <= 0)
+          {
+            return (Sequence) entry.getKey();
+          }
+        }
+      }
+    }
+    else
+    {
+      return createNewSequence(maxNoOfChildren, maxDepth, treeInfos); 
+    }
+    
+    throw new RuntimeException("this is an implementation error");
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param treeInfos
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  private Selection createNewSelection(int                         maxNoOfChildren,
+                                       int                         maxDepth,
+                                       Map<TaskTreeNode, NodeInfo> treeInfos)
+    throws Exception
+  {
+    Selection selection = mTaskTreeNodeFactory.createNewSelection();
+    
+    int noOfChildren = (int) (Math.random() * maxNoOfChildren);
+    
+    for (int i = 0; i < noOfChildren; i++)
+    {
+      TaskTreeNode child = createTree(maxNoOfChildren, maxDepth - 1, treeInfos);
+      
+      // through first removing an existing parent it is assured, that a parent is recorded
+      // only once. This is needed, because parent may be reused in a tree as well, but we always
+      // iterate the whole tree
+      ((NodeInfoImpl) treeInfos.get(child)).removeParent(selection);
+      ((NodeInfoImpl) treeInfos.get(child)).addParent(selection);
+      mTaskTreeBuilder.addChild(selection, child);
+    }
+    
+    treeInfos.put(selection, new NodeInfoImpl(selection));
+    return selection;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param treeInfos
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  private Selection reuseSelection(int                         maxNoOfChildren,
+                                   int                         maxDepth,
+                                   Map<TaskTreeNode, NodeInfo> treeInfos)
+    throws Exception
+  {
+    int noOfSelections = 0;
+    
+    for (Map.Entry<TaskTreeNode, NodeInfo> entry : treeInfos.entrySet())
+    {
+      if (entry.getKey() instanceof Selection)
+      {
+        noOfSelections++;
+      }
+    }
+    
+    if (noOfSelections > 0)
+    {
+      noOfSelections = (int) (Math.random() * noOfSelections);
+      
+      for (Map.Entry<TaskTreeNode, NodeInfo> entry : treeInfos.entrySet())
+      {
+        if (entry.getKey() instanceof Selection)
+        {
+          if (--noOfSelections <= 0)
+          {
+            return (Selection) entry.getKey();
+          }
+        }
+      }
+    }
+    else
+    {
+      return createNewSelection(maxNoOfChildren, maxDepth, treeInfos); 
+    }
+    
+    throw new RuntimeException("this is an implementation error");
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param treeInfos
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  private Iteration createNewIteration(int                         maxNoOfChildren,
+                                       int                         maxDepth,
+                                       Map<TaskTreeNode, NodeInfo> treeInfos)
+    throws Exception
+  {
+    Iteration iteration = mTaskTreeNodeFactory.createNewIteration();
+    
+    TaskTreeNode child = createTree(maxNoOfChildren, maxDepth - 1, treeInfos);
+    
+    // through first removing an existing parent it is assured, that a parent is recorded
+    // only once. This is needed, because parent may be reused in a tree as well, but we always
+    // iterate the whole tree
+    ((NodeInfoImpl) treeInfos.get(child)).removeParent(iteration);
+    ((NodeInfoImpl) treeInfos.get(child)).addParent(iteration);
+    mTaskTreeBuilder.setChild(iteration, child);
+    
+    treeInfos.put(iteration, new NodeInfoImpl(iteration));
+    return iteration;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param treeInfos
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  private Iteration reuseIteration(int                         maxNoOfChildren,
+                                   int                         maxDepth,
+                                   Map<TaskTreeNode, NodeInfo> treeInfos)
+    throws Exception
+  {
+    int noOfIterations = 0;
+    
+    for (Map.Entry<TaskTreeNode, NodeInfo> entry : treeInfos.entrySet())
+    {
+      if (entry.getKey() instanceof Iteration)
+      {
+        noOfIterations++;
+      }
+    }
+    
+    if (noOfIterations > 0)
+    {
+      noOfIterations = (int) (Math.random() * noOfIterations);
+      
+      for (Map.Entry<TaskTreeNode, NodeInfo> entry : treeInfos.entrySet())
+      {
+        if (entry.getKey() instanceof Iteration)
+        {
+          if (--noOfIterations <= 0)
+          {
+            return (Iteration) entry.getKey();
+          }
+        }
+      }
+    }
+    else
+    {
+      return createNewIteration(maxNoOfChildren, maxDepth, treeInfos); 
+    }
+    
+    throw new RuntimeException("this is an implementation error");
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/.classpath
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/.classpath	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/.classpath	(revision 540)
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/classes" path="src/main/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/.project
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/.project	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/.project	(revision 540)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>quest-core-tasktrees</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/.settings/org.eclipse.jdt.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/.settings/org.eclipse.jdt.core.prefs	(revision 540)
@@ -0,0 +1,5 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.6
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/.settings/org.eclipse.m2e.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/.settings/org.eclipse.m2e.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/.settings/org.eclipse.m2e.core.prefs	(revision 540)
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/pom.xml
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/pom.xml	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/pom.xml	(revision 540)
@@ -0,0 +1,35 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>de.ugoe.cs.quest</groupId>
+  <artifactId>quest-core-tasktrees</artifactId>
+  <version>0.0.1-SNAPSHOT</version>
+  <name>quest-core-tasktrees</name>
+  <scm>
+    <url>https://quest.informatik.uni-goettingen.de/svn/quest/trunk/quest-core-tasktrees</url>
+  </scm>
+  <dependencies>
+    <dependency>
+      <groupId>de.ugoe.cs.quest</groupId>
+      <artifactId>quest-core-events-patrick</artifactId>
+      <version>0.0.1-SNAPSHOT</version>
+    </dependency>
+  </dependencies>
+  <distributionManagement>
+    <snapshotRepository>
+      <id>quest-snapshots</id>
+      <url>https://trex.informatik.uni-goettingen.de/nexus/content/repositories/quest-snapshots</url>
+    </snapshotRepository>
+  </distributionManagement>
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>2.3.2</version>
+        <configuration>
+          <source>1.6</source>
+          <target>1.6</target>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/manager/ComponentManager.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/manager/ComponentManager.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/manager/ComponentManager.java	(revision 540)
@@ -0,0 +1,138 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: ComponentManager.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 12.02.2012 $
+// Project   : TaskTreeCreator
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.manager;
+
+import de.ugoe.cs.quest.tasktrees.nodeequality.NodeEqualityRuleManager;
+import de.ugoe.cs.quest.tasktrees.temporalrelation.TemporalRelationshipRuleManager;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeBuilder;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNodeFactory;
+import de.ugoe.cs.quest.tasktrees.treeimpl.TaskTreeBuilderImpl;
+import de.ugoe.cs.quest.tasktrees.treeimpl.TaskTreeNodeFactoryImpl;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 12.02.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+// -------------------------------------------------------------------------------------------------
+public class ComponentManager
+{
+  /** */
+  private static ComponentManager sInstance;
+
+  /** */
+  private TemporalRelationshipRuleManager mTemporalRelationshipRuleManager;
+  
+  /** */
+  private NodeEqualityRuleManager mNodeEqualityRuleManager;
+
+  /** */
+  private TaskTreeBuilder mTaskTreeBuilder;
+
+  /** */
+  private TaskTreeNodeFactory mTaskTreeNodeFactory;
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  public static TemporalRelationshipRuleManager getTemporalRelationshipRuleManager()
+  {
+    return getInstance().mTemporalRelationshipRuleManager;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  public static NodeEqualityRuleManager getNodeEqualityRuleManager()
+  {
+    return getInstance().mNodeEqualityRuleManager;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  public static TaskTreeBuilder getDefaultTaskTreeBuilder()
+  {
+    return getInstance().mTaskTreeBuilder;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  public static TaskTreeNodeFactory getDefaultTaskTreeNodeFactory()
+  {
+    return getInstance().mTaskTreeNodeFactory;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  public static synchronized void clearInstance()
+  {
+    sInstance = null;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  private static synchronized ComponentManager getInstance()
+  {
+    if (sInstance == null)
+    {
+      sInstance = new ComponentManager();
+      sInstance.init();
+    }
+    return sInstance;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  private void init()
+  {
+    mNodeEqualityRuleManager = new NodeEqualityRuleManager();
+    mNodeEqualityRuleManager.init();
+    
+    mTemporalRelationshipRuleManager =
+      new TemporalRelationshipRuleManager(mNodeEqualityRuleManager);
+    mTemporalRelationshipRuleManager.init();
+
+    mTaskTreeBuilder = new TaskTreeBuilderImpl();
+    mTaskTreeNodeFactory = new TaskTreeNodeFactoryImpl();
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/manager/TaskTreeManager.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/manager/TaskTreeManager.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/manager/TaskTreeManager.java	(revision 540)
@@ -0,0 +1,269 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: TaskTreeManager.java,v $
+// Version   : $Revision: 0.0 $  $Author: Patrick $  $Date: 06.11.2011 10:14:21 $
+// Project   : TaskTreePerformanceTest
+// Creation  : 2011 by Patrick
+// Copyright : Patrick Harms, 2011
+//-------------------------------------------------------------------------------------------------
+
+package de.ugoe.cs.quest.tasktrees.manager;
+
+import java.util.Observable;
+import java.util.Observer;
+import java.util.logging.Logger;
+
+import de.ugoe.cs.quest.eventcore.guimodel.GUIElement;
+import de.ugoe.cs.quest.eventcore.userinteraction.InteractionEvent;
+import de.ugoe.cs.quest.eventcore.userinteraction.KeyInteraction;
+import de.ugoe.cs.quest.eventcore.userinteraction.KeyboardFocusChange;
+import de.ugoe.cs.quest.eventcore.userinteraction.UserInteractionProvider;
+import de.ugoe.cs.quest.tasktrees.treeifc.InteractionTask;
+import de.ugoe.cs.quest.tasktrees.treeifc.Sequence;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTree;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeBuilder;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNode;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNodeFactory;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ *
+ * @version $Revision: $ $Date: $
+ * @author  2011, last modified by $Author: $
+ */
+//-------------------------------------------------------------------------------------------------
+public class TaskTreeManager implements Observer
+{
+  /** */
+  private static final int MAX_INTERACTIONS_TILL_RULE_APPLICATION = 100;
+
+  /** */
+  private static Logger LOG = Logger.getLogger(TaskTreeManager.class.getName());
+  
+  /** */
+  private TaskTreeBuilder mTaskTreeBuilder = ComponentManager.getDefaultTaskTreeBuilder();
+  
+  /** */
+  private TaskTreeNodeFactory mTaskTreeNodeFactory =
+    ComponentManager.getDefaultTaskTreeNodeFactory();
+  
+  /** */
+  private int mInteractionsTillRuleApplication = MAX_INTERACTIONS_TILL_RULE_APPLICATION;
+  
+  /** */
+  private Sequence mRootSequence;
+  
+  /** */
+  private GUIElement mCurrentKeyboardFocusGUIElement;
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  public TaskTreeManager()
+  {
+    mRootSequence = mTaskTreeNodeFactory.createNewSequence();
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see java.util.Observer#update(java.util.Observable, java.lang.Object)
+   */
+  //-----------------------------------------------------------------------------------------------
+  public void update(Observable observable, Object event)
+  {
+    if ((observable instanceof UserInteractionProvider) &&
+        (event instanceof InteractionEvent))
+    {
+      handleNewInteractionEvent((InteractionEvent) event);
+    }
+    else
+    {
+      LOG.warning("could not handle notification of " + observable + " regarding " + event);
+    }
+  }
+  
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  public void handleNewInteractionEvent(InteractionEvent event)
+  {
+    if (event.getInteraction() instanceof KeyInteraction)
+    {
+      if (mCurrentKeyboardFocusGUIElement == null)
+      {
+        mCurrentKeyboardFocusGUIElement = event.getGUIElement();
+      }
+      
+      addInteractionTask(mTaskTreeNodeFactory.createNewInteractionTask
+                           (mCurrentKeyboardFocusGUIElement, event.getInteraction()));
+    }
+    else
+    {
+      addInteractionTask(mTaskTreeNodeFactory.createNewInteractionTask
+                           (event.getGUIElement(), event.getInteraction()));
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  public synchronized TaskTree getTaskTree()
+  {
+    LOG.info("applying rules temporal relationship generation rules");
+    
+    Sequence rootSequence = mRootSequence.clone();
+    ComponentManager.getTemporalRelationshipRuleManager().applyRules
+      (rootSequence, mTaskTreeBuilder, mTaskTreeNodeFactory, true);
+
+    return mTaskTreeNodeFactory.createTaskTree(rootSequence);
+  }
+  
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * @param task
+   */
+  //-----------------------------------------------------------------------------------------------
+  private synchronized void addInteractionTask(InteractionTask task)
+  {
+    handleInteractionTask(task);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * adds the task to the current or the new sequence. The decision depends on the type
+   * of task. If the task finishes the current sequence, the sequence is marked as finished
+   * If the task does not start a new sequence, it is added to the current sequence, before it
+   * is marked s finished. Otherwise it is added to a new sequence.
+   */
+  //-----------------------------------------------------------------------------------------------
+  private void handleInteractionTask(InteractionTask interactionTask)
+  {
+    if (interactionTask.getInteraction() instanceof KeyboardFocusChange)
+    {
+      mCurrentKeyboardFocusGUIElement = interactionTask.getGUIElement();
+    }
+    else
+    {
+      LOG.info("handling interaction task \"" + interactionTask + "\"");
+      addTaskToSequence(interactionTask, mCurrentKeyboardFocusGUIElement);
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param interactionTask
+   */
+  //-----------------------------------------------------------------------------------------------
+  /*private boolean handleAndCorrectFocusChanges(InteractionTask interactionTask)
+  {
+    GUIElement newGUIElement = interactionTask.getGUIElement();
+    
+    // find the identical parent element
+    GUIElement identicalParentGUIElement = null;
+    
+    while ((identicalParentGUIElement == null) && (newGUIElement != null))
+    {
+      GUIElement currentGUIElement = mCurrentGUIElement;
+      
+      while ((identicalParentGUIElement == null) && (currentGUIElement != null))
+      {
+        if (newGUIElement.equals(currentGUIElement))
+        {
+          identicalParentGUIElement = newGUIElement;
+        }
+        else
+        {
+          currentGUIElement = currentGUIElement.getParent();
+        }
+      }
+      
+      newGUIElement = newGUIElement.getParent();
+    }
+    
+    // now create focus lost interactions for each GUI element, that is not common with the
+    // hierarchy of the new GUI element
+    GUIElement currentGUIElement = mCurrentGUIElement;
+    
+    List<InteractionTask> tasksToBeAdded = new ArrayList<InteractionTask>();
+    
+    while ((currentGUIElement != null) &&
+           ((identicalParentGUIElement == null) ||
+            (!currentGUIElement.equals(identicalParentGUIElement))))
+    {
+      tasksToBeAdded.add
+        (mTaskTreeNodeFactory.createNewInteractionTask(currentGUIElement, new FocusLost()));
+      currentGUIElement = currentGUIElement.getParent();
+    }
+    
+    // now create focus received interactions for each GUI element, that is not common with
+    // with the old one. Ensure, that if the current interaction is a focus reception, that
+    // it is used instead of a generated one
+    newGUIElement = interactionTask.getGUIElement();
+    
+    int index = tasksToBeAdded.size();
+    while ((newGUIElement != null) &&
+           ((identicalParentGUIElement == null) ||
+            (!newGUIElement.equals(identicalParentGUIElement))))
+    {
+      tasksToBeAdded.add(index, mTaskTreeNodeFactory.createNewInteractionTask
+                           (newGUIElement, new FocusReceived()));
+      newGUIElement = newGUIElement.getParent();
+    }
+    
+    // this part ensures, that the original focus reception, if any, is preserved as is.
+    boolean taskAlreadyHandled = false;
+    if (interactionTask.getInteraction() instanceof FocusReceived)
+    {
+      if (tasksToBeAdded.size() > 0)
+      {
+        tasksToBeAdded.set(tasksToBeAdded.size() - 1, interactionTask);
+      }
+      //else
+      //{
+        // in this case, we already have focus on the element to which the focus shall be changed.
+        // therefore, we discard the new focus change on the same element.
+      //}
+      
+      taskAlreadyHandled = true;
+    }
+    
+    // now that all tasks are determined, add them to the sequence
+    for (InteractionTask task : tasksToBeAdded)
+    {
+      addTaskToSequence(task);
+    }
+    
+    mCurrentGUIElement = interactionTask.getGUIElement();
+    
+    return taskAlreadyHandled;
+  }*/
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  private void addTaskToSequence(TaskTreeNode task, GUIElement currentKeyboardFocusGUIElement)
+  {
+    mTaskTreeBuilder.addChild(mRootSequence, task);
+    
+    if (--mInteractionsTillRuleApplication == 0)
+    {
+      mInteractionsTillRuleApplication = MAX_INTERACTIONS_TILL_RULE_APPLICATION;
+      
+      LOG.info("applying rules temporal relationship generation rules");
+      ComponentManager.getTemporalRelationshipRuleManager().applyRules
+        (mRootSequence, mTaskTreeBuilder, mTaskTreeNodeFactory, false);
+    }
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/nodeequality/IterationComparisonRule.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/nodeequality/IterationComparisonRule.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/nodeequality/IterationComparisonRule.java	(revision 540)
@@ -0,0 +1,133 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: NodeIdentityRule.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 19.02.2012 $
+// Project   : TaskTreeCreator
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.nodeequality;
+
+import de.ugoe.cs.quest.tasktrees.treeifc.Iteration;
+import de.ugoe.cs.quest.tasktrees.treeifc.Selection;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNode;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 19.02.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public class IterationComparisonRule implements NodeComparisonRule
+{
+  /** */
+  private NodeEqualityRuleManager mRuleManager;
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  IterationComparisonRule(NodeEqualityRuleManager ruleManager)
+  {
+    super();
+    mRuleManager = ruleManager;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.ugoe.cs.tasktree.nodeequality.NodeEqualityRule#apply(TaskTreeNode, TaskTreeNode)
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public NodeEquality compare(TaskTreeNode node1, TaskTreeNode node2)
+  {
+    if ((!(node1 instanceof Iteration)) || (!(node2 instanceof Iteration)))
+    {
+      return null;
+    }
+    
+    // if both iterations do not have children, they are equal although this doesn't make sense
+    if ((node1.getChildren().size() == 0) && (node2.getChildren().size() == 0))
+    {
+      return new NodesIdentical();
+    }
+    
+    TaskTreeNode child1 = node1.getChildren().get(0);
+    TaskTreeNode child2 = node2.getChildren().get(0);
+    
+    // iterations may have 3 different structures.
+    //   1. they have one child, which is the iterated one
+    //   2. they have a sequence of children, which is iterated
+    //   3. they have a selection of different iterated variants (usually the variants are
+    //      semantically equal)
+    //
+    // the permutations of the three variants in combination must be checked
+    
+    // check if both nodes are the same variants of iterations and if their children are equal.
+    // This condition matches, if both iterations are the same variants of iteration. I.e. three
+    // combinations of the permutation are handled herewith.
+    NodeEquality nodeEquality = mRuleManager.applyRules(child1, child2);
+      
+    if (nodeEquality.getStructuralEquality() || nodeEquality.getSemanticalEquality())
+    {
+      return nodeEquality;
+    }
+    
+    // compare one iteration with a single node as a child and another one with a selection of
+    // semantically equal nodes
+    if (selectionChildrenSemanticallyEqualNode(child1, child2))
+    {
+      return new NodesSemanticallyEqual();
+    }
+
+    // all other combinations (i.e. sequence with single child and sequence with selection)
+    // can not match
+    return null;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param taskTreeNode
+   * @param taskTreeNode2
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  private boolean selectionChildrenSemanticallyEqualNode(TaskTreeNode taskTreeNode,
+                                                         TaskTreeNode taskTreeNode2)
+  {
+    Selection selection = null;
+    TaskTreeNode node = null;
+    if (taskTreeNode instanceof Selection)
+    {
+      selection = (Selection) taskTreeNode;
+      node = taskTreeNode2;
+    }
+    else if (taskTreeNode2 instanceof Selection)
+    {
+      selection = (Selection) taskTreeNode2;
+      node = taskTreeNode;
+    }
+    else
+    {
+      return false;
+    }
+    
+    for (TaskTreeNode child : selection.getChildren())
+    {
+      NodeEquality nodeEquality = mRuleManager.applyRules(node, child);
+          
+      if (!nodeEquality.getStructuralEquality() && !nodeEquality.getSemanticalEquality())
+      {
+        return false;
+      }
+    }
+    
+    return true;
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/nodeequality/NodeComparisonRule.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/nodeequality/NodeComparisonRule.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/nodeequality/NodeComparisonRule.java	(revision 540)
@@ -0,0 +1,32 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: EqualityRule.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 19.02.2012 $
+// Project   : TaskTreeCreator
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.nodeequality;
+
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNode;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 19.02.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public interface NodeComparisonRule
+{
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * compares two nodes with each other. The result of the method is either a node equality or
+   * null. If it is null, it means, that the rule is not able to correctly compare the two
+   * given nodes
+   */
+  //-----------------------------------------------------------------------------------------------
+  public NodeEquality compare(TaskTreeNode node1, TaskTreeNode node2);
+  
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/nodeequality/NodeEquality.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/nodeequality/NodeEquality.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/nodeequality/NodeEquality.java	(revision 540)
@@ -0,0 +1,39 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: NodeEquality.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 19.02.2012 $
+// Project   : TaskTreeCreator
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.nodeequality;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 19.02.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public interface NodeEquality
+{
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  public boolean getStructuralEquality();
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  public boolean getSemanticalEquality();
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/nodeequality/NodeEqualityRuleManager.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/nodeequality/NodeEqualityRuleManager.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/nodeequality/NodeEqualityRuleManager.java	(revision 540)
@@ -0,0 +1,77 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: NodeEqualityRuleManager.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 19.02.2012 $
+// Project   : TaskTreeCreator
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.nodeequality;
+
+import java.util.ArrayList;
+import java.util.List;
+//import java.util.logging.Logger;
+
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNode;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 19.02.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public class NodeEqualityRuleManager
+{
+
+  /** */
+  //private static Logger LOG = Logger.getLogger(NodeEqualityRuleManager.class.getName());
+
+  /** */
+  private List<NodeComparisonRule> mRuleIndex = new ArrayList<NodeComparisonRule>();
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  public void init()
+  {
+    mRuleIndex.add(new NodeIdentityRule());
+    mRuleIndex.add(new IterationComparisonRule(this));
+    mRuleIndex.add(new SequenceComparisonRule(this));
+    mRuleIndex.add(new SelectionComparisonRule(this));
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param node1
+   * @param node2
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  public NodeEquality applyRules(TaskTreeNode node1, TaskTreeNode node2)
+  {
+    //LOG.info("checking for equality of " + node1 + " and " + node2);
+    NodeEquality nodeEquality = null;
+      
+    for (NodeComparisonRule rule : mRuleIndex)
+    {
+      nodeEquality = rule.compare(node1, node2);
+      
+      if (nodeEquality != null)
+      {
+        //LOG.warning("used rule " + rule + " for equality check");
+        return nodeEquality;
+      }
+    }
+    
+    //LOG.warning("no rule could be applied --> handling nodes as unequal");
+    
+    return new NodesUnequal();
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/nodeequality/NodeIdentityRule.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/nodeequality/NodeIdentityRule.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/nodeequality/NodeIdentityRule.java	(revision 540)
@@ -0,0 +1,45 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: NodeIdentityRule.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 19.02.2012 $
+// Project   : TaskTreeCreator
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.nodeequality;
+
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNode;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 19.02.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public class NodeIdentityRule implements NodeComparisonRule
+{
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.ugoe.cs.tasktree.nodeequality.NodeEqualityRule#apply(TaskTreeNode, TaskTreeNode)
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public NodeEquality compare(TaskTreeNode node1, TaskTreeNode node2)
+  {
+    if (node1 == node2)
+    {
+      return new NodesIdentical();
+    }
+    else if ((node1 != null) && (node1.equals(node2)))
+    {
+      return new NodesEqual();
+    }
+    else
+    {
+      return null;
+    }
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/nodeequality/NodesEqual.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/nodeequality/NodesEqual.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/nodeequality/NodesEqual.java	(revision 540)
@@ -0,0 +1,43 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: NodesEqual.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 19.02.2012 $
+// Project   : TaskTreeCreator
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.nodeequality;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 19.02.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public class NodesEqual implements NodeEquality
+{
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.ugoe.cs.tasktree.nodeequality.NodeEquality#getStructuralEquality()
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public boolean getStructuralEquality()
+  {
+    return true;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.ugoe.cs.tasktree.nodeequality.NodeEquality#getSemanticalEquality()
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public boolean getSemanticalEquality()
+  {
+    return true;
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/nodeequality/NodesIdentical.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/nodeequality/NodesIdentical.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/nodeequality/NodesIdentical.java	(revision 540)
@@ -0,0 +1,43 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: NodesIdentical.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 19.02.2012 $
+// Project   : TaskTreeCreator
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.nodeequality;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 19.02.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public class NodesIdentical implements NodeEquality
+{
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.ugoe.cs.tasktree.nodeequality.NodeEquality#getStructuralEquality()
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public boolean getStructuralEquality()
+  {
+    return true;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.ugoe.cs.tasktree.nodeequality.NodeEquality#getSemanticalEquality()
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public boolean getSemanticalEquality()
+  {
+    return true;
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/nodeequality/NodesSemanticallyEqual.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/nodeequality/NodesSemanticallyEqual.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/nodeequality/NodesSemanticallyEqual.java	(revision 540)
@@ -0,0 +1,43 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: NodesEqual.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 19.02.2012 $
+// Project   : TaskTreeCreator
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.nodeequality;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 19.02.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public class NodesSemanticallyEqual implements NodeEquality
+{
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.ugoe.cs.tasktree.nodeequality.NodeEquality#getStructuralEquality()
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public boolean getStructuralEquality()
+  {
+    return false;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.ugoe.cs.tasktree.nodeequality.NodeEquality#getSemanticalEquality()
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public boolean getSemanticalEquality()
+  {
+    return true;
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/nodeequality/NodesUnequal.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/nodeequality/NodesUnequal.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/nodeequality/NodesUnequal.java	(revision 540)
@@ -0,0 +1,43 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: NodeUnequality.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 19.02.2012 $
+// Project   : TaskTreeCreator
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.nodeequality;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 19.02.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public class NodesUnequal implements NodeEquality
+{
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.ugoe.cs.tasktree.nodeequality.NodeEquality#getStructuralEquality()
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public boolean getStructuralEquality()
+  {
+    return false;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.ugoe.cs.tasktree.nodeequality.NodeEquality#getSemanticalEquality()
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public boolean getSemanticalEquality()
+  {
+    return false;
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/nodeequality/SelectionComparisonRule.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/nodeequality/SelectionComparisonRule.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/nodeequality/SelectionComparisonRule.java	(revision 540)
@@ -0,0 +1,96 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: NodeIdentityRule.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 19.02.2012 $
+// Project   : TaskTreeCreator
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.nodeequality;
+
+import de.ugoe.cs.quest.tasktrees.treeifc.Sequence;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNode;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 19.02.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public class SelectionComparisonRule implements NodeComparisonRule
+{
+
+  /** */
+  private NodeEqualityRuleManager mRuleManager;
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   */
+  SelectionComparisonRule(NodeEqualityRuleManager ruleManager)
+  {
+    super();
+    mRuleManager = ruleManager;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.ugoe.cs.tasktree.nodeequality.NodeEqualityRule#apply(TaskTreeNode, TaskTreeNode)
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public NodeEquality compare(TaskTreeNode node1, TaskTreeNode node2)
+  {
+    if ((!(node1 instanceof Sequence)) || (!(node2 instanceof Sequence)))
+    {
+      return null;
+    }
+    
+    // if both sequences do not have children, they are equal although this doesn't make sense
+    if ((node1.getChildren().size() == 0) && (node2.getChildren().size() == 0))
+    {
+      return new NodesEqual();
+    }
+    
+    // Selections are semantically equal, if they have children, which are all semantically equal.
+    // they are structurally equals, if they have the same number and order of structurally equal
+    // children
+    boolean structurallyEqual =
+      node1.getChildren().size() == node2.getChildren().size();
+    
+    for (int i = 0; i < node1.getChildren().size(); i++)
+    {
+      TaskTreeNode child1 = node1.getChildren().get(i);
+      
+      for (int j = 0; j < node2.getChildren().size(); j++)
+      {
+        TaskTreeNode child2 = node2.getChildren().get(j);
+      
+        NodeEquality nodeEquality = mRuleManager.applyRules(child1, child2);
+        
+        if (!nodeEquality.getSemanticalEquality())
+        {
+          return null;
+        }
+        else if (structurallyEqual && (i == j))
+        {
+          // if we compare two children at the same position and if they are structurally equal
+          // then it can be further expected, that the selections are structurally equal
+          structurallyEqual &= nodeEquality.getStructuralEquality();
+        }
+      }
+    }
+    
+    if (structurallyEqual)
+    {
+      return new NodesEqual();
+    }
+    else
+    {
+      return new NodesSemanticallyEqual();
+    }
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/nodeequality/SequenceComparisonRule.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/nodeequality/SequenceComparisonRule.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/nodeequality/SequenceComparisonRule.java	(revision 540)
@@ -0,0 +1,94 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: NodeIdentityRule.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 19.02.2012 $
+// Project   : TaskTreeCreator
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.nodeequality;
+
+import de.ugoe.cs.quest.tasktrees.treeifc.Sequence;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNode;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 19.02.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public class SequenceComparisonRule implements NodeComparisonRule
+{
+
+
+  /** */
+  private NodeEqualityRuleManager mRuleManager;
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  SequenceComparisonRule(NodeEqualityRuleManager ruleManager)
+  {
+    super();
+    mRuleManager = ruleManager;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.ugoe.cs.tasktree.nodeequality.NodeEqualityRule#apply(TaskTreeNode, TaskTreeNode)
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public NodeEquality compare(TaskTreeNode node1, TaskTreeNode node2)
+  {
+    if ((!(node1 instanceof Sequence)) || (!(node2 instanceof Sequence)))
+    {
+      return null;
+    }
+    
+    // if both sequences do not have children, they are equal although this doesn't make sense
+    if ((node1.getChildren().size() == 0) && (node2.getChildren().size() == 0))
+    {
+      return new NodesEqual();
+    }
+    
+    // Sequences are equal, if they have the same number and order of children. If all the
+    // children match structurally, then the sequences are structurally equal. Otherwise, if
+    // at least one pair of children matches only semantically, then the sequences match only
+    // semantically.
+    if (node1.getChildren().size() != node2.getChildren().size())
+    {
+      return null;
+    }
+    
+    boolean structurallyEqual = true;
+    for (int i = 0; i < node1.getChildren().size(); i++)
+    {
+      TaskTreeNode child1 = node1.getChildren().get(i);
+      TaskTreeNode child2 = node2.getChildren().get(i);
+      
+      NodeEquality nodeEquality = mRuleManager.applyRules(child1, child2);
+      
+      structurallyEqual &= nodeEquality.getStructuralEquality();
+      
+      if (!structurallyEqual && !nodeEquality.getSemanticalEquality())
+      {
+        return null;
+      }
+    }
+    
+    if (structurallyEqual)
+    {
+      return new NodesEqual();
+    }
+    else
+    {
+      return new NodesSemanticallyEqual();
+    }
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/temporalrelation/DefaultGUIElementSequenceDetectionRule.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/temporalrelation/DefaultGUIElementSequenceDetectionRule.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/temporalrelation/DefaultGUIElementSequenceDetectionRule.java	(revision 540)
@@ -0,0 +1,137 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: DefaultSequenceDetectionRule.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 18.03.2012 $
+// Project   : TaskTreeCreator
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.temporalrelation;
+
+import de.ugoe.cs.quest.eventcore.guimodel.GUIElement;
+import de.ugoe.cs.quest.tasktrees.treeifc.InteractionTask;
+import de.ugoe.cs.quest.tasktrees.treeifc.Sequence;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeBuilder;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNode;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNodeFactory;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 18.03.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public class DefaultGUIElementSequenceDetectionRule implements TemporalRelationshipRule
+{
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.ugoe.cs.tasktree.temporalrelation.TemporalRelationshipRule#apply(TaskTreeNode, TaskTreeBuilder, TaskTreeNodeFactory)
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public RuleApplicationResult apply(TaskTreeNode        parent,
+                                     TaskTreeBuilder     builder,
+                                     TaskTreeNodeFactory nodeFactory,
+                                     boolean             finalize)
+  {
+    if (!(parent instanceof Sequence))
+    {
+      return null;
+    }
+    
+    RuleApplicationResult result = new RuleApplicationResult();
+    
+    GUIElement currentGUIElement = null;
+    int startingIndex = -1;
+    
+    int index = 0;
+    while (index < parent.getChildren().size())
+    {
+      TaskTreeNode child = parent.getChildren().get(index);
+      
+      GUIElement guiElement = determineGUIElement(child);
+      
+      if ((guiElement != null) && (!guiElement.equals(currentGUIElement)))
+      {
+        if (startingIndex < 0)
+        {
+          startingIndex = index;
+          currentGUIElement = guiElement;
+        }
+        else
+        {
+          handleGuiElementSequence(parent, startingIndex, index - 1, builder, nodeFactory, result);
+
+          return result;
+        }
+      }
+      
+      index++;
+    }
+    
+    if (startingIndex > -1)
+    {
+      if (finalize && (startingIndex > 0))
+      {
+        handleGuiElementSequence
+          (parent, startingIndex, parent.getChildren().size() - 1, builder, nodeFactory, result);
+      }
+      else
+      {
+        result.setRuleApplicationStatus(RuleApplicationStatus.RULE_APPLICATION_FEASIBLE);
+      }
+    }
+    
+    return result;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param child
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  private GUIElement determineGUIElement(TaskTreeNode node)
+  {
+    if (node instanceof InteractionTask)
+    {
+      return ((InteractionTask) node).getGUIElement();
+    }
+    else
+    {
+      return null;
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  private void handleGuiElementSequence(TaskTreeNode          parent,
+                                        int                   startIndex,
+                                        int                   endIndex,
+                                        TaskTreeBuilder       builder,
+                                        TaskTreeNodeFactory   nodeFactory,
+                                        RuleApplicationResult result)
+  {
+    Sequence sequence = nodeFactory.createNewSequence();
+    
+    for (int i = startIndex; i <= endIndex; i++)
+    {
+      builder.addChild(sequence, parent.getChildren().get(startIndex));
+      builder.removeChild((Sequence) parent, startIndex);
+    }
+    
+    builder.addChild((Sequence) parent, startIndex, sequence);
+    
+    result.addNewlyCreatedParentNode(sequence);
+    result.setRuleApplicationStatus(RuleApplicationStatus.RULE_APPLICATION_FINISHED);
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/temporalrelation/DefaultIterationDetectionRule.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/temporalrelation/DefaultIterationDetectionRule.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/temporalrelation/DefaultIterationDetectionRule.java	(revision 540)
@@ -0,0 +1,289 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: DefaultIterationDetectionRule.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 19.02.2012 $
+// Project   : TaskTreeCreator
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.temporalrelation;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import de.ugoe.cs.quest.tasktrees.nodeequality.NodeEquality;
+import de.ugoe.cs.quest.tasktrees.nodeequality.NodeEqualityRuleManager;
+import de.ugoe.cs.quest.tasktrees.treeifc.Iteration;
+import de.ugoe.cs.quest.tasktrees.treeifc.Selection;
+import de.ugoe.cs.quest.tasktrees.treeifc.Sequence;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeBuilder;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNode;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNodeFactory;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 19.02.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public class DefaultIterationDetectionRule implements TemporalRelationshipRule
+{
+  /** */
+  private NodeEqualityRuleManager mNodeEqualityRuleManager;
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  DefaultIterationDetectionRule(NodeEqualityRuleManager nodeEqualityRuleManager)
+  {
+    super();
+    mNodeEqualityRuleManager = nodeEqualityRuleManager;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see TemporalRelationshipRule#apply(TaskTreeNode, TaskTreeBuilder, TaskTreeNodeFactory)
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public RuleApplicationResult apply(TaskTreeNode        parent,
+                                     TaskTreeBuilder     treeBuilder,
+                                     TaskTreeNodeFactory nodeFactory,
+                                     boolean             finalize)
+  {
+    if (!(parent instanceof Sequence))
+    {
+      return null;
+    }
+    
+    // parent must already have at least 2 children
+    if ((parent.getChildren() == null) || (parent.getChildren().size() < 2))
+    {
+      return null;
+    }
+    
+    // iterations represent as a list of nodes that splits up in several equal sublists. If
+    // the remaining nodes also start an equal sublist, then the iteration may not be completed
+    // yet. So wait for further interactions to only identify completed iterations.
+    
+    // to find longer iterations first, start with long sequences
+    for (int end = parent.getChildren().size() - 1; end > 0; end--)
+    {
+      for (int start = 0; start < end; start++)
+      {
+        List<TaskTreeNode[]> equalVariants =
+          getEqualSublistVariantsInBoundaries(parent, start, end);
+        
+        if (equalVariants != null)
+        {
+          if (!finalize)
+          {
+            // check, if the iteration may go on. This may be the case, if the detected iteration
+            // finishes with the last child of the parent, or if the remaining children, which were
+            // not identified as part of the iteration, start a further occurrence of the iteration
+            if (end == (parent.getChildren().size() - 1))
+            {
+              RuleApplicationResult result = new RuleApplicationResult();
+              result.setRuleApplicationStatus(RuleApplicationStatus.RULE_APPLICATION_FEASIBLE);
+              return result;
+            }
+            
+            boolean allNodesEqual = true;
+            for (int i = 0; ((allNodesEqual) && (i < equalVariants.get(0).length)); i++)
+            {
+              if ((end + i + 1) >= parent.getChildren().size())
+              {
+                break;
+              }
+              
+              NodeEquality nodeEquality = mNodeEqualityRuleManager.applyRules
+                (equalVariants.get(0)[i], parent.getChildren().get(end + i + 1));
+              
+              allNodesEqual &=
+                nodeEquality.getStructuralEquality() || nodeEquality.getSemanticalEquality();
+            }
+            
+            if (allNodesEqual)
+            {
+              RuleApplicationResult result = new RuleApplicationResult();
+              result.setRuleApplicationStatus(RuleApplicationStatus.RULE_APPLICATION_FEASIBLE);
+              return result;
+            }
+          }
+          
+          RuleApplicationResult result = new RuleApplicationResult();
+          Iteration newIteration = nodeFactory.createNewIteration();
+          result.addNewlyCreatedParentNode(newIteration);
+          
+          if (equalVariants.size() == 1)
+          {
+            // all children are the same. Create an iteration of this child
+            if (equalVariants.get(0).length == 1)
+            {
+              // all children are the same. Create an iteration of this child
+              treeBuilder.setChild(newIteration, equalVariants.get(0)[0]);
+            }
+            else
+            {
+              // there was an iteration of structurally equal sequences
+              Sequence sequence = nodeFactory.createNewSequence();
+              result.addNewlyCreatedParentNode(sequence);
+              
+              for (TaskTreeNode node : equalVariants.get(0))
+              {
+                treeBuilder.addChild(sequence, node);
+              }
+              
+              treeBuilder.setChild(newIteration, sequence);
+            }
+          }
+          else
+          {
+            // there are distinct variants of semantically equal subsequences or children -->
+            // create an iterated selection
+            Selection selection = nodeFactory.createNewSelection();
+            result.addNewlyCreatedParentNode(selection);
+            
+            for (TaskTreeNode[] variant : equalVariants)
+            {
+              if (variant.length == 1)
+              {
+                treeBuilder.addChild(selection, variant[0]);
+              }
+              else
+              {
+                Sequence sequence = nodeFactory.createNewSequence();
+                result.addNewlyCreatedParentNode(sequence);
+                
+                for (TaskTreeNode node : variant)
+                {
+                  treeBuilder.addChild(sequence, node);
+                }
+                
+                treeBuilder.addChild(selection, sequence);
+              }
+            }
+            
+            treeBuilder.setChild(newIteration, selection);
+          }
+          
+          // remove iterated children
+          for (int j = end; j >= start; j--)
+          {
+            treeBuilder.removeChild((Sequence) parent, j);
+          }
+
+          // add the new iteration instead
+          treeBuilder.addChild((Sequence) parent, start, newIteration);
+
+          result.setRuleApplicationStatus(RuleApplicationStatus.RULE_APPLICATION_FINISHED);
+          return result;
+        }
+      }
+    }
+    
+    return null;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  private List<TaskTreeNode[]> getEqualSublistVariantsInBoundaries(TaskTreeNode parent,
+                                                                   int          start,
+                                                                   int          end)
+  {
+    List<TaskTreeNode[]> equalVariants = null;
+    
+    int noOfChildrenInBoundaries = end - start + 1;
+    
+    for (int subListLength = 1; subListLength <= (noOfChildrenInBoundaries / 2); subListLength++)
+    {
+      if ((noOfChildrenInBoundaries % subListLength) == 0)
+      {
+        equalVariants = getEqualSublistVariantsForSubListLength(parent, start, end, subListLength);
+      
+        if (equalVariants != null)
+        {
+          return equalVariants;
+        }
+      }
+    }
+    
+    return null;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  private List<TaskTreeNode[]> getEqualSublistVariantsForSubListLength(TaskTreeNode parent,
+                                                                       int          start,
+                                                                       int          end,
+                                                                       int          subListLength)
+  {
+    List<TaskTreeNode[]> equalVariants = new ArrayList<TaskTreeNode[]>();
+    TaskTreeNode[] firstVariant = new TaskTreeNode[subListLength];
+    
+    for (int i = 0; i < subListLength; i++)
+    {
+      firstVariant[i] = parent.getChildren().get(start + i);
+    }
+    
+    equalVariants.add(firstVariant);
+    
+    for (int parentIdx = (start + subListLength); parentIdx <= end; parentIdx += subListLength)
+    {
+      TaskTreeNode[] otherVariant = new TaskTreeNode[subListLength];
+      
+      for (int i = 0; i < subListLength; i++)
+      {
+        NodeEquality nodeEquality = mNodeEqualityRuleManager.applyRules
+          (firstVariant[i], parent.getChildren().get(parentIdx + i));
+    
+        if (!nodeEquality.getStructuralEquality())
+        {
+          if (nodeEquality.getSemanticalEquality())
+          {
+            otherVariant[i] = parent.getChildren().get(parentIdx + i);
+          }
+          else
+          {
+            return null;
+          }
+        }
+      }
+      
+      // check, if there is a semantically equal other variant. If so, add it to the list of
+      // variants
+      boolean semanticallyUnequal = false;
+      for (int i = 0; i < subListLength; i++)
+      {
+        if (otherVariant[i] == null)
+        {
+          otherVariant[i] = firstVariant[i];
+        }
+        else
+        {
+          semanticallyUnequal = true;
+        }
+      }
+      
+      if (semanticallyUnequal)
+      {
+        equalVariants.add(otherVariant);
+      }
+    }
+    
+    return equalVariants;
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/temporalrelation/DefaultMouseClickReductionRule.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/temporalrelation/DefaultMouseClickReductionRule.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/temporalrelation/DefaultMouseClickReductionRule.java	(revision 540)
@@ -0,0 +1,152 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: DefaultSequenceDetectionRule.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 18.03.2012 $
+// Project   : TaskTreeCreator
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.temporalrelation;
+
+import de.ugoe.cs.quest.eventcore.guimodel.GUIElement;
+import de.ugoe.cs.quest.eventcore.userinteraction.MouseButtonDown;
+import de.ugoe.cs.quest.eventcore.userinteraction.MouseButtonInteraction;
+import de.ugoe.cs.quest.eventcore.userinteraction.MouseButtonUp;
+import de.ugoe.cs.quest.eventcore.userinteraction.MouseClick;
+import de.ugoe.cs.quest.tasktrees.treeifc.InteractionTask;
+import de.ugoe.cs.quest.tasktrees.treeifc.Sequence;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeBuilder;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNode;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNodeFactory;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 18.03.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public class DefaultMouseClickReductionRule implements TemporalRelationshipRule
+{
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.ugoe.cs.tasktree.temporalrelation.TemporalRelationshipRule#apply(TaskTreeNode, TaskTreeBuilder, TaskTreeNodeFactory)
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public RuleApplicationResult apply(TaskTreeNode        parent,
+                                     TaskTreeBuilder     builder,
+                                     TaskTreeNodeFactory nodeFactory,
+                                     boolean             finalize)
+  {
+    if (!(parent instanceof Sequence))
+    {
+      return null;
+    }
+    
+    RuleApplicationResult result = new RuleApplicationResult();
+    
+    int index = 0;
+    while (index < parent.getChildren().size() - 2) // -2 because we don't need to go to the end
+    {
+      if (mouseClickSequenceFound(parent.getChildren().get(index),
+                                  parent.getChildren().get(index + 1),
+                                  parent.getChildren().get(index + 2)))
+      {
+         builder.removeChild((Sequence) parent, index);
+         builder.removeChild((Sequence) parent, index);
+         result.setRuleApplicationStatus(RuleApplicationStatus.RULE_APPLICATION_FINISHED);
+         return result;
+      }
+      else if ((parent.getChildren().get(index) instanceof Sequence) &&
+               (parent.getChildren().get(index).getChildren().size() == 2) &&
+               (mouseClickSequenceFound(parent.getChildren().get(index).getChildren().get(0),
+                                        parent.getChildren().get(index).getChildren().get(1),
+                                        parent.getChildren().get(index + 1))))
+      {
+        builder.removeChild((Sequence) parent, index);
+        result.setRuleApplicationStatus(RuleApplicationStatus.RULE_APPLICATION_FINISHED);
+        return result;
+      }
+      
+      index++;
+    }
+    
+    return result;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * 
+   */
+  //-----------------------------------------------------------------------------------------------
+  private boolean mouseClickSequenceFound(TaskTreeNode mouseButtonDown,
+                                          TaskTreeNode mouseButtonUp,
+                                          TaskTreeNode mouseClick)
+  {
+    // check the first in a row of three for validity
+    if (!(mouseButtonDown instanceof InteractionTask))
+    {
+      return false;
+    }
+    
+    GUIElement guiElement = ((InteractionTask) mouseButtonDown).getGUIElement();
+    
+    if (!(((InteractionTask) mouseButtonDown).getInteraction() instanceof MouseButtonDown))
+    {
+      return false;
+    }
+    
+    MouseButtonInteraction.Button button =
+      ((MouseButtonDown) ((InteractionTask) mouseButtonDown).getInteraction()).getButton();
+    
+    
+    // check the second node for validity
+    if (!(mouseButtonUp instanceof InteractionTask))
+    {
+      return false;
+    }
+    
+    if (!guiElement.equals(((InteractionTask) mouseButtonUp).getGUIElement()))
+    {
+      return false;
+    }
+    
+    if (!(((InteractionTask) mouseButtonUp).getInteraction() instanceof MouseButtonUp))
+    {
+      return false;
+    }
+    
+    if (!button.equals
+          (((MouseButtonUp) ((InteractionTask) mouseButtonUp).getInteraction()).getButton()))
+    {
+      return false;
+    }
+    
+    
+    // check the third node for validity
+    if (!(mouseClick instanceof InteractionTask))
+    {
+      return false;
+    }
+    
+    if (!guiElement.equals(((InteractionTask) mouseClick).getGUIElement()))
+    {
+      return false;
+    }
+    
+    if (!(((InteractionTask) mouseClick).getInteraction() instanceof MouseClick))
+    {
+      return false;
+    }
+    
+    if (!button.equals(((MouseClick) ((InteractionTask) mouseClick).getInteraction()).getButton()))
+    {
+      return false;
+    }
+    
+    return true;
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/temporalrelation/DefaultSequenceDetectionRule.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/temporalrelation/DefaultSequenceDetectionRule.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/temporalrelation/DefaultSequenceDetectionRule.java	(revision 540)
@@ -0,0 +1,124 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: DefaultSequenceDetectionRule.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 18.03.2012 $
+// Project   : TaskTreeCreator
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.temporalrelation;
+
+import de.ugoe.cs.quest.tasktrees.treeifc.InteractionTask;
+import de.ugoe.cs.quest.tasktrees.treeifc.Sequence;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeBuilder;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNode;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNodeFactory;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 18.03.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public class DefaultSequenceDetectionRule implements TemporalRelationshipRule
+{
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.ugoe.cs.tasktree.temporalrelation.TemporalRelationshipRule#apply(TaskTreeNode, TaskTreeBuilder, TaskTreeNodeFactory)
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public RuleApplicationResult apply(TaskTreeNode        parent,
+                                     TaskTreeBuilder     builder,
+                                     TaskTreeNodeFactory nodeFactory,
+                                     boolean             finalize)
+  {
+    if (!(parent instanceof Sequence))
+    {
+      return null;
+    }
+    
+    RuleApplicationResult result = new RuleApplicationResult();
+    int sequenceStartingIndex = -1;
+    
+    int index = 0;
+    while (index < parent.getChildren().size())
+    {
+      TaskTreeNode child = parent.getChildren().get(index);
+      
+      if (child instanceof InteractionTask)
+      {
+        if (((InteractionTask) child).getInteraction().finishesLogicalSequence() &&
+            (sequenceStartingIndex > -1))
+        {
+          // There are several situations in which this implementation may cause infinite
+          // loops. This is because the rule manager will reapply rules until
+          // no rule is applied anymore. A sequence identified in a first iteration will
+          // be identified as a sequence also in a second iteration. As an example
+          // many sequences start with an interaction starting that sequence and end
+          // with an interaction ending that sequence. This will be reidentified as further 
+          // subsequence. It must therefore be assured, that a sequence, that was once
+          // identified is not reidentified in a further application of the rule. For this,
+          // the implementation performs a kind of dry run. It creates a list of children
+          // that would belong to an identified sequence. Only if this list is not a
+          // reidentification then a new sequence is created and added to the parent. If it
+          // is a reidentification can be identified, if the list of children will contain
+          // all children of the parent, or if the list of children only consists of one
+          // sequence. Further, an identified sequence must at least have one child.
+          if (((sequenceStartingIndex != 0) || (index != (parent.getChildren().size() - 1))) &&
+              (((index - sequenceStartingIndex) > 0) ||
+                (((index - sequenceStartingIndex) == 0) &&
+                 (!((InteractionTask) child).getInteraction().startsLogicalSequence()))))
+          {
+            boolean allNewChildrenAreSequences = true;
+            
+            for (int j = sequenceStartingIndex; ((allNewChildrenAreSequences) && (j < index)); j++)
+            {
+              allNewChildrenAreSequences &= (parent.getChildren().get(j) instanceof Sequence);
+            }
+            
+            if (!allNewChildrenAreSequences)
+            {
+              Sequence sequence = nodeFactory.createNewSequence();
+            
+              for (int j = sequenceStartingIndex; j < index; j++)
+              {
+                builder.addChild(sequence, parent.getChildren().get(sequenceStartingIndex));
+                builder.removeChild((Sequence) parent, sequenceStartingIndex);
+              }
+
+              if (!((InteractionTask) child).getInteraction().startsLogicalSequence())
+              {
+                builder.addChild(sequence, parent.getChildren().get(sequenceStartingIndex));
+                builder.removeChild((Sequence) parent, sequenceStartingIndex);
+              }
+
+              builder.addChild((Sequence) parent, sequenceStartingIndex, sequence);
+
+              result.addNewlyCreatedParentNode(sequence);
+              result.setRuleApplicationStatus(RuleApplicationStatus.RULE_APPLICATION_FINISHED);
+              return result;
+            }
+          }
+        }
+        
+        if (((InteractionTask) child).getInteraction().startsLogicalSequence())
+        {
+          sequenceStartingIndex = index;
+        }
+      }
+      
+      index++;
+    }
+    
+    if (sequenceStartingIndex >= 0)
+    {
+      result.setRuleApplicationStatus(RuleApplicationStatus.RULE_APPLICATION_FEASIBLE);
+    }
+    
+    return result;
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/temporalrelation/DefaultTextInputReductionRule.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/temporalrelation/DefaultTextInputReductionRule.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/temporalrelation/DefaultTextInputReductionRule.java	(revision 540)
@@ -0,0 +1,273 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: DefaultSequenceDetectionRule.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 18.03.2012 $
+// Project   : TaskTreeCreator
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.temporalrelation;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+
+import de.ugoe.cs.quest.eventcore.guimodel.GUIElement;
+import de.ugoe.cs.quest.eventcore.guimodel.TextArea;
+import de.ugoe.cs.quest.eventcore.guimodel.TextField;
+import de.ugoe.cs.quest.eventcore.userinteraction.KeyInteraction;
+import de.ugoe.cs.quest.eventcore.userinteraction.KeyPressed;
+import de.ugoe.cs.quest.eventcore.userinteraction.KeyReleased;
+import de.ugoe.cs.quest.tasktrees.treeifc.InteractionTask;
+import de.ugoe.cs.quest.tasktrees.treeifc.Sequence;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeBuilder;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNode;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNodeFactory;
+import de.ugoe.cs.quest.tasktrees.treeifc.TextInputInteractionTask;
+import de.ugoe.cs.tasktree.keyboardmaps.KeyboardMap;
+import de.ugoe.cs.tasktree.keyboardmaps.KeyboardMapFactory;
+import de.ugoe.cs.tasktree.keyboardmaps.VirtualKey;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 18.03.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public class DefaultTextInputReductionRule implements TemporalRelationshipRule
+{
+  /** */
+  private KeyboardMap mKeyboardMap = KeyboardMapFactory.createKeyboardMap(Locale.GERMAN);
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see TemporalRelationshipRule#apply(TaskTreeNode, TaskTreeBuilder, TaskTreeNodeFactory)
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public RuleApplicationResult apply(TaskTreeNode        parent,
+                                     TaskTreeBuilder     builder,
+                                     TaskTreeNodeFactory nodeFactory,
+                                     boolean             finalize)
+  {
+    if ((!(parent instanceof Sequence)) ||
+        (parent instanceof TextInputInteractionTask))
+    {
+      return null;
+    }
+    
+    RuleApplicationResult result = new RuleApplicationResult();
+    int textEntryStartIndex = -1;
+    GUIElement currentGUIElement = null;
+    
+    int index = 0;
+    TaskTreeNode task = null;
+    while (index < parent.getChildren().size())
+    {
+      task = parent.getChildren().get(index);
+      if (isKeyInteraction(task) && isDataInputGUIElement(((InteractionTask) task).getGUIElement()))
+      {
+        if (textEntryStartIndex < 0)
+        {
+          textEntryStartIndex = index;
+          currentGUIElement = ((InteractionTask) task).getGUIElement();
+        }
+        else if (!currentGUIElement.equals(((InteractionTask) task).getGUIElement()))
+        {
+           handleTextEntrySequence(parent, textEntryStartIndex, index - 1, currentGUIElement,
+                                   builder, nodeFactory, result);
+           return result;
+        }
+      }
+      else if (textEntryStartIndex >= 0)
+      {
+        handleTextEntrySequence(parent, textEntryStartIndex, index - 1, currentGUIElement,
+                                builder, nodeFactory, result);
+        return result;
+      }
+      
+      index++;
+    }
+    
+    if (textEntryStartIndex >= 0)
+    {
+      if (finalize)
+      {
+        handleTextEntrySequence(parent, textEntryStartIndex, parent.getChildren().size() - 1,
+                                currentGUIElement, builder, nodeFactory, result);
+      }
+      else
+      {
+        result.setRuleApplicationStatus(RuleApplicationStatus.RULE_APPLICATION_FEASIBLE);
+      }
+    }
+    
+    return result;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param taskTreeNode
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  private boolean isKeyInteraction(TaskTreeNode taskTreeNode)
+  {
+    if ((taskTreeNode instanceof InteractionTask))
+    {
+      return (((InteractionTask) taskTreeNode).getInteraction() instanceof KeyInteraction);
+    }
+    else
+    {
+      return false;
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param textEntryStartIndex
+   * @param i
+   * @param result
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  private void handleTextEntrySequence(TaskTreeNode          parent,
+                                       int                   startIndex,
+                                       int                   endIndex,
+                                       GUIElement            guiElement,
+                                       TaskTreeBuilder       builder,
+                                       TaskTreeNodeFactory   nodeFactory,
+                                       RuleApplicationResult result)
+  {
+    TextInputInteractionTask textInput = nodeFactory.createNewTextInputInteractionTask(guiElement);
+    
+    for (int i = startIndex; i <= endIndex; i++)
+    {
+      builder.addChild(textInput, parent.getChildren().get(startIndex));
+      builder.removeChild((Sequence) parent, startIndex);
+    }
+    
+    builder.addChild((Sequence) parent, startIndex, textInput);
+    
+    StringBuffer enteredText = new StringBuffer();
+    determineEnteredText(textInput, new ArrayList<VirtualKey>(), enteredText);
+    textInput.setEnteredText(enteredText.toString());
+    
+    result.addNewlyCreatedParentNode(textInput);
+    result.setRuleApplicationStatus(RuleApplicationStatus.RULE_APPLICATION_FINISHED);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param guiElement
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  private boolean isDataInputGUIElement(GUIElement guiElement)
+  {
+    return ((guiElement instanceof TextField) || (guiElement instanceof TextArea));
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param sequence
+   * @param enteredText
+   */
+  //-----------------------------------------------------------------------------------------------
+  private void determineEnteredText(TaskTreeNode     node,
+                                    List<VirtualKey> pressedKeys,
+                                    StringBuffer     enteredText)
+  {
+    if ((node instanceof Sequence) || (node instanceof TextInputInteractionTask))
+    {
+      for (TaskTreeNode child : node.getChildren())
+      {
+        if (child instanceof InteractionTask)
+        {
+          if (((InteractionTask) child).getInteraction() instanceof KeyPressed)
+          {
+            VirtualKey key = ((KeyPressed) ((InteractionTask) child).getInteraction()).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 (!(((InteractionTask) child).getGUIElement() instanceof TextField))
+              {
+                enteredText.append(getCharacter(key, pressedKeys));
+              }
+            }
+            else
+            {
+              char theChar = getCharacter(key, pressedKeys);
+              if (theChar != Character.UNASSIGNED)
+              {
+                enteredText.append(theChar);
+              }
+            }
+          }
+          else if (((InteractionTask) child).getInteraction() instanceof KeyReleased)
+          {
+            pressedKeys.remove(((KeyReleased) ((InteractionTask) child).getInteraction()).getKey());
+          }
+        }
+        else
+        {
+          determineEnteredText(child, pressedKeys, enteredText);
+        }
+      }
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param key
+   * @param pressedKeys
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  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 mKeyboardMap.getCharacterFor(key, numlock, shift, altgr, false);
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/temporalrelation/RuleApplicationResult.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/temporalrelation/RuleApplicationResult.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/temporalrelation/RuleApplicationResult.java	(revision 540)
@@ -0,0 +1,92 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: RuleApplicationResult.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 18.03.2012 $
+// Project   : TaskTreeCreator
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.temporalrelation;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNode;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 18.03.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public class RuleApplicationResult
+{
+
+  /** */
+  private RuleApplicationStatus mStatus = RuleApplicationStatus.RULE_NOT_APPLIED;
+  
+  /** */
+  private List<TaskTreeNode> mNewParents = new ArrayList<TaskTreeNode>();
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param b
+   */
+  //-----------------------------------------------------------------------------------------------
+  public RuleApplicationResult()
+  {
+    // this is the default indicating nothing so far
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param b
+   */
+  //-----------------------------------------------------------------------------------------------
+  public void setRuleApplicationStatus(RuleApplicationStatus status)
+  {
+    mStatus = status;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  public RuleApplicationStatus getRuleApplicationStatus()
+  {
+    return mStatus;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param sequence
+   */
+  //-----------------------------------------------------------------------------------------------
+  public void addNewlyCreatedParentNode(TaskTreeNode newParent)
+  {
+    mNewParents.add(newParent);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  public List<TaskTreeNode> getNewlyCreatedParentNodes()
+  {
+    return mNewParents;
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/temporalrelation/RuleApplicationStatus.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/temporalrelation/RuleApplicationStatus.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/temporalrelation/RuleApplicationStatus.java	(revision 540)
@@ -0,0 +1,23 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: RuleApplicationStatus.java,v $
+// Version   : $Revision: 0.0 $  $Author: pharms $  $Date: 09.07.2012 $
+// Project   : TaskTreeTemporalRelationship
+// Creation  : 2012 by pharms
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.temporalrelation;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 09.07.2012$
+ * @author 2012, last modified by $Author: pharms$
+ */
+//-------------------------------------------------------------------------------------------------
+public enum RuleApplicationStatus
+{
+  RULE_APPLICATION_FINISHED,
+  RULE_APPLICATION_FEASIBLE,
+  RULE_NOT_APPLIED;
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/temporalrelation/TemporalRelationshipRule.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/temporalrelation/TemporalRelationshipRule.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/temporalrelation/TemporalRelationshipRule.java	(revision 540)
@@ -0,0 +1,36 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: TemporalRelationshipRule.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 12.02.2012 $
+// Project   : TaskTreeCreator
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.temporalrelation;
+
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeBuilder;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNode;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNodeFactory;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 12.02.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public interface TemporalRelationshipRule
+{
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * applies the rule to the given situation and returns a rule application result, if this was
+   * successful
+   */
+  //-----------------------------------------------------------------------------------------------
+  public RuleApplicationResult apply(TaskTreeNode        parent,
+                                     TaskTreeBuilder     builder,
+                                     TaskTreeNodeFactory nodeFactory,
+                                     boolean             finalize);
+  
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/temporalrelation/TemporalRelationshipRuleManager.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/temporalrelation/TemporalRelationshipRuleManager.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/temporalrelation/TemporalRelationshipRuleManager.java	(revision 540)
@@ -0,0 +1,166 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: TemporalRelationshipRuleManager.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 12.02.2012 $
+// Project   : TaskTreeCreator
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.temporalrelation;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Logger;
+
+import de.ugoe.cs.quest.tasktrees.nodeequality.NodeEqualityRuleManager;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeBuilder;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNode;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNodeFactory;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 12.02.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public class TemporalRelationshipRuleManager
+{
+  /** */
+  private static Logger LOG = Logger.getLogger(TemporalRelationshipRuleManager.class.getName());
+
+  /** */
+  private NodeEqualityRuleManager mNodeEqualityRuleManager;
+
+  /** */
+  private List<TemporalRelationshipRule> mRuleIndex = new ArrayList<TemporalRelationshipRule>();
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  public TemporalRelationshipRuleManager(NodeEqualityRuleManager nodeEqualityRuleManager)
+  {
+    super();
+    mNodeEqualityRuleManager = nodeEqualityRuleManager;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  public void init()
+  {
+    LOG.info("initializing");
+    
+    mRuleIndex.add(new DefaultMouseClickReductionRule());
+    mRuleIndex.add(new DefaultTextInputReductionRule());
+    mRuleIndex.add(new DefaultGUIElementSequenceDetectionRule());
+    mRuleIndex.add(new TrackBarSelectionDetectionRule(mNodeEqualityRuleManager));
+    mRuleIndex.add(new DefaultSequenceDetectionRule());
+    mRuleIndex.add(new DefaultIterationDetectionRule(mNodeEqualityRuleManager));
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * returns true, if there is a rule that matches the current situation and if, therefore, a
+   * new temporal relationship has been added to the tree.
+   * 
+   * @param parent
+   * @param newChild
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  public void applyRules(TaskTreeNode        parent,
+                         TaskTreeBuilder     builder,
+                         TaskTreeNodeFactory nodeFactory,
+                         boolean             finalize)
+  {
+    applyRules(parent, builder, nodeFactory, finalize, "");
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * returns true, if there is a rule that matches the current situation and if, therefore, a
+   * new temporal relationship has been added to the tree.
+   * 
+   * @param parent
+   * @param newChild
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  private int applyRules(TaskTreeNode        parent,
+                         TaskTreeBuilder     builder,
+                         TaskTreeNodeFactory nodeFactory,
+                         boolean             finalize,
+                         String              logIndent)
+  {
+    LOG.info(logIndent + "applying rules for " + parent);
+    
+    int noOfRuleApplications = 0;
+    
+    for (TemporalRelationshipRule rule : mRuleIndex)
+    {
+      RuleApplicationResult result;
+      do
+      {
+        //LOG.info(logIndent + "trying to apply rule " + rule + " on " + parent);
+        result = rule.apply(parent, builder, nodeFactory, finalize);
+        
+        if ((result != null) &&
+            (result.getRuleApplicationStatus() == RuleApplicationStatus.RULE_APPLICATION_FINISHED))
+        {
+          LOG.info(logIndent + "applied rule " + rule + " on " + parent);
+          noOfRuleApplications++;
+          
+          for (TaskTreeNode newParent : result.getNewlyCreatedParentNodes())
+          {
+            noOfRuleApplications +=
+              applyRules(newParent, builder, nodeFactory, true, logIndent + "  ");
+          }
+        }
+      }
+      while ((result != null) &&
+             (result.getRuleApplicationStatus() == RuleApplicationStatus.RULE_APPLICATION_FINISHED));
+      
+      if ((!finalize) && (result != null) &&
+          (result.getRuleApplicationStatus() == RuleApplicationStatus.RULE_APPLICATION_FEASIBLE))
+      {
+        // in this case, don't go on applying rules, which should not be applied yet
+        break;
+      }
+    }
+    
+    if (noOfRuleApplications <= 0)
+    {
+      LOG.warning(logIndent + "no rules applied --> no temporal relationship generated");
+    }
+    
+    return noOfRuleApplications;
+  }
+  
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  /*private void dumpTask(TaskTreeNode task, String indent)
+  {
+    System.err.print(indent);
+    System.err.print(task);
+    System.err.println(" ");
+    
+    if ((task.getChildren() != null) && (task.getChildren().size() > 0))
+    {
+      for (TaskTreeNode child : task.getChildren())
+      {
+        dumpTask(child, indent + "  ");
+      }
+    }
+  }*/
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/temporalrelation/TrackBarSelectionDetectionRule.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/temporalrelation/TrackBarSelectionDetectionRule.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/temporalrelation/TrackBarSelectionDetectionRule.java	(revision 540)
@@ -0,0 +1,220 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: TrackBarSelectionDetectionRule.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 28.04.2012 $
+// Project   : TaskTreeTemporalRelationship
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.temporalrelation;
+
+import de.ugoe.cs.quest.eventcore.guimodel.TrackBar;
+import de.ugoe.cs.quest.eventcore.userinteraction.ValueSelection;
+import de.ugoe.cs.quest.tasktrees.nodeequality.NodeEquality;
+import de.ugoe.cs.quest.tasktrees.nodeequality.NodeEqualityRuleManager;
+import de.ugoe.cs.quest.tasktrees.treeifc.InteractionTask;
+import de.ugoe.cs.quest.tasktrees.treeifc.Iteration;
+import de.ugoe.cs.quest.tasktrees.treeifc.Selection;
+import de.ugoe.cs.quest.tasktrees.treeifc.Sequence;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeBuilder;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNode;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNodeFactory;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 28.04.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public class TrackBarSelectionDetectionRule implements TemporalRelationshipRule
+{
+
+  /** */
+  private NodeEqualityRuleManager mNodeEqualityRuleManager;
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  TrackBarSelectionDetectionRule(NodeEqualityRuleManager nodeEqualityRuleManager)
+  {
+    super();
+    mNodeEqualityRuleManager = nodeEqualityRuleManager;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see TemporalRelationshipRule#apply(TaskTreeNode, TaskTreeBuilder, TaskTreeNodeFactory)
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public RuleApplicationResult apply(TaskTreeNode        parent,
+                                     TaskTreeBuilder     builder,
+                                     TaskTreeNodeFactory nodeFactory,
+                                     boolean             finalize)
+  {
+    if (!(parent instanceof Sequence))
+    {
+      return null;
+    }
+    
+    RuleApplicationResult result = new RuleApplicationResult();
+    
+    int valueSelectionStartIndex = -1;
+    
+    int index = 0;
+    while (index < parent.getChildren().size())
+    {
+      TaskTreeNode child = parent.getChildren().get(index);
+      
+      if ((child instanceof InteractionTask) &&
+          (((InteractionTask) child).getGUIElement() instanceof TrackBar) &&
+          (((InteractionTask) child).getInteraction() instanceof ValueSelection))
+      {
+        if (valueSelectionStartIndex < 0)
+        {
+          // let the show begin
+          valueSelectionStartIndex = index;
+        }
+      }
+      else if (valueSelectionStartIndex >= 0)
+      {
+        // current child is no more value selection. But the preceding tasks were. Therefore,
+        // create an iteration with the different selectable values as selection children
+        handleValueSelections
+          (valueSelectionStartIndex, index - 1, parent, builder, nodeFactory, result);
+        
+        return result;
+      }
+      
+      index++;
+    }
+    
+    if (valueSelectionStartIndex >= 0)
+    {
+      if (finalize)
+      {
+        handleValueSelections(valueSelectionStartIndex, parent.getChildren().size() - 1, parent,
+                              builder, nodeFactory, result);
+      }
+      else
+      {
+        result.setRuleApplicationStatus(RuleApplicationStatus.RULE_APPLICATION_FEASIBLE);
+      }
+    }
+    
+    return result;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param valueSelectionStartIndex
+   * @param i
+   */
+  //-----------------------------------------------------------------------------------------------
+  private void handleValueSelections(int                   startIndex,
+                                     int                   endIndex,
+                                     TaskTreeNode          parent,
+                                     TaskTreeBuilder       builder,
+                                     TaskTreeNodeFactory   nodeFactory,
+                                     RuleApplicationResult result)
+  {
+    Iteration iteration = nodeFactory.createNewIteration();
+    result.addNewlyCreatedParentNode(iteration);
+    
+    Selection selection = nodeFactory.createNewSelection();
+    result.addNewlyCreatedParentNode(selection);
+    builder.setChild(iteration, selection);
+    
+    for (int i = endIndex - startIndex; i >= 0 ; i--)
+    {
+      addChildIfNecessary
+        (selection, parent.getChildren().get(startIndex), builder, nodeFactory, result);
+      builder.removeChild((Sequence) parent, startIndex);
+    }
+    
+    builder.addChild((Sequence) parent, startIndex, iteration);
+    
+    result.setRuleApplicationStatus(RuleApplicationStatus.RULE_APPLICATION_FINISHED);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  private void addChildIfNecessary(Selection             parentSelection,
+                                   TaskTreeNode          node,
+                                   TaskTreeBuilder       builder,
+                                   TaskTreeNodeFactory   nodeFactory,
+                                   RuleApplicationResult result)
+  {
+    for (int i = 0; i < parentSelection.getChildren().size(); i++)
+    {
+      TaskTreeNode child = parentSelection.getChildren().get(i);
+
+      if (child instanceof InteractionTask)
+      {
+        // check, if the new node is a variant for the current interaction task
+        NodeEquality nodeEquality = mNodeEqualityRuleManager.applyRules(child, node);
+        if (nodeEquality.getSemanticalEquality())
+        {
+          // the node is a variant. If it not structurally equal, a new sub-selection for the
+          // existing and the new node must be created. Otherwise, the new node does not need
+          // to be added
+          if (!nodeEquality.getStructuralEquality())
+          {
+            Selection selection = nodeFactory.createNewSelection();
+            result.addNewlyCreatedParentNode(selection);
+            builder.addChild(parentSelection, selection);
+
+            builder.addChild(selection, child);
+            builder.addChild(selection, node);
+            builder.removeChild(parentSelection, child);
+          }
+
+          return;
+        }
+      }
+      else if (child instanceof Selection)
+      {
+        // check, if the new node is a variant for the semantically equal children of the current
+        // selection
+        boolean addNode = true;
+        for (int j = 0; j < child.getChildren().size(); j++)
+        {
+          NodeEquality nodeEquality = mNodeEqualityRuleManager.applyRules(child, node);
+          if (!nodeEquality.getSemanticalEquality())
+          {
+            // the new node is no semantical equivalent of the nodes in the current selection -
+            // break up
+            addNode = false;
+            break;
+          }
+          else if (nodeEquality.getStructuralEquality())
+          {
+            addNode = false;
+            break;
+          }
+        }
+
+        if (addNode)
+        {
+          // the node is a semantical equivalent to all the nodes in the existing sub-selection
+          // but it is not structurally identical to either of them. Therefore add it.
+          builder.addChild((Selection) child, node);
+          return;
+        }
+      }
+    }
+    
+    // if we did not return in the previous checks, then the node must be added
+    builder.addChild(parentSelection, node);
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeifc/AbstractTask.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeifc/AbstractTask.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeifc/AbstractTask.java	(revision 540)
@@ -0,0 +1,22 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: AbstractTask.java,v $
+// Version   : $Revision: 0.0 $  $Author: Patrick $  $Date: 06.11.2011 12:53:24 $
+// Project   : TaskTreePerformanceTest
+// Creation  : 2011 by Patrick
+// Copyright : Patrick Harms, 2011
+//-------------------------------------------------------------------------------------------------
+
+package de.ugoe.cs.quest.tasktrees.treeifc;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ *
+ * @version $Revision: $ $Date: $
+ * @author  2011, last modified by $Author: $
+ */
+//-------------------------------------------------------------------------------------------------
+public interface AbstractTask extends TaskTreeNode
+{
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeifc/InteractionTask.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeifc/InteractionTask.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeifc/InteractionTask.java	(revision 540)
@@ -0,0 +1,38 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: InteractionTask.java,v $
+// Version   : $Revision: 0.0 $  $Author: Patrick $  $Date: 08.11.2011 19:44:52 $
+// Project   : TaskTreePerformanceTest
+// Creation  : 2011 by Patrick
+// Copyright : Patrick Harms, 2011
+//-------------------------------------------------------------------------------------------------
+
+package de.ugoe.cs.quest.tasktrees.treeifc;
+
+import de.ugoe.cs.quest.eventcore.guimodel.GUIElement;
+import de.ugoe.cs.quest.eventcore.userinteraction.Interaction;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ *
+ * @version $Revision: $ $Date: $
+ * @author  2011, last modified by $Author: $
+ */
+//-------------------------------------------------------------------------------------------------
+public interface InteractionTask extends TaskTreeNode
+{
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * @return Returns the interaction.
+   */
+  //-----------------------------------------------------------------------------------------------
+  public Interaction getInteraction();
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * @return Returns the GUIElement.
+   */
+  //-----------------------------------------------------------------------------------------------
+  public GUIElement getGUIElement();
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeifc/Iteration.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeifc/Iteration.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeifc/Iteration.java	(revision 540)
@@ -0,0 +1,21 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: Iteration.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 21.02.2012 $
+// Project   : TaskTreeCreator
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.treeifc;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 21.02.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public interface Iteration extends TemporalRelationship
+{
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeifc/NodeInfo.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeifc/NodeInfo.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeifc/NodeInfo.java	(revision 540)
@@ -0,0 +1,43 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: NodeInfo.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 21.02.2012 $
+// Project   : TaskTreeCreator
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+
+package de.ugoe.cs.quest.tasktrees.treeifc;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 21.02.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public interface NodeInfo
+{
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * 
+   */
+  //-----------------------------------------------------------------------------------------------
+  public TaskTreeNode getTask();
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * 
+   */
+  //-----------------------------------------------------------------------------------------------
+  public int getNoOfOccurencesInTree();
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  public long getLastUpdate();
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeifc/Selection.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeifc/Selection.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeifc/Selection.java	(revision 540)
@@ -0,0 +1,21 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: Selection.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 21.02.2012 $
+// Project   : TaskTreeCreator
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.treeifc;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 21.02.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public interface Selection extends TemporalRelationship
+{
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeifc/Sequence.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeifc/Sequence.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeifc/Sequence.java	(revision 540)
@@ -0,0 +1,30 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: Sequence.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 21.02.2012 $
+// Project   : TaskTreeCreator
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.treeifc;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 21.02.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public interface Sequence extends TemporalRelationship
+{
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  public Sequence clone();
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeifc/TaskTree.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeifc/TaskTree.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeifc/TaskTree.java	(revision 540)
@@ -0,0 +1,47 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: TaskTree.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 21.02.2012 $
+// Project   : TaskTreeCreator
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.treeifc;
+
+import java.util.Map;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 21.02.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public interface TaskTree extends Cloneable
+{
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  public TaskTreeNode getRoot();
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  public Map<TaskTreeNode, NodeInfo> getTaskMap();
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  public TaskTree clone();
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeifc/TaskTreeBuilder.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeifc/TaskTreeBuilder.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeifc/TaskTreeBuilder.java	(revision 540)
@@ -0,0 +1,102 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: TaskTreeBuilder.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 21.02.2012 $
+// Project   : TaskTreeCreator
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.treeifc;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 21.02.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public interface TaskTreeBuilder
+{
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param sequence
+   * @param task
+   */
+  //-----------------------------------------------------------------------------------------------
+  void addChild(Sequence parent, TaskTreeNode child);
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param parent
+   * @param index
+   * @param sequence
+   */
+  //-----------------------------------------------------------------------------------------------
+  void addChild(Sequence parent, int index, TaskTreeNode child);
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param sequence
+   * @param task
+   */
+  //-----------------------------------------------------------------------------------------------
+  void addChild(Selection parent, TaskTreeNode child);
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param sequence
+   * @param task
+   */
+  //-----------------------------------------------------------------------------------------------
+  void addChild(TextInputInteractionTask parent, TaskTreeNode child);
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param iteration
+   * @param newChild
+   */
+  //-----------------------------------------------------------------------------------------------
+  void setChild(Iteration iteration, TaskTreeNode newChild);
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param parent
+   * @param i
+   */
+  //-----------------------------------------------------------------------------------------------
+  void removeChild(Sequence parent, int index);
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param parent
+   * @param i
+   */
+  //-----------------------------------------------------------------------------------------------
+  void removeChild(Selection parent, TaskTreeNode child);
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param parent
+   * @param i
+   */
+  //-----------------------------------------------------------------------------------------------
+  void setDescription(TaskTreeNode parent, String description);
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeifc/TaskTreeNode.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeifc/TaskTreeNode.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeifc/TaskTreeNode.java	(revision 540)
@@ -0,0 +1,75 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: Task.java,v $
+// Version   : $Revision: 0.0 $  $Author: Patrick $  $Date: 08.11.2011 19:42:29 $
+// Project   : TaskTreePerformanceTest
+// Creation  : 2011 by Patrick
+// Copyright : Patrick Harms, 2011
+//-------------------------------------------------------------------------------------------------
+
+package de.ugoe.cs.quest.tasktrees.treeifc;
+
+import java.util.List;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ *
+ * @version $Revision: $ $Date: $
+ * @author  2011, last modified by $Author: $
+ */
+//-------------------------------------------------------------------------------------------------
+public interface TaskTreeNode extends Cloneable
+{
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  public String getName();
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   */
+  //-----------------------------------------------------------------------------------------------
+  //public void addChild(TaskTreeNode child);
+  
+  //-----------------------------------------------------------------------------------------------
+  /**
+   */
+  //-----------------------------------------------------------------------------------------------
+  //public void removeChild(int index);
+  
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  public String getDescription();
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   */
+  //-----------------------------------------------------------------------------------------------
+  public List<TaskTreeNode> getChildren();
+  
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  public boolean equals(TaskTreeNode taskTreeNode);
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  public int hashCode();
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  public TaskTreeNode clone();
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeifc/TaskTreeNodeFactory.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeifc/TaskTreeNodeFactory.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeifc/TaskTreeNodeFactory.java	(revision 540)
@@ -0,0 +1,82 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: TaskTreeNodeFactory.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 21.02.2012 $
+// Project   : TaskTreeCreator
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.treeifc;
+
+import de.ugoe.cs.quest.eventcore.guimodel.GUIElement;
+import de.ugoe.cs.quest.eventcore.userinteraction.Interaction;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 21.02.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public interface TaskTreeNodeFactory
+{
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param GUIElement
+   * @param interaction
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  InteractionTask createNewInteractionTask(GUIElement  guiElement,
+                                           Interaction interaction);
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  Sequence createNewSequence();
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  TextInputInteractionTask createNewTextInputInteractionTask(GUIElement guiElement);
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  Iteration createNewIteration();
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  Selection createNewSelection();
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param rootSequence
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  TaskTree createTaskTree(TaskTreeNode root);
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeifc/TemporalRelationship.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeifc/TemporalRelationship.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeifc/TemporalRelationship.java	(revision 540)
@@ -0,0 +1,21 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: TemporalRelationship.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 12.02.2012 $
+// Project   : TaskTreeCreator
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.treeifc;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 12.02.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+// -------------------------------------------------------------------------------------------------
+public interface TemporalRelationship extends TaskTreeNode
+{
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeifc/TextInputInteractionTask.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeifc/TextInputInteractionTask.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeifc/TextInputInteractionTask.java	(revision 540)
@@ -0,0 +1,44 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: TextInputSequence.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 10.06.2012 $
+// Project   : TaskTreeIfc
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.treeifc;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 10.06.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public interface TextInputInteractionTask extends InteractionTask
+{
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  public TextInputInteractionTask clone();
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * 
+   */
+  //-----------------------------------------------------------------------------------------------
+  public String getEnteredText();
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param string
+   */
+  //-----------------------------------------------------------------------------------------------
+  public void setEnteredText(String text);
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeimpl/InteractionTaskImpl.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeimpl/InteractionTaskImpl.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeimpl/InteractionTaskImpl.java	(revision 540)
@@ -0,0 +1,106 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: InteractionTask.java,v $
+// Version   : $Revision: 0.0 $  $Author: Patrick $  $Date: 06.11.2011 10:57:52 $
+// Project   : TaskTreePerformanceTest
+// Creation  : 2011 by Patrick
+// Copyright : Patrick Harms, 2011
+//-------------------------------------------------------------------------------------------------
+
+package de.ugoe.cs.quest.tasktrees.treeimpl;
+
+import de.ugoe.cs.quest.eventcore.guimodel.GUIElement;
+import de.ugoe.cs.quest.eventcore.userinteraction.Interaction;
+import de.ugoe.cs.quest.tasktrees.treeifc.InteractionTask;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNode;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ *
+ * @version $Revision: $ $Date: $
+ * @author  2011, last modified by $Author: $
+ */
+//-------------------------------------------------------------------------------------------------
+public class InteractionTaskImpl extends TaskTreeNodeImpl implements InteractionTask
+{
+  /** */
+  private GUIElement mGUIElement;
+  
+  /** */
+  private Interaction mInteraction;
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * @param guiElement
+   * @param interaction
+   */
+  //-----------------------------------------------------------------------------------------------
+  InteractionTaskImpl(GUIElement guiElement, Interaction interaction)
+  {
+    super(interaction.getName() + "(" + guiElement + ")");
+    super.setDescription(interaction + " on " + guiElement);
+    mGUIElement = guiElement;
+    mInteraction = interaction;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * @return Returns the interaction.
+   */
+  //-----------------------------------------------------------------------------------------------
+  public Interaction getInteraction()
+  {
+    return mInteraction;
+  }
+
+  
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * @return Returns the GUIElement.
+   */
+  //-----------------------------------------------------------------------------------------------
+  public GUIElement getGUIElement()
+  {
+    return mGUIElement;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.harms.ctte.Task#equals(de.harms.ctte.Task)
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public boolean equals(TaskTreeNode task)
+  {
+    if (!(task instanceof InteractionTask))
+    {
+      return false;
+    }
+    
+    GUIElement otherInteractionElem = ((InteractionTask) task).getGUIElement();
+    Interaction otherInteraction = ((InteractionTask) task).getInteraction();
+    
+    if ((((mGUIElement == null) && (otherInteractionElem == null)) ||
+         ((mGUIElement != null) && (mGUIElement.equals(otherInteractionElem)))) &&
+        (((mInteraction == null) && (otherInteraction == null)) ||
+         ((mInteraction != null) && (mInteraction.equals(otherInteraction)))))
+    {
+      return true;
+    }
+    
+    return false;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.harms.tasktrees.TreeNode#clone()
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public InteractionTaskImpl clone()
+  {
+    // GUI element and interaction are unchangeable and do not need to be cloned
+    return (InteractionTaskImpl) super.clone();
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeimpl/IterationImpl.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeimpl/IterationImpl.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeimpl/IterationImpl.java	(revision 540)
@@ -0,0 +1,74 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: Iteration.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 19.02.2012 $
+// Project   : TaskTreeCreator
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.treeimpl;
+
+import de.ugoe.cs.quest.tasktrees.treeifc.Iteration;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNode;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 19.02.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public class IterationImpl extends TaskTreeNodeImpl implements Iteration
+{
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  IterationImpl()
+  {
+    super("Iteration");
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.ugoe.cs.tasktree.treeifc.TaskTreeNode#addChild(TaskTreeNode)
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public void addChild(TaskTreeNode child)
+  {
+    // adding more children is not allowed
+    throw new UnsupportedOperationException();
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param selection
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  public void setChild(TaskTreeNode child)
+  {
+    if (super.getChildren().size() > 0)
+    {
+      super.removeChild(0);
+    }
+    super.addChild(child);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see java.lang.Object#clone()
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public IterationImpl clone()
+  {
+    return (IterationImpl) super.clone();
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeimpl/NodeInfoImpl.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeimpl/NodeInfoImpl.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeimpl/NodeInfoImpl.java	(revision 540)
@@ -0,0 +1,114 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: NodeInfo.java,v $
+// Version   : $Revision: 0.0 $  $Author: Patrick $  $Date: 05.11.2011 19:24:14 $
+// Project   : TestTreePerformanceTest
+// Creation  : 2011 by Patrick
+// Copyright : Patrick Harms, 2011
+//-------------------------------------------------------------------------------------------------
+
+package de.ugoe.cs.quest.tasktrees.treeimpl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import de.ugoe.cs.quest.tasktrees.treeifc.NodeInfo;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNode;
+
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ *
+ * @version $Revision: $ $Date: $
+ * @author  2011, last modified by $Author: $
+ */
+//-------------------------------------------------------------------------------------------------
+public class NodeInfoImpl implements NodeInfo
+{
+  /** */
+  private TaskTreeNode mTask;
+  
+  /** */
+  private long mLastUpdate;
+
+  /** */
+  private List<TaskTreeNode> mParentNodes = new ArrayList<TaskTreeNode>();
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * @param node 
+   */
+  //-----------------------------------------------------------------------------------------------
+  NodeInfoImpl(TaskTreeNode task)
+  {
+    mTask = task;
+    mLastUpdate = System.currentTimeMillis();
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.ugoe.cs.tasktree.treeifc.NodeInfo#getTask()
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public TaskTreeNode getTask()
+  {
+    return mTask;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.ugoe.cs.tasktree.treeimpl.NodeInfo#getNoOfOccurencesInTree()
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public int getNoOfOccurencesInTree()
+  {
+    return mParentNodes.size();
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.ugoe.cs.tasktree.treeimpl.NodeInfo#getLastUpdate()
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public long getLastUpdate()
+  {
+    return mLastUpdate;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  void addParent(TaskTreeNode parent)
+  {
+    mParentNodes.add(parent);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  void removeParent(TaskTreeNode parent)
+  {
+    mParentNodes.remove(parent);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see java.lang.Object#toString()
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public synchronized String toString()
+  {
+    return "NodeInfo(" + mTask + ", " + mParentNodes.size() + " parents)";
+  }
+  
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeimpl/SelectionImpl.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeimpl/SelectionImpl.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeimpl/SelectionImpl.java	(revision 540)
@@ -0,0 +1,46 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: Selection.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 19.02.2012 $
+// Project   : TaskTreeCreator
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.treeimpl;
+
+import de.ugoe.cs.quest.tasktrees.treeifc.Selection;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 19.02.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public class SelectionImpl extends TaskTreeNodeImpl implements Selection
+{
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param name
+   */
+  //-----------------------------------------------------------------------------------------------
+  SelectionImpl()
+  {
+    super("Selection");
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see java.lang.Object#clone()
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public SelectionImpl clone()
+  {
+    return (SelectionImpl) super.clone();
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeimpl/SequenceImpl.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeimpl/SequenceImpl.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeimpl/SequenceImpl.java	(revision 540)
@@ -0,0 +1,57 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: Sequence.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 19.02.2012 $
+// Project   : TaskTreeCreator
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.treeimpl;
+
+import de.ugoe.cs.quest.tasktrees.treeifc.Sequence;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 19.02.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public class SequenceImpl extends TaskTreeNodeImpl implements Sequence
+{
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param name
+   */
+  //-----------------------------------------------------------------------------------------------
+  SequenceImpl()
+  {
+    super("Sequence");
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param name
+   */
+  //-----------------------------------------------------------------------------------------------
+  SequenceImpl(String name)
+  {
+    super(name);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.ugoe.cs.tasktree.treeimpl.TaskTreeNodeImpl#clone()
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public SequenceImpl clone()
+  {
+    return (SequenceImpl) super.clone();
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeimpl/TaskTreeBuilderImpl.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeimpl/TaskTreeBuilderImpl.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeimpl/TaskTreeBuilderImpl.java	(revision 540)
@@ -0,0 +1,221 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: TaskTreeBuilderImpl.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 21.02.2012 $
+// Project   : TaskTreeCreator
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.treeimpl;
+
+import de.ugoe.cs.quest.tasktrees.treeifc.Iteration;
+import de.ugoe.cs.quest.tasktrees.treeifc.Selection;
+import de.ugoe.cs.quest.tasktrees.treeifc.Sequence;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeBuilder;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNode;
+import de.ugoe.cs.quest.tasktrees.treeifc.TextInputInteractionTask;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 21.02.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public class TaskTreeBuilderImpl implements TaskTreeBuilder
+{
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.ugoe.cs.tasktree.treeifc.TaskTreeBuilder#addChild(Sequence, TaskTreeNode)
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public void addChild(Sequence parent, TaskTreeNode child)
+  {
+    if (!(parent instanceof SequenceImpl))
+    {
+      throw new IllegalArgumentException
+        ("illegal type of task tree node provided: " + parent.getClass());
+    }
+
+    addChildInternal(parent, -1, child);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.ugoe.cs.tasktree.treeifc.TaskTreeBuilder#addChild(Sequence, int, TaskTreeNode)
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public void addChild(Sequence parent, int index, TaskTreeNode child)
+  {
+    if (!(parent instanceof SequenceImpl))
+    {
+      throw new IllegalArgumentException
+        ("illegal type of task tree node provided: " + parent.getClass());
+    }
+
+    addChildInternal(parent, index, child);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.ugoe.cs.tasktree.treeifc.TaskTreeBuilder#addChild(Selection, TaskTreeNode)
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public void addChild(Selection parent, TaskTreeNode child)
+  {
+    if (!(parent instanceof SelectionImpl))
+    {
+      throw new IllegalArgumentException
+        ("illegal type of task tree node provided: " + parent.getClass());
+    }
+
+    addChildInternal(parent, -1, child);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.ugoe.cs.tasktree.treeifc.TaskTreeBuilder#addChild(de.ugoe.cs.tasktree.treeifc.TextInputInteractionTask, de.ugoe.cs.tasktree.treeifc.TaskTreeNode)
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public void addChild(TextInputInteractionTask parent, TaskTreeNode child)
+  {
+    if (!(parent instanceof TextInputInteractionTaskImpl))
+    {
+      throw new IllegalArgumentException
+        ("illegal type of task tree node provided: " + parent.getClass());
+    }
+
+    addChildInternal(parent, -1, child);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.ugoe.cs.tasktree.treeifc.TaskTreeBuilder#setChild(Iteration, TaskTreeNode)
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public void setChild(Iteration iteration, TaskTreeNode newChild)
+  {
+    if (!(iteration instanceof IterationImpl))
+    {
+      throw new IllegalArgumentException
+        ("illegal type of iteration provided: " + iteration.getClass());
+    }
+
+    if (!(newChild instanceof TaskTreeNodeImpl))
+    {
+      throw new IllegalArgumentException
+        ("illegal type of task tree node provided: " + newChild.getClass());
+    }
+    
+    ((IterationImpl) iteration).setChild(determineNode(newChild));
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.ugoe.cs.tasktree.treeifc.TaskTreeBuilder#removeChild(Sequence, int)
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public void removeChild(Sequence parent, int index)
+  {
+    if (!(parent instanceof TaskTreeNodeImpl))
+    {
+      throw new IllegalArgumentException
+        ("illegal type of task tree node provided: " + parent.getClass());
+    }
+
+    ((TaskTreeNodeImpl) parent).removeChild(index);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.ugoe.cs.tasktree.treeifc.TaskTreeBuilder#removeChild(Selection, TaskTreeNode)
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public void removeChild(Selection parent, TaskTreeNode child)
+  {
+    if (!(parent instanceof TaskTreeNodeImpl))
+    {
+      throw new IllegalArgumentException
+        ("illegal type of task tree node provided: " + parent.getClass());
+    }
+
+    for (int i = 0; i < parent.getChildren().size(); i++)
+    {
+      if ((parent.getChildren().get(i) == child) ||
+          ((parent.getChildren().get(i) != null) && (parent.getChildren().get(i).equals(child))))
+      {
+        ((TaskTreeNodeImpl) parent).removeChild(i);
+        break;
+      }
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.ugoe.cs.tasktree.treeifc.TaskTreeBuilder#setDescription(TaskTreeNode, String)
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public void setDescription(TaskTreeNode parent, String description)
+  {
+    if (!(parent instanceof TaskTreeNodeImpl))
+    {
+      throw new IllegalArgumentException
+        ("illegal type of task tree node provided: " + parent.getClass());
+    }
+
+    ((TaskTreeNodeImpl) parent).setDescription(description);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * 
+   */
+  //-----------------------------------------------------------------------------------------------
+  private void addChildInternal(TaskTreeNode parent, int index, TaskTreeNode child)
+  {
+    if (!(child instanceof TaskTreeNodeImpl))
+    {
+      throw new IllegalArgumentException
+        ("illegal type of task tree node provided: " + child.getClass());
+    }
+    
+    if (index > -1)
+    {
+      ((TaskTreeNodeImpl) parent).addChild(index, determineNode(child));
+    }
+    else
+    {
+      ((TaskTreeNodeImpl) parent).addChild(determineNode(child));
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param newChild
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  private TaskTreeNode determineNode(TaskTreeNode newNode)
+  {
+    return newNode;
+    /*TaskTreeNode node = mTaskMap.get(newNode);
+    if (node == null)
+    {
+      node = newNode;
+      mTaskMap.put(node, node);
+    }
+    
+    return node;*/
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeimpl/TaskTreeImpl.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeimpl/TaskTreeImpl.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeimpl/TaskTreeImpl.java	(revision 540)
@@ -0,0 +1,131 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: TaskTree.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 21.02.2012 $
+// Project   : TaskTreeCreator
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.treeimpl;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import de.ugoe.cs.quest.tasktrees.treeifc.NodeInfo;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTree;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNode;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 21.02.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public class TaskTreeImpl implements TaskTree
+{
+  /** the map of nodes */
+  private Map<TaskTreeNode, NodeInfo> mTaskMap;
+  
+  /** the root node of the task tree */
+  private TaskTreeNode mRootNode;
+  
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  TaskTreeImpl(TaskTreeNode rootNode)
+  {
+    mRootNode = rootNode;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.ugoe.cs.tasktree.treeifc.TaskTree#getRoot()
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public TaskTreeNode getRoot()
+  {
+    return mRootNode;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.ugoe.cs.tasktree.treeifc.TaskTree#getTaskMap()
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public synchronized Map<TaskTreeNode, NodeInfo> getTaskMap()
+  {
+    if (mTaskMap == null)
+    {
+      mTaskMap = new HashMap<TaskTreeNode, NodeInfo>();
+      addNodeToMap(mRootNode, null);
+    }
+    return mTaskMap;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param rootNode
+   */
+  //-----------------------------------------------------------------------------------------------
+  private void addNodeToMap(TaskTreeNode node, TaskTreeNode parent)
+  {
+    NodeInfoImpl nodeInfo = (NodeInfoImpl) mTaskMap.get(node);
+    
+    if (nodeInfo == null)
+    {
+      nodeInfo = new NodeInfoImpl(node);
+      mTaskMap.put(node, nodeInfo);
+    }
+    
+    if (parent != null)
+    {
+      // through first removing an existing parent it is assured, that a parent is recorded
+      // only once. This is needed, because parent may be reused in a tree as well, but we always
+      // iterate the whole tree
+      nodeInfo.removeParent(parent);
+      nodeInfo.addParent(parent);
+    }
+    
+    for (TaskTreeNode child : node.getChildren())
+    {
+      addNodeToMap(child, node);
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see java.lang.Object#clone()
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public TaskTreeImpl clone()
+  {
+    TaskTreeImpl clone = null;
+    try
+    {
+      clone = (TaskTreeImpl) super.clone();
+      
+      clone.mRootNode = mRootNode.clone();
+      
+      // the clone will create the task map itself, when it is first retrieved
+      clone.mTaskMap = null;
+      
+    }
+    catch (CloneNotSupportedException e)
+    {
+      // this should never happen. Therefore simply dump the exception
+      e.printStackTrace();
+    }
+    
+    return clone;
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeimpl/TaskTreeNodeFactoryImpl.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeimpl/TaskTreeNodeFactoryImpl.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeimpl/TaskTreeNodeFactoryImpl.java	(revision 540)
@@ -0,0 +1,99 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: TaskTreeNodeFactoryImpl.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 21.02.2012 $
+// Project   : TaskTreeCreator
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.treeimpl;
+
+import de.ugoe.cs.quest.eventcore.guimodel.GUIElement;
+import de.ugoe.cs.quest.eventcore.userinteraction.Interaction;
+import de.ugoe.cs.quest.tasktrees.treeifc.InteractionTask;
+import de.ugoe.cs.quest.tasktrees.treeifc.Iteration;
+import de.ugoe.cs.quest.tasktrees.treeifc.Selection;
+import de.ugoe.cs.quest.tasktrees.treeifc.Sequence;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTree;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNode;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNodeFactory;
+import de.ugoe.cs.quest.tasktrees.treeifc.TextInputInteractionTask;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 21.02.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public class TaskTreeNodeFactoryImpl implements TaskTreeNodeFactory
+{
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see TaskTreeNodeFactory#createNewInteractionTask(GUIElement, Interaction)
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public InteractionTask createNewInteractionTask(GUIElement  guiElement,
+                                                  Interaction interaction)
+  {
+    return new InteractionTaskImpl(guiElement, interaction);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.ugoe.cs.tasktree.treeifc.TaskTreeNodeFactory#createNewSequence()
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public Sequence createNewSequence()
+  {
+    return new SequenceImpl();
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.ugoe.cs.tasktree.treeifc.TaskTreeNodeFactory#createNewTextInputInteractionTask()
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public TextInputInteractionTask createNewTextInputInteractionTask(GUIElement guiElement)
+  {
+    return new TextInputInteractionTaskImpl(guiElement);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.ugoe.cs.tasktree.treeifc.TaskTreeNodeFactory#createNewIteration()
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public Iteration createNewIteration()
+  {
+    return new IterationImpl();
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.ugoe.cs.tasktree.treeifc.TaskTreeNodeFactory#createNewSelection()
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public Selection createNewSelection()
+  {
+    return new SelectionImpl();
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.ugoe.cs.tasktree.treeifc.TaskTreeNodeFactory#createTaskTree(de.ugoe.cs.tasktree.treeifc.TaskTreeNode)
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public TaskTree createTaskTree(TaskTreeNode root)
+  {
+    return new TaskTreeImpl(root);
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeimpl/TaskTreeNodeImpl.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeimpl/TaskTreeNodeImpl.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeimpl/TaskTreeNodeImpl.java	(revision 540)
@@ -0,0 +1,277 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: TreeNode.java,v $
+// Version   : $Revision: 0.0 $  $Author: Patrick $  $Date: 06.11.2011 11:00:46 $
+// Project   : TaskTreePerformanceTest
+// Creation  : 2011 by Patrick
+// Copyright : Patrick Harms, 2011
+//-------------------------------------------------------------------------------------------------
+
+package de.ugoe.cs.quest.tasktrees.treeimpl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNode;
+
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ *
+ * @version $Revision: $ $Date: $
+ * @author  2011, last modified by $Author: $
+ */
+//-------------------------------------------------------------------------------------------------
+public class TaskTreeNodeImpl implements TaskTreeNode
+{
+  /** */
+  private static int sTemporalId = 0;
+
+  /** */
+  private String mName;
+
+  /** */
+  private String mDescription;
+  
+  /** */
+  private int mId;
+  
+  /** children */
+  private List<TaskTreeNode> mChildren;
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   */
+  //-----------------------------------------------------------------------------------------------
+  TaskTreeNodeImpl(String name)
+  {
+    mName = name;
+    mId = getNewId();
+  }
+  
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  private static synchronized int getNewId()
+  {
+    if (sTemporalId == Integer.MAX_VALUE)
+    {
+      sTemporalId = 0;
+    }
+    
+    return sTemporalId++;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * @return Returns the name.
+   */
+  //-----------------------------------------------------------------------------------------------
+  public String getName()
+  {
+    return mName;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.ugoe.cs.tasktree.treeifc.TaskTreeNode#getDescription()
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public String getDescription()
+  {
+    return mDescription;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   */
+  //-----------------------------------------------------------------------------------------------
+  public synchronized List<TaskTreeNode> getChildren()
+  {
+    if ((mChildren == null) || (mChildren.size() == 0))
+    {
+      return new ArrayList<TaskTreeNode>();
+    }
+    
+    return mChildren.subList(0, mChildren.size());
+  }
+  
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNode#equals(TaskTreeNode)
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public boolean equals(TaskTreeNode taskTreeNode)
+  {
+    if (!this.getClass().isInstance(taskTreeNode))
+    {
+      return false;
+    }
+    
+    if (taskTreeNode.hashCode() != hashCode())
+    {
+      return false;
+    }
+    
+    TaskTreeNodeImpl other = (TaskTreeNodeImpl) taskTreeNode;
+    
+    if (mId != other.mId)
+    {
+      return false;
+    }
+    
+    if (!mName.equals(other.mName))
+    {
+      return false;
+    }
+    
+    synchronized (other)
+    {
+      if (mChildren == null)
+      {
+        return (other.mChildren == null);
+      }
+      else if (other.mChildren == null)
+      {
+        return (mChildren == null);
+      }
+      else if (other.mChildren.size() != mChildren.size())
+      {
+        return false;
+      }
+      
+      for (int i = 0; i < mChildren.size(); i++)
+      {
+        if (!mChildren.get(i).equals(other.mChildren.get(i)))
+        {
+          return false;
+        }
+      }
+    }
+
+    return true;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see java.lang.Object#hashCode()
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public synchronized int hashCode()
+  {
+    return getClass().getSimpleName().hashCode();
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see java.lang.Object#toString()
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public synchronized String toString()
+  {
+    if (mChildren == null)
+    {
+      return mName + "(" + mId + ")";
+    }
+    else
+    {
+      return mName + "(" + mId + ", " + mChildren.size() + " children)";
+    }
+  }
+  
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param i
+   * @return 
+   */
+  //-----------------------------------------------------------------------------------------------
+  void setDescription(String description)
+  {
+    mDescription = description;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   */
+  //-----------------------------------------------------------------------------------------------
+  synchronized void addChild(TaskTreeNode child)
+  {
+    if (mChildren == null)
+    {
+      mChildren = new ArrayList<TaskTreeNode>();
+    }
+    
+    mChildren.add(child);
+  }
+  
+  //-----------------------------------------------------------------------------------------------
+  /**
+   */
+  //-----------------------------------------------------------------------------------------------
+  synchronized void addChild(int index, TaskTreeNode child)
+  {
+    if (mChildren == null)
+    {
+      mChildren = new ArrayList<TaskTreeNode>();
+    }
+    
+    mChildren.add(index, child);
+  }
+  
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param i
+   * @return 
+   */
+  //-----------------------------------------------------------------------------------------------
+  synchronized TaskTreeNode removeChild(int index)
+  {
+    return mChildren.remove(index);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see java.lang.Object#clone()
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public TaskTreeNode clone()
+  {
+    TaskTreeNodeImpl clone = null;
+    try
+    {
+      clone = (TaskTreeNodeImpl) super.clone();
+      
+      if (mChildren != null)
+      {
+        clone.mChildren = new ArrayList<TaskTreeNode>();
+      
+        for (TaskTreeNode child : mChildren)
+        {
+          clone.mChildren.add(child.clone());
+        }
+      }
+      
+    }
+    catch (CloneNotSupportedException e)
+    {
+      // this should never happen. Therefore simply dump the exception
+      e.printStackTrace();
+    }
+    
+    return clone;
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeimpl/TextInputInteractionTaskImpl.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeimpl/TextInputInteractionTaskImpl.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-tasktrees/src/main/java/de/ugoe/cs/quest/tasktrees/treeimpl/TextInputInteractionTaskImpl.java	(revision 540)
@@ -0,0 +1,94 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: TextInputSequenceImpl.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 10.06.2012 $
+// Project   : TaskTreeImpl
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.tasktrees.treeimpl;
+
+import de.ugoe.cs.quest.eventcore.guimodel.GUIElement;
+import de.ugoe.cs.quest.eventcore.userinteraction.TextInput;
+import de.ugoe.cs.quest.tasktrees.treeifc.TextInputInteractionTask;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 10.06.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public class TextInputInteractionTaskImpl extends InteractionTaskImpl
+  implements TextInputInteractionTask
+{
+
+  /** the text, that was finally entered in this sequence without all backspaces, etc. */
+  private String mEnteredText;
+  
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param name
+   */
+  //-----------------------------------------------------------------------------------------------
+  TextInputInteractionTaskImpl(GUIElement guiElement)
+  {
+    super(guiElement, new TextInput());
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.ugoe.cs.tasktree.treeimpl.TaskTreeNodeImpl#clone()
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public TextInputInteractionTaskImpl clone()
+  {
+    // entered text is unchangeable and does not need to be cloned
+    return (TextInputInteractionTaskImpl) super.clone();
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.ugoe.cs.tasktree.treeifc.TextInputSequence#getEnteredText()
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public String getEnteredText()
+  {
+    return mEnteredText;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.ugoe.cs.tasktree.treeifc.TextInputSequence#setEnteredText(java.lang.String)
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public void setEnteredText(String text)
+  {
+    mEnteredText = text;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see java.lang.Object#toString()
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public synchronized String toString()
+  {
+    if (super.getChildren() == null)
+    {
+      return super.getName();
+    }
+    else
+    {
+      return "TextInputInteraction(\"" + mEnteredText + "\", " + super.getChildren().size() +
+        " children)";
+    }
+  }
+  
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-testgeneration/.classpath
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-testgeneration/.classpath	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-testgeneration/.classpath	(revision 540)
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/classes" path="src/main/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
Index: /tags/quest-pre-eventrefactoring/quest-core-testgeneration/.project
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-testgeneration/.project	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-testgeneration/.project	(revision 540)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>quest-core-testgeneration</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
Index: /tags/quest-pre-eventrefactoring/quest-core-testgeneration/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-testgeneration/.settings/org.eclipse.jdt.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-testgeneration/.settings/org.eclipse.jdt.core.prefs	(revision 540)
@@ -0,0 +1,5 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.6
Index: /tags/quest-pre-eventrefactoring/quest-core-testgeneration/.settings/org.eclipse.m2e.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-testgeneration/.settings/org.eclipse.m2e.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-testgeneration/.settings/org.eclipse.m2e.core.prefs	(revision 540)
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
Index: /tags/quest-pre-eventrefactoring/quest-core-testgeneration/pom.xml
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-testgeneration/pom.xml	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-testgeneration/pom.xml	(revision 540)
@@ -0,0 +1,39 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>de.ugoe.cs.quest</groupId>
+  <artifactId>quest-core-testgeneration</artifactId>
+  <version>0.0.1-SNAPSHOT</version>
+  <name>quest-core-testgeneration</name>
+	<scm>
+		<url>https://quest.informatik.uni-goettingen.de/svn/quest/trunk/quest-core-testgeneration</url>
+	</scm>
+	<dependencies>
+		<dependency>
+			<groupId>de.ugoe.cs.quest</groupId>
+			<artifactId>quest-core-events</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+		</dependency>
+		<dependency>
+			<groupId>de.ugoe.cs.quest</groupId>
+			<artifactId>quest-core-usageprofiles</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+		</dependency>
+		<dependency>
+			<groupId>de.ugoe.cs.quest</groupId>
+			<artifactId>quest-core-coverage</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+		</dependency>
+	</dependencies>
+	<build>
+		<plugins>
+			<plugin>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>2.3.2</version>
+				<configuration>
+					<source>1.6</source>
+					<target>1.6</target>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+</project>
Index: /tags/quest-pre-eventrefactoring/quest-core-testgeneration/src/main/java/de/ugoe/cs/quest/testgeneration/DrawFromAllSequencesGenerator.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-testgeneration/src/main/java/de/ugoe/cs/quest/testgeneration/DrawFromAllSequencesGenerator.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-testgeneration/src/main/java/de/ugoe/cs/quest/testgeneration/DrawFromAllSequencesGenerator.java	(revision 540)
@@ -0,0 +1,182 @@
+package de.ugoe.cs.quest.testgeneration;
+
+import java.security.InvalidParameterException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Random;
+import java.util.Set;
+
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.usageprofiles.IStochasticProcess;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Generates a test suite by drawing from all possible sequences of a fixed
+ * length according to the probabilities of the sequences in a
+ * {@link IStochasticProcess}.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class DrawFromAllSequencesGenerator {
+
+	/**
+	 * <p>
+	 * Number of sequences in the test suite.
+	 * </p>
+	 */
+	private final int numSequences;
+
+	/**
+	 * <p>
+	 * Minimal length of a test sequence.
+	 * </p>
+	 */
+	private final int minLength;
+
+	/**
+	 * <p>
+	 * Maximal length of a test sequence.
+	 * </p>
+	 */
+	private final int maxLength;
+
+	/**
+	 * <p>
+	 * In case this member is true, only test cases that end in the global end
+	 * event {@link Event#ENDEVENT} are generated. If it is false, the end event
+	 * can be any event.
+	 * </p>
+	 */
+	private final boolean validEnd;
+
+	/**
+	 * <p>
+	 * If this member is true, the generated test suite contains all possible
+	 * sequences and {@link #numSequences} is ignored.
+	 * </p>
+	 */
+	private final boolean generateAll;
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new DrawFromAllSequencesGenerator and ensures the
+	 * validity of the parameters:
+	 * <ul>
+	 * <li>numSequences must at least be 1
+	 * <li>maxLength must at least be 1
+	 * <li>minLength must be less than or equal to maxLength
+	 * </ul>
+	 * If one of these conditions is violated an
+	 * {@link InvalidParameterException} is thrown.
+	 * </p>
+	 * 
+	 * @param numSequences
+	 *            number of sequences desired for the test suite
+	 * @param minLength
+	 *            minimal length of a test sequence
+	 * @param maxLength
+	 *            maximal length of a test sequence
+	 * @param validEnd
+	 *            defines if test cases have to end with the global end event
+	 *            {@link Event#ENDEVENT} (see {@link #validEnd})
+	 * @param generateAll
+	 *            if this parameter is true, the test suite contains all
+	 *            possible sequences and numSequences is ignored
+	 */
+	public DrawFromAllSequencesGenerator(int numSequences, int minLength,
+			int maxLength, boolean validEnd, boolean generateAll) {
+		// check validity of the parameters
+		if (numSequences < 1) {
+			throw new InvalidParameterException(
+					"number of sequences must be at least 1 but is "
+							+ numSequences);
+		}
+		if (maxLength < 1) {
+			throw new InvalidParameterException(
+					"maximal allowed length of test cases must be at least 1 but is "
+							+ maxLength);
+		}
+		if (minLength > maxLength) {
+			throw new InvalidParameterException(
+					"minimal allowed length of test cases must be less than or equal to the maximal allowed length (min length: "
+							+ minLength + " ; max length: " + maxLength + ")");
+		}
+		this.numSequences = numSequences;
+		this.minLength = minLength;
+		this.maxLength = maxLength;
+		this.validEnd = validEnd;
+		this.generateAll = generateAll;
+	}
+
+	/**
+	 * <p>
+	 * Generates a test suite by drawing from all possible sequences with valid
+	 * lengths.
+	 * </p>
+	 * 
+	 * @param model
+	 *            model used to determine the probability of each possible
+	 *            sequence
+	 * @return the test suite
+	 */
+	public Collection<List<? extends Event<?>>> generateTestSuite(
+			IStochasticProcess model) {
+		if (model == null) {
+			throw new InvalidParameterException("model must not be null!");
+		}
+
+		Collection<List<? extends Event<?>>> sequences = new LinkedHashSet<List<? extends Event<?>>>();
+		for (int length = minLength; length <= maxLength; length++) {
+			if (validEnd) {
+				sequences.addAll(model.generateValidSequences(length + 2));
+			} else {
+				sequences.addAll(model.generateSequences(length + 1, true));
+			}
+		}
+		Console.traceln("" + sequences.size() + " possible");
+		if (!generateAll && numSequences < sequences.size()) {
+			List<Double> probabilities = new ArrayList<Double>(sequences.size());
+			double probSum = 0.0;
+			for (List<? extends Event<?>> sequence : sequences) {
+				double prob = model.getProbability(sequence);
+				probabilities.add(prob);
+				probSum += prob;
+			}
+			Set<Integer> drawnSequences = new HashSet<Integer>(numSequences);
+			Random r = new Random();
+			while (drawnSequences.size() < numSequences) {
+				double randVal = r.nextDouble() * probSum;
+				double sum = 0.0d;
+				int index = -1;
+				while (sum < randVal) {
+					index++;
+					double currentProb = probabilities.get(index);
+					sum += currentProb;
+				}
+				if (!drawnSequences.contains(index)) {
+					drawnSequences.add(index);
+					probSum -= probabilities.get(index);
+					probabilities.set(index, 0.0d);
+				}
+			}
+			Collection<List<? extends Event<?>>> retainedSequences = new LinkedList<List<? extends Event<?>>>();
+			int index = 0;
+			for (List<? extends Event<?>> sequence : sequences) {
+				if (drawnSequences.contains(index)) {
+					retainedSequences.add(sequence);
+				}
+				index++;
+			}
+			sequences = retainedSequences;
+		}
+		return sequences;
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-testgeneration/src/main/java/de/ugoe/cs/quest/testgeneration/HybridGenerator.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-testgeneration/src/main/java/de/ugoe/cs/quest/testgeneration/HybridGenerator.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-testgeneration/src/main/java/de/ugoe/cs/quest/testgeneration/HybridGenerator.java	(revision 540)
@@ -0,0 +1,219 @@
+package de.ugoe.cs.quest.testgeneration;
+
+import java.security.InvalidParameterException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Random;
+
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.usageprofiles.IStochasticProcess;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Generates a test suite with a hybrid approach that is a mixture of random
+ * walks and drawing from all possible sequences.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class HybridGenerator {
+
+	/**
+	 * <p>
+	 * Number of sequences in the test suite.
+	 * </p>
+	 */
+	private final int numSequences;
+
+	/**
+	 * <p>
+	 * Length of a test sequence.
+	 * </p>
+	 */
+	private final int length;
+
+	/**
+	 * <p>
+	 * Maximal length where it is possible to generate all sequences and draw
+	 * from them.
+	 * </p>
+	 */
+	private final int maxLengthAll;
+
+	/**
+	 * <p>
+	 * In case this member is true, only test cases that end in the global end
+	 * event {@link Event#ENDEVENT} are generated. If it is false, the end event
+	 * can be any event.
+	 * </p>
+	 */
+	private final boolean validEnd;
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new HybridGenerator and ensures the validity of
+	 * the parameters:
+	 * <ul>
+	 * <li>numSequences must at least be 1
+	 * <li>length must be at least 1
+	 * </ul>
+	 * If one of these conditions is violated an
+	 * {@link InvalidParameterException} is thrown.
+	 * </p>
+	 * 
+	 * @param numSequences
+	 *            number of sequences desired for the test suite
+	 * @param length
+	 *            length of a test sequence
+	 * @param maxLengthAll
+	 *            maximal length where it is possible to generate all sequences
+	 *            and draw from them
+	 * @param validEnd
+	 *            defines if test cases have to end with the global end event
+	 *            {@link Event#ENDEVENT} (see {@link #validEnd})
+	 */
+	public HybridGenerator(int numSequences, int length, int maxLengthAll,
+			boolean validEnd) {
+		// check validity of the parameters
+		if (numSequences < 1) {
+			throw new InvalidParameterException(
+					"number of sequences must be at least 1 but is "
+							+ numSequences);
+		}
+		if (length < 1) {
+			throw new InvalidParameterException(
+					"length of test cases must be at least 1 but is " + length);
+		}
+		this.numSequences = numSequences;
+		this.length = length;
+		this.maxLengthAll = maxLengthAll;
+		this.validEnd = validEnd;
+	}
+
+	/**
+	 * <p>
+	 * Generates a test suite with a hybrid approach that is a mixture of random
+	 * walks and drawing from all possible sequences
+	 * </p>
+	 * 
+	 * @param model
+	 *            model used to determine the probability of each possible
+	 *            sequence
+	 * @return the test suite
+	 */
+	public Collection<List<? extends Event<?>>> generateTestSuite(
+			IStochasticProcess model) {
+		if (model == null) {
+			throw new InvalidParameterException("model must not be null!");
+		}
+		
+		Collection<List<? extends Event<?>>> sequences = new LinkedHashSet<List<? extends Event<?>>>();
+
+		List<List<? extends Event<?>>> seqsTmp = new ArrayList<List<? extends Event<?>>>(
+				model.generateSequences(maxLengthAll + 1, true));
+
+		Console.traceln("" + seqsTmp.size() + " of length " + maxLengthAll
+				+ " possible");
+		List<Double> probabilities = new ArrayList<Double>(seqsTmp.size());
+		double probSum = 0.0;
+		for (List<? extends Event<?>> sequence : seqsTmp) {
+			double prob = model.getProbability(sequence);
+			probabilities.add(prob);
+			probSum += prob;
+		}
+
+		Random r = new Random();
+		int j = 0;
+		while (sequences.size() < numSequences && j <= numSequences * 100) {
+			j++;
+			double randVal = r.nextDouble() * probSum;
+			double sum = 0.0d;
+			int index = -1;
+			while (sum < randVal) {
+				index++;
+				double currentProb = probabilities.get(index);
+				sum += currentProb;
+			}
+			List<? extends Event<?>> seqTmp = seqsTmp.get(index);
+			if (!Event.ENDEVENT.equals(seqTmp.get(seqTmp.size() - 1))) {
+				List<? extends Event<?>> sequence;
+				if (validEnd) {
+					sequence = finishSequence(seqTmp, model, length + 2,
+							validEnd);
+					if( sequence!= null && sequence.size()!=length+2 ) {
+						sequence = null;
+					}
+				} else {
+					sequence = finishSequence(seqTmp, model, length + 1,
+							validEnd);
+					if( sequence!= null && sequence.size()!=length+1 ) {
+						sequence = null;
+					}
+				}
+				if( sequence!=null ) {
+					sequences.add(sequence);
+				}
+			}
+		}
+		
+		return sequences;
+	}
+
+	/**
+	 * <p>
+	 * Finishes a sequence with a random walk.
+	 * </p>
+	 * 
+	 * @param sequence
+	 *            sequence to be finished
+	 * @param model
+	 *            model used for the random walk
+	 * @param length
+	 *            desired length of the sequence
+	 * @param validEnd
+	 *            if the sequence should end in {@link Event#ENDEVENT}.
+	 * @return finished sequence of the desired length
+	 */
+	private List<? extends Event<?>> finishSequence(
+			List<? extends Event<?>> sequence, IStochasticProcess model,
+			int length, boolean validEnd) {
+		Random r = new Random();
+		boolean endFound = false;
+		List<Event<?>> sequenceCopy = new LinkedList<Event<?>>(sequence);
+		final int maxIter = 30000;
+		int iter = 0;
+		while (!endFound && iter < maxIter) {
+			iter++;
+			sequenceCopy = new LinkedList<Event<?>>(sequence);
+			while (!endFound && sequenceCopy.size() <= length) {
+				double randVal = r.nextDouble();
+				double probSum = 0.0;
+				for (Event<?> symbol : model.getEvents()) {
+					probSum += model.getProbability(sequenceCopy, symbol);
+					if (probSum >= randVal) {
+						if (!(Event.STARTEVENT.equals(symbol) || (!validEnd && Event.ENDEVENT
+								.equals(symbol)))) {
+							// only add the symbol the sequence if it is not
+							// START
+							// or END
+							sequenceCopy.add(symbol);
+						}
+						endFound = Event.ENDEVENT.equals(symbol)
+								|| (!validEnd && sequenceCopy.size() == length);
+						break;
+					}
+				}
+			}
+		}
+		if (iter == maxIter) {
+			return null;
+		}
+		return sequenceCopy;
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-testgeneration/src/main/java/de/ugoe/cs/quest/testgeneration/RandomWalkGenerator.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-testgeneration/src/main/java/de/ugoe/cs/quest/testgeneration/RandomWalkGenerator.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-testgeneration/src/main/java/de/ugoe/cs/quest/testgeneration/RandomWalkGenerator.java	(revision 540)
@@ -0,0 +1,181 @@
+package de.ugoe.cs.quest.testgeneration;
+
+import java.security.InvalidParameterException;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.usageprofiles.IStochasticProcess;
+
+/**
+ * <p>
+ * Generates a test suite by randomly walking an {@link IStochasticProcess}.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class RandomWalkGenerator {
+
+	/**
+	 * <p>
+	 * Number of sequences in the test suite.
+	 * </p>
+	 */
+	private final int numSequences;
+
+	/**
+	 * <p>
+	 * Minimal length of a test sequence.
+	 * </p>
+	 */
+	private final int minLength;
+
+	/**
+	 * <p>
+	 * Maximal length of a test sequence.
+	 * </p>
+	 */
+	private final int maxLength;
+
+	/**
+	 * <p>
+	 * In case this member is true, only test cases that end in the global end
+	 * event {@link Event#ENDEVENT} are generated. If it is false, the end event
+	 * can be any event.
+	 * </p>
+	 */
+	private final boolean validEnd;
+
+	/**
+	 * <p>
+	 * Maximal number of random walks performed before aborting the test case
+	 * generation and returning a test suite with less than
+	 * {@link #numSequences} test cases. This can happen if too many generated
+	 * random walks have to be discarded because their length is not between
+	 * {@link #minLength} and {@link #maxLength}.
+	 * </p>
+	 */
+	private final long maxIter;
+
+	/**
+	 * <p>
+	 * Actual number of random walks performed to generate the test suite.
+	 * </p>
+	 */
+	private long actualIter = -1;
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new RandomWalkGenerator and ensures the validity
+	 * of the parameters:
+	 * <ul>
+	 * <li>numSequences must at least be 1
+	 * <li>maxLength must at least be 1
+	 * <li>minLength must be less than or equal to maxLength
+	 * <li>maxIter must be greater than or equal to numSequences
+	 * </ul>
+	 * If one of these conditions is violated an
+	 * {@link InvalidParameterException} is thrown.
+	 * </p>
+	 * 
+	 * @param numSequences
+	 *            number of sequences desired for the test suite
+	 * @param minLength
+	 *            minimal length of a test sequence
+	 * @param maxLength
+	 *            maximal length of a test sequence
+	 * @param validEnd
+	 *            defines if test cases have to end with the global end event
+	 *            {@link Event#ENDEVENT} (see {@link #validEnd})
+	 * @param maxIter
+	 *            maximal number of random walks before aborting the test case
+	 *            generation (see {@link #maxIter})
+	 */
+	public RandomWalkGenerator(int numSequences, int minLength, int maxLength,
+			boolean validEnd, long maxIter) {
+		// check validity of the parameters
+		if (numSequences < 1) {
+			throw new InvalidParameterException(
+					"number of sequences must be at least 1 but is "
+							+ numSequences);
+		}
+		if (maxLength < 1) {
+			throw new InvalidParameterException(
+					"maximal allowed length of test cases must be at least 1 but is "
+							+ maxLength);
+		}
+		if (minLength > maxLength) {
+			throw new InvalidParameterException(
+					"minimal allowed length of test cases must be less than or equal to the maximal allowed length (min length: "
+							+ minLength + " ; max length: " + maxLength + ")");
+		}
+		if (maxIter < numSequences) {
+			throw new InvalidParameterException(
+					"maximal number of iterations must greater than or equal to the number of sequences (number of sequences: "
+							+ numSequences
+							+ " ; max iterations: "
+							+ maxIter
+							+ ")");
+		}
+		this.numSequences = numSequences;
+		this.minLength = minLength;
+		this.maxLength = maxLength;
+		this.validEnd = validEnd;
+		this.maxIter = maxIter;
+	}
+
+	/**
+	 * <p>
+	 * Generates a test suite by repeatedly randomly walking a stochastic
+	 * process.
+	 * </p>
+	 * 
+	 * @param model
+	 *            stochastic process which performs the random walks
+	 * @return the test suite
+	 */
+	@SuppressWarnings("unchecked")
+	public Collection<List<? extends Event<?>>> generateTestSuite(
+			IStochasticProcess model) {
+		if (model == null) {
+			throw new InvalidParameterException("model must not be null!");
+		}
+
+		Set<List<? extends Event<?>>> sequences = new HashSet<List<? extends Event<?>>>(
+				numSequences);
+		actualIter = 0;
+		while (sequences.size() < numSequences && actualIter < maxIter) {
+			List<? extends Event<?>> generatedSequence = model.randomSequence(
+					maxLength, validEnd);
+			if (generatedSequence.size() >= minLength
+					&& generatedSequence.size() <= maxLength) {
+				((List<Event<?>>) generatedSequence).add(0, Event.STARTEVENT);
+				if (validEnd) {
+					((List<Event<?>>) generatedSequence).add(Event.ENDEVENT);
+				}
+				sequences.add(generatedSequence);
+			}
+			actualIter++;
+		}
+
+		return sequences;
+	}
+
+	/**
+	 * <p>
+	 * Returns the actual number of random walks performed during the last call
+	 * of {@link #generateTestSuite(IStochasticProcess)} or -1 if
+	 * {@link #generateTestSuite(IStochasticProcess)} has not been called yet.
+	 * </p>
+	 * 
+	 * @return actual number of random walks or -1 if
+	 *         {@link #generateTestSuite(IStochasticProcess)} has not been
+	 *         called
+	 */
+	public long getActualIter() {
+		return actualIter;
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-usability-test/.classpath
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usability-test/.classpath	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usability-test/.classpath	(revision 540)
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/test-classes" path="src/test/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="src" output="target/classes" path="src/main/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
Index: /tags/quest-pre-eventrefactoring/quest-core-usability-test/.project
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usability-test/.project	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usability-test/.project	(revision 540)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>quest-core-usability-test</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
Index: /tags/quest-pre-eventrefactoring/quest-core-usability-test/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usability-test/.settings/org.eclipse.jdt.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usability-test/.settings/org.eclipse.jdt.core.prefs	(revision 540)
@@ -0,0 +1,5 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.6
Index: /tags/quest-pre-eventrefactoring/quest-core-usability-test/.settings/org.eclipse.m2e.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usability-test/.settings/org.eclipse.m2e.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usability-test/.settings/org.eclipse.m2e.core.prefs	(revision 540)
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
Index: /tags/quest-pre-eventrefactoring/quest-core-usability-test/pom.xml
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usability-test/pom.xml	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usability-test/pom.xml	(revision 540)
@@ -0,0 +1,135 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>de.ugoe.cs.quest</groupId>
+  <artifactId>quest-core-usability-test</artifactId>
+  <version>0.0.1-SNAPSHOT</version>
+  <name>quest-core-usability-test</name>
+  <scm>
+    <url>https://quest.informatik.uni-goettingen.de/svn/quest/trunk/quest-core-usability-test</url>
+  </scm>
+  <dependencies>
+    <dependency>
+      <groupId>de.ugoe.cs.quest</groupId>
+      <artifactId>quest-core-usability</artifactId>
+      <version>0.0.1-SNAPSHOT</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>de.ugoe.cs.quest</groupId>
+      <artifactId>quest-core-tasktrees-test</artifactId>
+      <version>0.0.1-SNAPSHOT</version>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+        <groupId>junit</groupId>
+        <artifactId>junit</artifactId>
+        <version>4.8.1</version>
+        <scope>test</scope>
+    </dependency>
+  </dependencies>
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.eclipse.m2e</groupId>
+          <artifactId>lifecycle-mapping</artifactId>
+          <version>1.0.0</version>
+          <configuration>
+            <lifecycleMappingMetadata>
+              <pluginExecutions>
+                <pluginExecution>
+                  <pluginExecutionFilter>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-dependency-plugin</artifactId>
+                    <versionRange>[1.0.0,)</versionRange>
+                    <goals>
+                      <goal>unpack</goal>
+                    </goals>
+                  </pluginExecutionFilter>
+                  <action>
+                    <ignore/>
+                  </action>
+                </pluginExecution>
+                <pluginExecution>
+                  <pluginExecutionFilter>
+                    <groupId>org.codehaus.mojo</groupId>
+                    <artifactId>emma-maven-plugin</artifactId>
+                    <versionRange>[1.0-alpha-3,)</versionRange>
+                    <goals>
+                      <goal>emma</goal>
+                    </goals>
+                  </pluginExecutionFilter>
+                  <action>
+                    <ignore/>
+                  </action>
+                </pluginExecution>
+              </pluginExecutions>
+            </lifecycleMappingMetadata>
+          </configuration>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>2.3.2</version>
+        <configuration>
+          <source>1.6</source>
+          <target>1.6</target>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-dependency-plugin</artifactId>
+        <version>2.4</version>
+        <executions>
+          <execution>
+            <id>unpack</id>
+            <phase>process-classes</phase>
+            <goals>
+              <goal>unpack</goal>
+            </goals>
+            <configuration>
+              <artifactItems>
+                <artifactItem>
+                  <groupId>de.ugoe.cs.quest</groupId>
+                  <artifactId>quest-core-usability</artifactId>
+                  <version>0.0.1-SNAPSHOT</version>
+                  <outputDirectory>${project.build.directory}/classes</outputDirectory>
+                </artifactItem>
+              </artifactItems>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>emma-maven-plugin</artifactId>
+        <version>1.0-alpha-3</version>
+        <inherited>true</inherited>          
+        <executions>
+          <execution>
+            <phase>process-classes</phase>
+            <goals>
+              <goal>emma</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <version>2.3.2</version>
+        <executions>
+          <execution>
+            <goals>
+              <goal>test-jar</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>
Index: /tags/quest-pre-eventrefactoring/quest-core-usability-test/src/test/java/de/ugoe/cs/quest/usability/AbstractUsabilityEvaluationTC.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usability-test/src/test/java/de/ugoe/cs/quest/usability/AbstractUsabilityEvaluationTC.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usability-test/src/test/java/de/ugoe/cs/quest/usability/AbstractUsabilityEvaluationTC.java	(revision 540)
@@ -0,0 +1,263 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: AbstractUsabilityEvaluationTC.java,v $
+// Version   : $Revision: 0.0 $  $Author: pharms $  $Date: 18.07.2012 $
+// Project   : UsabilityEvaluationManager
+// Creation  : 2012 by pharms
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.usability;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.util.logging.Logger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.junit.Before;
+
+import de.ugoe.cs.quest.tasktrees.testutils.DummyGUIElement;
+import de.ugoe.cs.quest.tasktrees.testutils.DummyInteraction;
+import de.ugoe.cs.quest.tasktrees.testutils.DummyTextField;
+import de.ugoe.cs.quest.tasktrees.testutils.SimpleLogFormatter;
+import de.ugoe.cs.quest.tasktrees.treeifc.Iteration;
+import de.ugoe.cs.quest.tasktrees.treeifc.Selection;
+import de.ugoe.cs.quest.tasktrees.treeifc.Sequence;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTree;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeBuilder;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNode;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNodeFactory;
+import de.ugoe.cs.quest.tasktrees.treeifc.TextInputInteractionTask;
+import de.ugoe.cs.quest.tasktrees.treeimpl.TaskTreeBuilderImpl;
+import de.ugoe.cs.quest.tasktrees.treeimpl.TaskTreeNodeFactoryImpl;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 18.07.2012$
+ * @author 2012, last modified by $Author: pharms$
+ */
+//-------------------------------------------------------------------------------------------------
+public class AbstractUsabilityEvaluationTC
+{
+  
+  /** */
+  private TaskTreeBuilder mTaskTreeBuilder = new TaskTreeBuilderImpl();
+
+  /** */
+  private TaskTreeNodeFactory mTaskTreeNodeFactory = new TaskTreeNodeFactoryImpl();
+  
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Before
+  public void setUp()
+  {
+    Logger.getLogger("").getHandlers()[0].setFormatter(new SimpleLogFormatter());
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  protected TaskTree createTaskTree(String spec)
+  {
+    Matcher matcher =
+      Pattern.compile("(\\s*(\\w+)\\s*(\\(((\\w*\\s*)*)\\))?\\s*(\\{))|(\\})").matcher(spec);
+      
+    if (!matcher.find())
+    {
+      if (!matcher.hitEnd())
+      {
+        throw new IllegalArgumentException("could not parse task specification");
+      }
+    }
+
+    return mTaskTreeNodeFactory.createTaskTree(parseTask(matcher, new int[1]));
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param expectedDefects
+   * @param evaluateUsability
+   */
+  //-----------------------------------------------------------------------------------------------
+  protected void assertUsabilityEvaluationResult(UsabilityDefect[]         expectedDefects,
+                                                 UsabilityEvaluationResult evaluationResult)
+  {
+    assertEquals(expectedDefects.length, evaluationResult.getAllDefects().size());
+    
+    EXPECTED_DEFECT_ITERATION:
+    for (UsabilityDefect expectedDefect : expectedDefects)
+    {
+      for (UsabilityDefect defect : evaluationResult.getAllDefects())
+      {
+        if (expectedDefect.equals(defect))
+        {
+          System.err.println(defect.getParameterizedDescription());
+          continue EXPECTED_DEFECT_ITERATION;
+        }
+      }
+      
+      for (UsabilityDefect defect : evaluationResult.getAllDefects())
+      {
+        System.err.println(defect);
+      }
+      
+      fail("expected defect " + expectedDefect + " not found in evaluation result");
+    }
+  }
+
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * 
+   */
+  //-----------------------------------------------------------------------------------------------
+  private TaskTreeNode parseTask(Matcher tokenMatcher, int[] typeNumbers)
+  {
+    String firstToken = tokenMatcher.group();
+    
+    if ("}".equals(firstToken))
+    {
+      throw new IllegalArgumentException("found a closing bracket at an unexpected place");
+    }
+    
+    TaskTreeNode treeNode = instantiateTreeNode(tokenMatcher, typeNumbers);
+    
+    if (!tokenMatcher.find())
+    {
+      throw new IllegalArgumentException("could not parse task specification");
+    }
+    
+    firstToken = tokenMatcher.group();
+    
+    if (!"}".equals(firstToken))
+    {
+      TaskTreeNode child = null;
+    
+      do
+      {
+        child = parseTask(tokenMatcher, typeNumbers);
+        
+        if (child != null)
+        {
+          addChild(treeNode, child);
+          
+          if (!tokenMatcher.find())
+          {
+            throw new IllegalArgumentException("could not parse task specification");
+          }
+          
+          firstToken = tokenMatcher.group();
+          
+          if ("}".equals(firstToken))
+          {
+            break;
+          }
+        }
+        
+      }
+      while (child != null);
+      
+    }
+    
+    return treeNode;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param group
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  private TaskTreeNode instantiateTreeNode(Matcher tokenMatcher, int[] typeNumbers)
+  {
+    String type = tokenMatcher.group(2);
+    String additionalInfo = tokenMatcher.group(4);
+    
+    if ("Interaction".equals(type))
+    {
+      return mTaskTreeNodeFactory.createNewInteractionTask
+        (new DummyGUIElement("dummy"), new DummyInteraction("dummy", typeNumbers[0]++));
+    }
+    else if ("Sequence".equals(type))
+    {
+      return mTaskTreeNodeFactory.createNewSequence();
+    }
+    else if ("Iteration".equals(type))
+    {
+      return mTaskTreeNodeFactory.createNewIteration();
+    }
+    else if ("Selection".equals(type))
+    {
+      return mTaskTreeNodeFactory.createNewSelection();
+    }
+    else if ("TextInput".equals(type))
+    {
+      if (additionalInfo == null)
+      {
+        fail("no simulated text provided for text input interactin task");
+      }
+      
+      TextInputInteractionTask task =
+        mTaskTreeNodeFactory.createNewTextInputInteractionTask(new DummyTextField(additionalInfo));
+     
+      task.setEnteredText(additionalInfo);
+      return task;
+    }
+    else
+    {
+      fail("invalid type of task tree node: " + type);
+      return null;
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param treeNode
+   * @param child
+   */
+  //-----------------------------------------------------------------------------------------------
+  private void addChild(TaskTreeNode parent, TaskTreeNode child)
+  {
+    if (parent instanceof Sequence)
+    {
+      mTaskTreeBuilder.addChild((Sequence) parent, child);
+    }
+    else if (parent instanceof Iteration)
+    {
+      if (parent.getChildren().size() <= 0)
+      {
+        mTaskTreeBuilder.setChild((Iteration) parent, child);
+      }
+      else
+      {
+        fail("can not add more than one child to an iteration");
+      }
+    }
+    else if (parent instanceof Selection)
+    {
+      mTaskTreeBuilder.addChild((Selection) parent, child);
+    }
+    else if (parent instanceof TextInputInteractionTask)
+    {
+      mTaskTreeBuilder.addChild((TextInputInteractionTask) parent, child);
+    }
+    else
+    {
+      fail("can not add children to parent task tree node of type " + parent.getClass().getName());
+    }
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-usability-test/src/test/java/de/ugoe/cs/quest/usability/TextInputStatisticsRuleTest.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usability-test/src/test/java/de/ugoe/cs/quest/usability/TextInputStatisticsRuleTest.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usability-test/src/test/java/de/ugoe/cs/quest/usability/TextInputStatisticsRuleTest.java	(revision 540)
@@ -0,0 +1,741 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: TextInputStatisticsRuleTest.java,v $
+// Version   : $Revision: 0.0 $  $Author: pharms $  $Date: 18.07.2012 $
+// Project   : UsabilityEvaluationManager
+// Creation  : 2012 by pharms
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.usability;
+
+import static de.ugoe.cs.quest.usability.UsabilityDefectDescription.TEXT_FIELD_INPUT_RATIO;
+import static de.ugoe.cs.quest.usability.UsabilityDefectDescription.TEXT_FIELD_INPUT_REPETITIONS;
+import static de.ugoe.cs.quest.usability.UsabilityDefectDescription.TEXT_FIELD_NO_LETTER_OR_DIGIT_RATIO;
+import static de.ugoe.cs.quest.usability.UsabilityDefectSeverity.HIGH;
+import static de.ugoe.cs.quest.usability.UsabilityDefectSeverity.INFO;
+import static de.ugoe.cs.quest.usability.UsabilityDefectSeverity.LOW;
+import static de.ugoe.cs.quest.usability.UsabilityDefectSeverity.MEDIUM;
+
+import org.junit.Test;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 18.07.2012$
+ * @author 2012, last modified by $Author: pharms$
+ */
+//-------------------------------------------------------------------------------------------------
+public class TextInputStatisticsRuleTest extends AbstractUsabilityEvaluationTC
+{
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Test
+  public void testWithDifferentTextInputInteractionsOnly()
+  {
+    UsabilityEvaluationManager manager = new UsabilityEvaluationManager();
+    
+    // ===== check =====
+    String spec = "TextInput (bla) {}";
+    UsabilityDefect[] expectedDefects = new UsabilityDefect[]
+    {
+      new UsabilityDefect(HIGH, TEXT_FIELD_INPUT_RATIO)
+    };
+    
+    assertUsabilityEvaluationResult
+      (expectedDefects, manager.evaluateUsability(createTaskTree(spec)));
+    
+    // ===== check =====
+    spec =
+      "Sequence {" +
+      "  TextInput (bla) {}" +
+      "}";
+    
+    expectedDefects = new UsabilityDefect[]
+    {
+      new UsabilityDefect(HIGH, UsabilityDefectDescription.TEXT_FIELD_INPUT_RATIO)
+    };
+    
+    assertUsabilityEvaluationResult
+      (expectedDefects, manager.evaluateUsability(createTaskTree(spec)));
+    
+    // ===== check =====
+    spec =
+      "Sequence {" +
+      "  TextInput (a) {}" +
+      "  TextInput (b) {}" +
+      "  TextInput (c) {}" +
+      "  TextInput (d) {}" +
+      "}";
+    
+    expectedDefects = new UsabilityDefect[]
+    {
+      new UsabilityDefect(HIGH, TEXT_FIELD_INPUT_RATIO)
+    };
+    
+    assertUsabilityEvaluationResult
+      (expectedDefects, manager.evaluateUsability(createTaskTree(spec)));
+    
+    // ===== check =====
+    spec =
+      "Selection {" +
+      "  TextInput (a) {}" +
+      "  TextInput (b) {}" +
+      "  TextInput (c) {}" +
+      "  TextInput (d) {}" +
+      "}";
+      
+    expectedDefects = new UsabilityDefect[]
+    {
+      new UsabilityDefect(HIGH, TEXT_FIELD_INPUT_RATIO)
+    };
+      
+    assertUsabilityEvaluationResult
+      (expectedDefects, manager.evaluateUsability(createTaskTree(spec)));
+      
+    // ===== check =====
+    spec =
+      "Iteration {" +
+      "  TextInput (bla) {}" +
+      "}";
+        
+    expectedDefects = new UsabilityDefect[]
+    {
+      new UsabilityDefect(HIGH, TEXT_FIELD_INPUT_RATIO)
+    };
+      
+    assertUsabilityEvaluationResult
+      (expectedDefects, manager.evaluateUsability(createTaskTree(spec)));
+        
+    // ===== check =====
+    spec =
+      "Sequence {" +
+      "  TextInput (a) {}" +
+      "  Sequence {" +
+      "    TextInput (b) {}" +
+      "    TextInput (c) {}" +
+      "    TextInput (d) {}" +
+      "    TextInput (e) {}" +
+      "  }" +
+      "  Iteration {" +
+      "    TextInput (f) {}" +
+      "  }" +
+      "  TextInput (g) {}" +
+      "  Selection {" +
+      "    TextInput (h) {}" +
+      "    TextInput (i) {}" +
+      "    TextInput (j) {}" +
+      "    TextInput (k) {}" +
+      "  }" +
+      "  Sequence {" +
+      "    TextInput (l) {}" +
+      "    Sequence {" +
+      "      TextInput (m) {}" +
+      "      TextInput (n) {}" +
+      "      TextInput (o) {}" +
+      "      TextInput (p) {}" +
+      "    }" +
+      "    Iteration {" +
+      "      TextInput (q) {}" +
+      "    }" +
+      "    TextInput (r) {}" +
+      "    Selection {" +
+      "      TextInput (s) {}" +
+      "      TextInput (t) {}" +
+      "      TextInput (u) {}" +
+      "      TextInput (v) {}" +
+      "    }" +
+      "  }" +
+      "  Selection {" +
+      "    TextInput (w) {}" +
+      "    Sequence {" +
+      "      TextInput (x) {}" +
+      "      TextInput (y) {}" +
+      "      TextInput (z) {}" +
+      "      TextInput (aa) {}" +
+      "    }" +
+      "    Iteration {" +
+      "      TextInput (ab) {}" +
+      "    }" +
+      "    TextInput (ac) {}" +
+      "    Selection {" +
+      "      TextInput (ad) {}" +
+      "      TextInput (ae) {}" +
+      "      TextInput (af) {}" +
+      "      TextInput (ag) {}" +
+      "    }" +
+      "  }" +
+      "  TextInput (ah) {}" +
+      "}";
+     
+    expectedDefects = new UsabilityDefect[]
+    {
+      new UsabilityDefect(HIGH, TEXT_FIELD_INPUT_RATIO)
+    };
+    
+    assertUsabilityEvaluationResult
+      (expectedDefects, manager.evaluateUsability(createTaskTree(spec)));   
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Test
+  public void testCombinationsOfTextInputInteractionsAndOtherInteractions()
+  {
+    UsabilityEvaluationManager manager = new UsabilityEvaluationManager();
+    
+    // ===== check =====
+    String spec =
+      "Sequence {" +
+      "  Interaction {}" +
+      "  TextInput (a) {}" +
+      "  TextInput (b) {}" +
+      "  Interaction {}" +
+      "  TextInput (c) {}" +
+      "}";
+      
+    UsabilityDefect[] expectedDefects = new UsabilityDefect[]
+    {
+      new UsabilityDefect(LOW, TEXT_FIELD_INPUT_RATIO)
+    };
+    
+    assertUsabilityEvaluationResult
+      (expectedDefects, manager.evaluateUsability(createTaskTree(spec)));
+    
+    // ===== check =====
+    spec =
+      "Sequence {" +
+      "  Interaction {}" +
+      "  TextInput (a) {}" +
+      "  Interaction {}" +
+      "  Interaction {}" +
+      "  TextInput (c) {}" +
+      "}";
+        
+    expectedDefects = new UsabilityDefect[]
+    {
+      new UsabilityDefect(INFO, TEXT_FIELD_INPUT_RATIO)
+    };
+    
+    assertUsabilityEvaluationResult
+      (expectedDefects, manager.evaluateUsability(createTaskTree(spec)));
+      
+    // ===== check =====
+    spec =
+      "Sequence {" +
+      "  Interaction {}" +
+      "  TextInput (a) {}" +
+      "  Interaction {}" +
+      "  Interaction {}" +
+      "  Interaction {}" +
+      "}";
+          
+    expectedDefects = new UsabilityDefect[0];
+        
+    assertUsabilityEvaluationResult
+      (expectedDefects, manager.evaluateUsability(createTaskTree(spec)));
+        
+    // ===== check =====
+    spec =
+      "Selection {" +
+      "  Interaction {}" +
+      "  TextInput (a) {}" +
+      "  TextInput (b) {}" +
+      "  Interaction {}" +
+      "  TextInput (c) {}" +
+      "}";
+      
+    expectedDefects = new UsabilityDefect[]
+    {
+      new UsabilityDefect(LOW, TEXT_FIELD_INPUT_RATIO)
+    };
+      
+    assertUsabilityEvaluationResult
+      (expectedDefects, manager.evaluateUsability(createTaskTree(spec)));
+      
+    // ===== check =====
+    spec =
+      "Sequence {" +
+      "  TextInput (a) {}" +
+      "  Sequence {" +
+      "    Interaction {}" +
+      "    TextInput (b) {}" +
+      "    TextInput (c) {}" +
+      "    Interaction {}" +
+      "    TextInput (d) {}" +
+      "  }" +
+      "  Iteration {" +
+      "    TextInput (e) {}" +
+      "  }" +
+      "  Interaction {}" +
+      "  Selection {" +
+      "    Interaction {}" +
+      "    TextInput (f) {}" +
+      "    TextInput (g) {}" +
+      "    Interaction {}" +
+      "    TextInput (h) {}" +
+      "    TextInput (i) {}" +
+      "  }" +
+      "  Sequence {" +
+      "    TextInput (j) {}" +
+      "    Sequence {" +
+      "      TextInput (k) {}" +
+      "      Interaction {}" +
+      "      TextInput (l) {}" +
+      "      TextInput (m) {}" +
+      "      Interaction {}" +
+      "      TextInput (n) {}" +
+      "      TextInput (o) {}" +
+      "    }" +
+      "    Iteration {" +
+      "      Interaction {}" +
+      "    }" +
+      "    Interaction {}" +
+      "    Selection {" +
+      "      TextInput (p) {}" +
+      "      TextInput (q) {}" +
+      "      TextInput (r) {}" +
+      "      Interaction {}" +
+      "      TextInput (s) {}" +
+      "      TextInput (t) {}" +
+      "      Interaction {}" +
+      "      TextInput (u) {}" +
+      "      TextInput (v) {}" +
+      "    }" +
+      "  }" +
+      "  Selection {" +
+      "    Interaction {}" +
+      "    Sequence {" +
+      "      TextInput (w) {}" +
+      "      Interaction {}" +
+      "      TextInput (x) {}" +
+      "      TextInput (y) {}" +
+      "      Interaction {}" +
+      "    }" +
+      "    Iteration {" +
+      "      TextInput (z) {}" +
+      "    }" +
+      "    TextInput (aa) {}" +
+      "    Selection {" +
+      "      TextInput (ab) {}" +
+      "      Interaction {}" +
+      "      TextInput (ac) {}" +
+      "      TextInput (ad) {}" +
+      "      Interaction {}" +
+      "      TextInput (ae) {}" +
+      "    }" +
+      "  }" +
+      "  Interaction {}" +
+      "}";
+     
+    expectedDefects = new UsabilityDefect[]
+    {
+      new UsabilityDefect(LOW, TEXT_FIELD_INPUT_RATIO)
+    };
+    
+    assertUsabilityEvaluationResult
+      (expectedDefects, manager.evaluateUsability(createTaskTree(spec)));
+    
+    // ===== check =====
+    spec =
+      "Sequence {" +
+      "  TextInput (a) {}" +
+      "  Sequence {" +
+      "    Interaction {}" +
+      "    TextInput (b) {}" +
+      "    Interaction {}" +
+      "    Interaction {}" +
+      "    TextInput (c) {}" +
+      "  }" +
+      "  Iteration {" +
+      "    TextInput (d) {}" +
+      "  }" +
+      "  Interaction {}" +
+      "  Selection {" +
+      "    Interaction {}" +
+      "    TextInput (e) {}" +
+      "    Interaction {}" +
+      "    Interaction {}" +
+      "    TextInput (g) {}" +
+      "    Interaction {}" +
+      "  }" +
+      "  Sequence {" +
+      "    TextInput (i) {}" +
+      "    Sequence {" +
+      "      TextInput (j) {}" +
+      "      Interaction {}" +
+      "      TextInput (k) {}" +
+      "      Interaction {}" +
+      "      Interaction {}" +
+      "      TextInput (m) {}" +
+      "      Interaction {}" +
+      "    }" +
+      "    Iteration {" +
+      "      Interaction {}" +
+      "    }" +
+      "    Interaction {}" +
+      "    Selection {" +
+      "      TextInput (o) {}" +
+      "      Interaction {}" +
+      "      Interaction {}" +
+      "      Interaction {}" +
+      "      Interaction {}" +
+      "      TextInput (s) {}" +
+      "      Interaction {}" +
+      "      TextInput (t) {}" +
+      "      TextInput (u) {}" +
+      "    }" +
+      "  }" +
+      "  Selection {" +
+      "    Interaction {}" +
+      "    Sequence {" +
+      "      TextInput (v) {}" +
+      "      Interaction {}" +
+      "      Interaction {}" +
+      "      TextInput (x) {}" +
+      "      Interaction {}" +
+      "    }" +
+      "    Iteration {" +
+      "      TextInput (y) {}" +
+      "    }" +
+      "    TextInput (z) {}" +
+      "    Selection {" +
+      "      TextInput (aa) {}" +
+      "      Interaction {}" +
+      "      TextInput (ab) {}" +
+      "      Interaction {}" +
+      "      Interaction {}" +
+      "      TextInput (ad) {}" +
+      "    }" +
+      "  }" +
+      "  Interaction {}" +
+      "}";
+
+    expectedDefects = new UsabilityDefect[]
+    {
+      new UsabilityDefect(INFO, TEXT_FIELD_INPUT_RATIO)
+    };
+
+    assertUsabilityEvaluationResult
+      (expectedDefects, manager.evaluateUsability(createTaskTree(spec)));   
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Test
+  public void testTextEntryRepetitions()
+  {
+    UsabilityEvaluationManager manager = new UsabilityEvaluationManager();
+    
+    // ===== check =====
+    String spec =
+      "Sequence {" +
+      "  TextInput (a b c) {}" +
+      "  Sequence {" +
+      "    TextInput (a) {}" +
+      "    TextInput (b) {}" +
+      "    TextInput (c) {}" +
+      "    TextInput (a) {}" +
+      "  }" +
+      "  Iteration {" +
+      "    TextInput (a) {}" +
+      "  }" +
+      "  TextInput (a) {}" +
+      "  Selection {" +
+      "    TextInput (b c) {}" +
+      "    TextInput (a) {}" +
+      "    TextInput (a c) {}" +
+      "    TextInput (b a) {}" +
+      "  }" +
+      "  Sequence {" +
+      "    TextInput (b c) {}" +
+      "    Sequence {" +
+      "      TextInput (d a c) {}" +
+      "      TextInput (b b b a) {}" +
+      "      TextInput (a a c c) {}" +
+      "      TextInput (b b a) {}" +
+      "    }" +
+      "  }" +
+      "  TextInput (d) {}" +
+      "}";
+     
+    UsabilityDefect[] expectedDefects = new UsabilityDefect[]
+    {
+      new UsabilityDefect(HIGH, TEXT_FIELD_INPUT_RATIO),
+      new UsabilityDefect(HIGH, TEXT_FIELD_INPUT_REPETITIONS)
+    };
+    
+    assertUsabilityEvaluationResult
+      (expectedDefects, manager.evaluateUsability(createTaskTree(spec)));   
+
+    // ===== check =====
+    spec =
+      "Sequence {" +
+      "  TextInput (a b c d e f g h i j k l m) {}" +
+      "  Sequence {" +
+      "    TextInput (a) {}" +
+      "    TextInput (b) {}" +
+      "    TextInput (c) {}" +
+      "    TextInput (d) {}" +
+      "  }" +
+      "  Iteration {" +
+      "    TextInput (e) {}" +
+      "  }" +
+      "  TextInput (f) {}" +
+      "  Selection {" +
+      "    TextInput (g) {}" +
+      "    TextInput (h) {}" +
+      "    TextInput (i) {}" +
+      "    TextInput (j) {}" +
+      "  }" +
+      "  Sequence {" +
+      "    TextInput (k) {}" +
+      "    Sequence {" +
+      "      TextInput (l) {}" +
+      "      TextInput (m) {}" +
+      "      TextInput (n) {}" +
+      "      TextInput (o) {}" +
+      "    }" +
+      "  }" +
+      "  TextInput (p) {}" +
+      "}";
+
+    expectedDefects = new UsabilityDefect[]
+    {
+      new UsabilityDefect(HIGH, TEXT_FIELD_INPUT_RATIO),
+      new UsabilityDefect(HIGH, TEXT_FIELD_INPUT_REPETITIONS)
+    };
+
+    assertUsabilityEvaluationResult
+      (expectedDefects, manager.evaluateUsability(createTaskTree(spec)));
+
+    // ===== check =====
+    spec =
+      "Sequence {" +
+      "  TextInput (a b c d e f g h i j k l m) {}" +
+      "  Sequence {" +
+      "    TextInput (a) {}" +
+      "    TextInput (b) {}" +
+      "    TextInput (c) {}" +
+      "    TextInput (d) {}" +
+      "  }" +
+      "  Iteration {" +
+      "    TextInput (e) {}" +
+      "  }" +
+      "  TextInput (a) {}" +
+      "  Selection {" +
+      "    TextInput (b) {}" +
+      "    TextInput (c) {}" +
+      "    TextInput (d) {}" +
+      "    TextInput (e) {}" +
+      "  }" +
+      "  Sequence {" +
+      "    TextInput (a) {}" +
+      "    Sequence {" +
+      "      TextInput (b) {}" +
+      "      TextInput (c) {}" +
+      "      TextInput (d) {}" +
+      "      TextInput (e) {}" +
+      "    }" +
+      "  }" +
+      "  TextInput (f) {}" +
+      "}";
+
+    expectedDefects = new UsabilityDefect[]
+    {
+      new UsabilityDefect(HIGH, TEXT_FIELD_INPUT_RATIO),
+      new UsabilityDefect(MEDIUM, TEXT_FIELD_INPUT_REPETITIONS)
+    };
+
+    assertUsabilityEvaluationResult
+      (expectedDefects, manager.evaluateUsability(createTaskTree(spec)));
+ 
+    // ===== check =====
+    spec =
+      "Sequence {" +
+      "  TextInput (a b c d e f g h i j k l m) {}" +
+      "  Sequence {" +
+      "    TextInput (a) {}" +
+      "    TextInput (b) {}" +
+      "    TextInput (c) {}" +
+      "    TextInput (a) {}" +
+      "  }" +
+      "  Iteration {" +
+      "    TextInput (b) {}" +
+      "  }" +
+      "  TextInput (c) {}" +
+      "  Selection {" +
+      "    TextInput (a) {}" +
+      "    TextInput (b) {}" +
+      "    TextInput (c) {}" +
+      "    TextInput (a) {}" +
+      "  }" +
+      "  Sequence {" +
+      "    TextInput (b) {}" +
+      "    Sequence {" +
+      "      TextInput (c) {}" +
+      "      TextInput (a) {}" +
+      "      TextInput (b) {}" +
+      "      TextInput (c) {}" +
+      "    }" +
+      "  }" +
+      "  TextInput (a) {}" +
+      "}";
+
+    expectedDefects = new UsabilityDefect[]
+    {
+      new UsabilityDefect(HIGH, TEXT_FIELD_INPUT_RATIO),
+      new UsabilityDefect(MEDIUM, TEXT_FIELD_INPUT_REPETITIONS)
+    };
+
+    assertUsabilityEvaluationResult
+      (expectedDefects, manager.evaluateUsability(createTaskTree(spec)));
+   
+    // ===== check =====
+    spec =
+      "Sequence {" +
+      "  TextInput (a b c) {}" +
+      "  Sequence {" +
+      "    TextInput (a) {}" +
+      "    TextInput (b) {}" +
+      "    TextInput (c) {}" +
+      "  }" +
+      "}";
+
+    expectedDefects = new UsabilityDefect[]
+    {
+      new UsabilityDefect(HIGH, TEXT_FIELD_INPUT_RATIO),
+      new UsabilityDefect(LOW, TEXT_FIELD_INPUT_REPETITIONS)
+    };
+
+    assertUsabilityEvaluationResult
+      (expectedDefects, manager.evaluateUsability(createTaskTree(spec)));
+     
+    // ===== check =====
+    spec =
+      "Sequence {" +
+      "  TextInput (a b c) {}" +
+      "  Sequence {" +
+      "    TextInput (a) {}" +
+      "    TextInput (a) {}" +
+      "    TextInput (b) {}" +
+      "  }" +
+      "}";
+
+    expectedDefects = new UsabilityDefect[]
+    {
+      new UsabilityDefect(HIGH, TEXT_FIELD_INPUT_RATIO),
+      new UsabilityDefect(LOW, TEXT_FIELD_INPUT_REPETITIONS)
+    };
+
+    assertUsabilityEvaluationResult
+      (expectedDefects, manager.evaluateUsability(createTaskTree(spec)));
+       
+    // ===== check =====
+    spec =
+      "Sequence {" +
+      "  TextInput (a b c) {}" +
+      "  Sequence {" +
+      "    TextInput (a) {}" +
+      "    TextInput (d) {}" +
+      "    TextInput (e) {}" +
+      "  }" +
+      "}";
+
+    expectedDefects = new UsabilityDefect[]
+    {
+      new UsabilityDefect(HIGH, TEXT_FIELD_INPUT_RATIO),
+      new UsabilityDefect(INFO, TEXT_FIELD_INPUT_REPETITIONS)
+    };
+
+    assertUsabilityEvaluationResult
+      (expectedDefects, manager.evaluateUsability(createTaskTree(spec)));
+         
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Test
+  public void testNoLetterOrDigitInput()
+  {
+    UsabilityEvaluationManager manager = new UsabilityEvaluationManager();
+    
+    // ===== check =====
+    String spec =
+      "Sequence {" +
+      "  TextInput (_a_b_c_) {}" +
+      "}";
+     
+    UsabilityDefect[] expectedDefects = new UsabilityDefect[]
+    {
+      new UsabilityDefect(HIGH, TEXT_FIELD_INPUT_RATIO),
+      new UsabilityDefect(HIGH, TEXT_FIELD_NO_LETTER_OR_DIGIT_RATIO)
+    };
+    
+    assertUsabilityEvaluationResult
+      (expectedDefects, manager.evaluateUsability(createTaskTree(spec)));   
+
+    // ===== check =====
+    spec =
+      "Sequence {" +
+      "  TextInput (12345_6789012345) {}" +
+      "}";
+     
+    expectedDefects = new UsabilityDefect[]
+    {
+      new UsabilityDefect(HIGH, TEXT_FIELD_INPUT_RATIO),
+      new UsabilityDefect(MEDIUM, TEXT_FIELD_NO_LETTER_OR_DIGIT_RATIO)
+    };
+    
+    assertUsabilityEvaluationResult
+      (expectedDefects, manager.evaluateUsability(createTaskTree(spec)));   
+
+    // ===== check =====
+    spec =
+      "Sequence {" +
+      "  TextInput (123456789012345678901234567890_123456789012345) {}" +
+      "}";
+     
+    expectedDefects = new UsabilityDefect[]
+    {
+      new UsabilityDefect(HIGH, TEXT_FIELD_INPUT_RATIO),
+      new UsabilityDefect(LOW, TEXT_FIELD_NO_LETTER_OR_DIGIT_RATIO)
+    };
+    
+    assertUsabilityEvaluationResult
+      (expectedDefects, manager.evaluateUsability(createTaskTree(spec)));   
+
+    // ===== check =====
+    spec =
+      "Sequence {" +
+      "  TextInput (1234567890123456789012345678901234567890123456789_01234567890" +
+      "12345678901234567890123456789012345) {}" +
+      "}";
+     
+    expectedDefects = new UsabilityDefect[]
+    {
+      new UsabilityDefect(HIGH, TEXT_FIELD_INPUT_RATIO),
+      new UsabilityDefect(INFO, TEXT_FIELD_NO_LETTER_OR_DIGIT_RATIO)
+    };
+    
+    assertUsabilityEvaluationResult
+      (expectedDefects, manager.evaluateUsability(createTaskTree(spec)));   
+
+  }
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-usability-test/src/test/java/de/ugoe/cs/quest/usability/UsabilityDefectDescriptionTest.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usability-test/src/test/java/de/ugoe/cs/quest/usability/UsabilityDefectDescriptionTest.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usability-test/src/test/java/de/ugoe/cs/quest/usability/UsabilityDefectDescriptionTest.java	(revision 540)
@@ -0,0 +1,70 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: UsabilityDefectDescriptionTest.java,v $
+// Version   : $Revision: 0.0 $  $Author: pharms $  $Date: 20.07.2012 $
+// Project   : UsabilityEvaluationManager
+// Creation  : 2012 by pharms
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.usability;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Test;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 20.07.2012$
+ * @author 2012, last modified by $Author: pharms$
+ */
+//-------------------------------------------------------------------------------------------------
+public class UsabilityDefectDescriptionTest
+{
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Test
+  public void testInitialization()
+  {
+    for (UsabilityDefectDescription description : UsabilityDefectDescription.values())
+    {
+      assertNotNull(description.toString());
+      assertNotSame("", description.toString());
+      System.err.println(description);
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Test
+  public void testParameterization()
+  {
+    for (UsabilityDefectDescription description : UsabilityDefectDescription.values())
+    {
+      Map<String, String> parameters = new HashMap<String, String>();
+      
+      for (String parameter : description.getDescriptionParameters())
+      {
+        parameters.put(parameter, "<parameter " + parameter + ">");
+      }
+      
+      assertNotNull(description.toString(parameters));
+      assertNotSame("", description.toString(parameters));
+      System.err.println(description.toString(parameters));
+    }
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-usability/.classpath
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usability/.classpath	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usability/.classpath	(revision 540)
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src/main/java"/>
+	<classpathentry kind="src" path="src/main/resources"/>
+	<classpathentry kind="src" path="target/generated-sources/xjc"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
Index: /tags/quest-pre-eventrefactoring/quest-core-usability/.project
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usability/.project	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usability/.project	(revision 540)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>quest-core-usability</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
Index: /tags/quest-pre-eventrefactoring/quest-core-usability/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usability/.settings/org.eclipse.jdt.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usability/.settings/org.eclipse.jdt.core.prefs	(revision 540)
@@ -0,0 +1,12 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.6
Index: /tags/quest-pre-eventrefactoring/quest-core-usability/.settings/org.eclipse.m2e.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usability/.settings/org.eclipse.m2e.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usability/.settings/org.eclipse.m2e.core.prefs	(revision 540)
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
Index: /tags/quest-pre-eventrefactoring/quest-core-usability/pom.xml
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usability/pom.xml	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usability/pom.xml	(revision 540)
@@ -0,0 +1,50 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>de.ugoe.cs.quest</groupId>
+  <artifactId>quest-core-usability</artifactId>
+  <version>0.0.1-SNAPSHOT</version>
+  <name>quest-core-usability</name>
+  <scm>
+    <url>https://quest.informatik.uni-goettingen.de/svn/quest/trunk/quest-core-usability</url>
+  </scm>
+  <dependencies>
+    <dependency>
+        <groupId>de.ugoe.cs.quest</groupId>
+        <artifactId>quest-core-tasktrees</artifactId>
+        <version>0.0.1-SNAPSHOT</version>
+    </dependency>
+  </dependencies>
+  <distributionManagement>
+    <snapshotRepository>
+      <id>quest-snapshots</id>
+      <url>https://trex.informatik.uni-goettingen.de/nexus/content/repositories/quest-snapshots</url>
+    </snapshotRepository>
+  </distributionManagement>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.jvnet.jaxb2.maven2</groupId>
+        <artifactId>maven-jaxb2-plugin</artifactId>
+        <version>0.8.2</version>
+        <configuration>
+          <generatePackage>de.ugoe.cs.quest.usability</generatePackage>
+        </configuration>
+        <executions>
+          <execution>
+            <goals>
+              <goal>generate</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>2.5.1</version>
+        <configuration>
+          <source>1.6</source>
+          <target>1.6</target>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
Index: /tags/quest-pre-eventrefactoring/quest-core-usability/src/main/java/de/ugoe/cs/quest/usability/TextInputStatisticsRule.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usability/src/main/java/de/ugoe/cs/quest/usability/TextInputStatisticsRule.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usability/src/main/java/de/ugoe/cs/quest/usability/TextInputStatisticsRule.java	(revision 540)
@@ -0,0 +1,483 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: TextInputStatisticsRule.java,v $
+// Version   : $Revision: 0.0 $  $Author: pharms $  $Date: 16.07.2012 $
+// Project   : UsabilityEvaluationManager
+// Creation  : 2012 by pharms
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.usability;
+
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import de.ugoe.cs.quest.eventcore.guimodel.TextArea;
+import de.ugoe.cs.quest.eventcore.guimodel.TextField;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTree;
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNode;
+import de.ugoe.cs.quest.tasktrees.treeifc.TextInputInteractionTask;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 16.07.2012$
+ * @author 2012, last modified by $Author: pharms$
+ */
+//-------------------------------------------------------------------------------------------------
+public class TextInputStatisticsRule implements de.ugoe.cs.quest.usability.UsabilityEvaluationRule
+{
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see de.ugoe.cs.usability.UsabilityEvaluationRule#evaluate(TaskTree)
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public UsabilityEvaluationResult evaluate(TaskTree taskTree)
+  {
+    TextInputStatistics statistics = new TextInputStatistics();
+    calculateStatistics(taskTree.getRoot(), statistics);
+    
+    UsabilityEvaluationResult results = new UsabilityEvaluationResult();
+    analyzeStatistics(statistics, results);
+    
+    return results;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param statistics
+   * @param results
+   */
+  //-----------------------------------------------------------------------------------------------
+  private void analyzeStatistics(TextInputStatistics statistics, UsabilityEvaluationResult results)
+  {
+    checkTextInputRatio(statistics, results);
+    checkTextFieldEntryRepetitions(statistics, results);
+    checkTextFieldNoLetterOrDigitInputs(statistics, results);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param statistics
+   * @param results 
+   */
+  //-----------------------------------------------------------------------------------------------
+  private void checkTextInputRatio(TextInputStatistics       statistics,
+                                   UsabilityEvaluationResult results)
+  {
+    float allTextFieldInputs =
+      statistics.getNoOfTextFieldInputs() + statistics.getNoOfTextAreaInputs();
+    
+    float ratio = allTextFieldInputs / (float) statistics.getNoOfAllInteractions();
+    
+    UsabilityDefectSeverity severity = null;
+    if (ratio > 0.9)
+    {
+      severity = UsabilityDefectSeverity.HIGH;
+    }
+    else if (ratio > 0.7)
+    {
+      severity = UsabilityDefectSeverity.MEDIUM;
+    }
+    else if (ratio > 0.5)
+    {
+      severity = UsabilityDefectSeverity.LOW;
+    }
+    else if (ratio > 0.3)
+    {
+      severity = UsabilityDefectSeverity.INFO;
+    }
+    
+    if (severity != null)
+    {
+      Map<String, String> parameters = new HashMap<String, String>();
+      parameters.put("textInputRatio", DecimalFormat.getInstance().format(ratio * 100) + "%");
+      
+      results.addDefect
+        (new UsabilityDefect
+           (severity, UsabilityDefectDescription.TEXT_FIELD_INPUT_RATIO, parameters));
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param statistics
+   * @param results
+   */
+  //-----------------------------------------------------------------------------------------------
+  private void checkTextFieldEntryRepetitions(TextInputStatistics       statistics,
+                                              UsabilityEvaluationResult results)
+  {
+    Map<String, Integer> words = new HashMap<String, Integer>();
+    int numberOfRepeatedWords = 0;
+    int maxRepetitions = 0;
+
+    for (int i = 0; i < statistics.getNoOfTextFieldInputs(); i++)
+    {
+      String[] fragments = statistics.getTextFieldInputFragments(i);
+      for (String fragment : fragments)
+      {
+        if (!"".equals(fragment.trim()))
+        {
+          Integer count = words.get(fragment);
+          if (count == null)
+          {
+            words.put(fragment, 1);
+          }
+          else
+          {
+            count++;
+            words.put(fragment, count);
+            maxRepetitions = Math.max(count, maxRepetitions);
+
+            if (count == 2)
+            {
+              // do not calculate repeated words several times
+              numberOfRepeatedWords++;
+            }
+          }
+        }
+      }
+    }
+    
+    UsabilityDefectSeverity severity = null;
+    if ((numberOfRepeatedWords > 10) || (maxRepetitions > 10))
+    {
+      severity = UsabilityDefectSeverity.HIGH;
+    }
+    else if ((numberOfRepeatedWords > 4) || (maxRepetitions > 4))
+    {
+      severity = UsabilityDefectSeverity.MEDIUM;
+    }
+    else if ((numberOfRepeatedWords > 2) || (maxRepetitions > 2))
+    {
+      severity = UsabilityDefectSeverity.LOW;
+    }
+    else if ((numberOfRepeatedWords > 1) || (maxRepetitions > 1))
+    {
+      severity = UsabilityDefectSeverity.INFO;
+    }
+    
+    if (severity != null)
+    {
+      Map<String, String> parameters = new HashMap<String, String>();
+      parameters.put("textRepetitionRatio", numberOfRepeatedWords + " repeated tokens, up to " +
+                     maxRepetitions + " repetitions per token");
+
+      results.addDefect
+        (new UsabilityDefect
+           (severity, UsabilityDefectDescription.TEXT_FIELD_INPUT_REPETITIONS, parameters));
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param statistics
+   * @param results
+   */
+  //-----------------------------------------------------------------------------------------------
+  private void checkTextFieldNoLetterOrDigitInputs(TextInputStatistics       statistics,
+                                                   UsabilityEvaluationResult results)
+  {
+    int allCharactersCount = 0;
+    int noLetterOrDigitCount = 0;
+
+    for (int i = 0; i < statistics.getNoOfTextFieldInputs(); i++)
+    {
+      String[] fragments = statistics.getTextFieldInputFragments(i);
+      for (String fragment : fragments)
+      {
+        String effectiveFragment = fragment.trim();
+        for (int j = 0; j < effectiveFragment.length(); j++)
+        {
+          if (!Character.isWhitespace(effectiveFragment.charAt(j)))
+          {
+            if (!Character.isLetterOrDigit(effectiveFragment.charAt(j)))
+            {
+              noLetterOrDigitCount++;
+            }
+            allCharactersCount++;
+          }
+        }
+      }
+    }
+    
+    float ratio = (float) noLetterOrDigitCount / (float) allCharactersCount;
+    
+    UsabilityDefectSeverity severity = null;
+    if (ratio > 0.1) // every 10th sign
+    {
+      severity = UsabilityDefectSeverity.HIGH;
+    }
+    else if (ratio > 0.05) // every 20th sign
+    {
+      severity = UsabilityDefectSeverity.MEDIUM;
+    }
+    else if (ratio > 0.02) // every 50th sign
+    {
+      severity = UsabilityDefectSeverity.LOW;
+    }
+    else if (ratio > 0.01) // every 100th sign
+    {
+      severity = UsabilityDefectSeverity.INFO;
+    }
+    
+    if (severity != null)
+    {
+      Map<String, String> parameters = new HashMap<String, String>();
+      parameters.put("noLetterOrDigitRatio", allCharactersCount + " entered characters of " +
+                     "which " + noLetterOrDigitCount + " were no letter or digit");
+
+      results.addDefect
+        (new UsabilityDefect
+           (severity, UsabilityDefectDescription.TEXT_FIELD_NO_LETTER_OR_DIGIT_RATIO, parameters));
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param taskTree
+   * @param statistics
+   */
+  //-----------------------------------------------------------------------------------------------
+  private void calculateStatistics(TaskTreeNode node, TextInputStatistics statistics)
+  {
+    if (node instanceof TextInputInteractionTask)
+    {
+      calculateStatistics((TextInputInteractionTask) node, statistics);
+    }
+    else
+    {
+      if ((node.getChildren() == null) ||
+          (node.getChildren().size() == 0))
+      {
+        statistics.incrementNoOfOtherInteractionTasks();
+      }
+      else
+      {
+        for (TaskTreeNode child : node.getChildren())
+        {
+          calculateStatistics(child, statistics);
+        }
+      }
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param taskTree
+   * @param statistics
+   */
+  //-----------------------------------------------------------------------------------------------
+  private void calculateStatistics(TextInputInteractionTask node, TextInputStatistics statistics)
+  {
+    String[] fragments = determineTextFragments(node.getEnteredText());
+    
+    if (node.getGUIElement() instanceof TextField)
+    {
+      statistics.addTextFieldInput(node, fragments);
+    }
+    else if (node.getGUIElement() instanceof TextArea)
+    {
+      statistics.addTextAreaInput(node, fragments);
+    }
+  }
+  
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param enteredText
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  private String[] determineTextFragments(String enteredText)
+  {
+    List<String> fragments = new ArrayList<String>();
+    
+    StringBuffer fragment = new StringBuffer();
+    char lastChar = 0;
+    
+    for (int i = 0; i < enteredText.length(); i++)
+    {
+      char currentChar = enteredText.charAt(i);
+      
+      if (!isEqualCharacterType(lastChar, currentChar))
+      {
+        // the previous fragment ended. so finalize it and start a new one
+        if ((fragment != null) && (fragment.length() > 0))
+        {
+          fragments.add(fragment.toString());
+          fragment = new StringBuffer();
+        }
+      }
+
+      fragment.append(currentChar);
+      lastChar = currentChar;
+    }
+    
+    if ((fragment != null) && (fragment.length() > 0))
+    {
+      fragments.add(fragment.toString());
+    }
+    
+    return fragments.toArray(new String[fragments.size()]);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param lastChar
+   * @param currentChar
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  private boolean isEqualCharacterType(char char1, char char2)
+  {
+    return
+      ((char1 == char2) ||
+       (Character.isWhitespace(char1) && Character.isWhitespace(char2)) ||
+       (Character.isDigit(char1) && Character.isDigit(char2)) ||
+       (Character.isLetter(char1) && Character.isLetter(char2)) ||
+       (Character.isJavaIdentifierPart(char1) && Character.isJavaIdentifierPart(char2)));
+  }
+
+  //-------------------------------------------------------------------------------------------------
+  /**
+   * TODO comment
+   * 
+   * @version $Revision: $ $Date: 16.07.2012$
+   * @author 2012, last modified by $Author: pharms$
+   */
+  //-------------------------------------------------------------------------------------------------
+  public static class TextInputStatistics
+  {
+    /** */
+    private List<Object[]> mTextFieldInputs = new ArrayList<Object[]>();
+    
+    /** */
+    private List<Object[]> mTextAreaInputs = new ArrayList<Object[]>();
+    
+    /** */
+    private int mOtherInteractionsCount;
+    
+    //-----------------------------------------------------------------------------------------------
+    /**
+     * TODO: comment
+     * @param node 
+     * @param fragments 
+     *
+     */
+    //-----------------------------------------------------------------------------------------------
+    public void addTextFieldInput(TextInputInteractionTask node, String[] fragments)
+    {
+      mTextFieldInputs.add(new Object[] { node, fragments });
+    }
+
+    //-----------------------------------------------------------------------------------------------
+    /**
+     * TODO: comment
+     * @param node 
+     * @param fragments 
+     *
+     */
+    //-----------------------------------------------------------------------------------------------
+    public void addTextAreaInput(TextInputInteractionTask node, String[] fragments)
+    {
+      mTextAreaInputs.add(new Object[] { node, fragments });
+    }
+
+    //-----------------------------------------------------------------------------------------------
+    /**
+     * TODO: comment
+     *
+     * @return
+     */
+    //-----------------------------------------------------------------------------------------------
+    public int getNoOfAllInteractions()
+    {
+      return mTextFieldInputs.size() + mTextAreaInputs.size() + mOtherInteractionsCount;
+    }
+
+    //-----------------------------------------------------------------------------------------------
+    /**
+     * TODO: comment
+     *
+     * @return
+     */
+    //-----------------------------------------------------------------------------------------------
+    public int getNoOfTextFieldInputs()
+    {
+      return mTextFieldInputs.size();
+    }
+
+    //-----------------------------------------------------------------------------------------------
+    /**
+     * TODO: comment
+     *
+     * @param i
+     * @return
+     */
+    //-----------------------------------------------------------------------------------------------
+    public String[] getTextFieldInputFragments(int index)
+    {
+      return (String[]) mTextFieldInputs.get(index)[1];
+    }
+
+    //-----------------------------------------------------------------------------------------------
+    /**
+     * TODO: comment
+     *
+     * @return
+     */
+    //-----------------------------------------------------------------------------------------------
+    public int getNoOfTextAreaInputs()
+    {
+      return mTextAreaInputs.size();
+    }
+
+    //-----------------------------------------------------------------------------------------------
+    /**
+     * TODO: comment
+     *
+     * @param i
+     * @return
+     */
+    //-----------------------------------------------------------------------------------------------
+    public String[] getTextAreaInputFragments(int index)
+    {
+      return (String[]) mTextAreaInputs.get(index)[1];
+    }
+
+    //-----------------------------------------------------------------------------------------------
+    /**
+     * TODO: comment
+     *
+     */
+    //-----------------------------------------------------------------------------------------------
+    public void incrementNoOfOtherInteractionTasks()
+    {
+      mOtherInteractionsCount++;
+    }
+
+    
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-usability/src/main/java/de/ugoe/cs/quest/usability/UsabilityDefect.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usability/src/main/java/de/ugoe/cs/quest/usability/UsabilityDefect.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usability/src/main/java/de/ugoe/cs/quest/usability/UsabilityDefect.java	(revision 540)
@@ -0,0 +1,147 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: UsabilityDefect.java,v $
+// Version   : $Revision: 0.0 $  $Author: pharms $  $Date: 16.07.2012 $
+// Project   : UsabilityEvaluationManager
+// Creation  : 2012 by pharms
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.usability;
+
+import java.util.Map;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 16.07.2012$
+ * @author 2012, last modified by $Author: pharms$
+ */
+//-------------------------------------------------------------------------------------------------
+public class UsabilityDefect
+{
+
+  /** */
+  private UsabilityDefectSeverity mSeverity;
+  
+  /** */
+  private UsabilityDefectDescription mDescription;
+
+  /** */
+  private Map<String, String> mDescriptionParameters;
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param medium
+   * @param highTextInputRatio
+   */
+  //-----------------------------------------------------------------------------------------------
+  public UsabilityDefect(UsabilityDefectSeverity    severity,
+                         UsabilityDefectDescription description)
+  {
+    this(severity, description, null);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param medium
+   * @param highTextInputRatio
+   */
+  //-----------------------------------------------------------------------------------------------
+  public UsabilityDefect(UsabilityDefectSeverity    severity,
+                         UsabilityDefectDescription description,
+                         Map<String, String>        parameters)
+  {
+    mSeverity = severity;
+    mDescription = description;
+    mDescriptionParameters = parameters;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  public UsabilityDefectSeverity getSeverity()
+  {
+    return mSeverity;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * @param severity the severity to set
+   */
+  //-----------------------------------------------------------------------------------------------
+  public void setSeverity(UsabilityDefectSeverity severity)
+  {
+    mSeverity = severity;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * @param description the description to set
+   */
+  //-----------------------------------------------------------------------------------------------
+  public void setDescription(UsabilityDefectDescription description)
+  {
+    mDescription = description;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * 
+   */
+  //-----------------------------------------------------------------------------------------------
+  public String getParameterizedDescription()
+  {
+    return mDescription.toString(mDescriptionParameters);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see java.lang.Object#equals(java.lang.Object)
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public boolean equals(Object obj)
+  {
+    if (obj instanceof UsabilityDefect)
+    {
+      return
+        (mSeverity == ((UsabilityDefect) obj).mSeverity) &&
+        (mDescription == ((UsabilityDefect) obj).mDescription);
+    }
+    else
+    {
+      return false;
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see java.lang.Object#hashCode()
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public int hashCode()
+  {
+    return mSeverity.hashCode() + mDescription.hashCode();
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see java.lang.Object#toString()
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public String toString()
+  {
+    return "UsabilityDefect(" + mSeverity.name() + ", " + mDescription.name() + ")";
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-usability/src/main/java/de/ugoe/cs/quest/usability/UsabilityDefectDescription.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usability/src/main/java/de/ugoe/cs/quest/usability/UsabilityDefectDescription.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usability/src/main/java/de/ugoe/cs/quest/usability/UsabilityDefectDescription.java	(revision 540)
@@ -0,0 +1,236 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: UsabilityDefectDescriptions.java,v $
+// Version   : $Revision: 0.0 $  $Author: pharms $  $Date: 18.07.2012 $
+// Project   : UsabilityEvaluationManager
+// Creation  : 2012 by pharms
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.usability;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.Unmarshaller;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 18.07.2012$
+ * @author 2012, last modified by $Author: pharms$
+ */
+//-------------------------------------------------------------------------------------------------
+public enum UsabilityDefectDescription
+{
+  TEXT_FIELD_INPUT_RATIO,
+  TEXT_FIELD_INPUT_REPETITIONS,
+  TEXT_FIELD_NO_LETTER_OR_DIGIT_RATIO;
+
+  /** */
+  private static final String DEFAULT_MESSAGES_FILE = "defectDescriptions_en.xml";
+  
+  /** */
+  private static DefectDescriptions sDefectDescriptions;
+
+  /** */
+  private DefectDescription mDefectDescription;
+  
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param name
+   * @param ordinal
+   */
+  //-----------------------------------------------------------------------------------------------
+  private UsabilityDefectDescription()
+  {
+    init();
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  @SuppressWarnings("unchecked")
+  private void init()
+  {
+    synchronized (this.getClass())
+    {
+      if (sDefectDescriptions == null)
+      {
+        InputStream inputStream = ClassLoader.getSystemResourceAsStream(DEFAULT_MESSAGES_FILE);
+
+        try
+        {
+          String packageName = DefectDescriptions.class.getPackage().getName();
+          JAXBContext jaxbContext = JAXBContext.newInstance(packageName);
+          Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
+        
+          sDefectDescriptions =
+            ((JAXBElement<DefectDescriptions>) unmarshaller.unmarshal(inputStream)).getValue();
+        }
+        catch (Exception e)
+        {
+          throw new RuntimeException("error while initializing usability defect descriptions", e);
+        }
+        finally
+        {
+          if (inputStream != null)
+          {
+            try
+            {
+              inputStream.close();
+            }
+            catch (IOException e)
+            {
+              // ignore
+            }
+          }
+        }
+      }
+    }
+    
+    for (DefectDescription description : sDefectDescriptions.getDefectDescription())
+    {
+      if (this.name().equals(description.getDefectId()))
+      {
+        mDefectDescription = description;
+        break;
+      }
+    }
+    
+    if (mDefectDescription == null)
+    {
+      throw new RuntimeException("error while initializing usability defect descriptions. No " +
+                                 "description text available for description " + this.name());
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * 
+   */
+  //-----------------------------------------------------------------------------------------------
+  public String[] getDescriptionParameters()
+  {
+    List<String> parameters = new ArrayList<String>();
+    
+    for (Object fragment : mDefectDescription.getTextFragmentOrParameterFragment())
+    {
+      if (fragment instanceof ParameterFragment)
+      {
+        parameters.add(((ParameterFragment) fragment).getParameterName());
+      }
+    }
+    
+    return parameters.toArray(new String[parameters.size()]);
+  }
+  
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * 
+   */
+  //-----------------------------------------------------------------------------------------------
+  public String toString(Map<String, String> parameters) throws IllegalArgumentException
+  {
+    StringBuffer result = new StringBuffer();
+    
+    for (Object fragment : mDefectDescription.getTextFragmentOrParameterFragment())
+    {
+      if (result.length() > 0)
+      {
+        result.append(" ");
+      }
+      
+      if (fragment instanceof ParameterFragment)
+      {
+        String value = null;
+        if (parameters != null)
+        {
+          value = parameters.get(((ParameterFragment) fragment).getParameterName());
+        }
+        
+        if (value != null)
+        {
+          result.append(value);
+        }
+        else
+        {
+          throw new IllegalArgumentException
+            ("required parameter \"" + ((ParameterFragment) fragment).getParameterName() +
+             "\" for usability defect description " + this.name() + " not provided");
+        }
+      }
+      else
+      {
+        result.append(getFragmentString(fragment));
+      }
+    }
+    
+    return result.toString();
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see java.lang.Enum#toString()
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public String toString()
+  {
+    StringBuffer result = new StringBuffer();
+    
+    int paramCount = 1;
+    for (Object fragment : mDefectDescription.getTextFragmentOrParameterFragment())
+    {
+      if (result.length() > 0)
+      {
+        result.append(" ");
+      }
+      
+      if (fragment instanceof ParameterFragment)
+      {
+        result.append("<parameter");
+        result.append(paramCount++);
+        result.append(">");
+      }
+      else
+      {
+        result.append(getFragmentString(fragment));
+      }
+    }
+    
+    return result.toString();
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param fragment
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  private String getFragmentString(Object fragment)
+  {
+    String fragmentStr = fragment.toString().trim();
+    
+    fragmentStr = fragmentStr.replaceAll("\n", " ");
+    
+    while (fragmentStr.indexOf("  ") > -1)
+    {
+      fragmentStr = fragmentStr.replaceAll("  ", " ");
+    }
+    
+    return fragmentStr;
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-usability/src/main/java/de/ugoe/cs/quest/usability/UsabilityDefectSeverity.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usability/src/main/java/de/ugoe/cs/quest/usability/UsabilityDefectSeverity.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usability/src/main/java/de/ugoe/cs/quest/usability/UsabilityDefectSeverity.java	(revision 540)
@@ -0,0 +1,24 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: UsabilityDefectSeverity.java,v $
+// Version   : $Revision: 0.0 $  $Author: pharms $  $Date: 16.07.2012 $
+// Project   : UsabilityEvaluationManager
+// Creation  : 2012 by pharms
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.usability;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 16.07.2012$
+ * @author 2012, last modified by $Author: pharms$
+ */
+//-------------------------------------------------------------------------------------------------
+public enum UsabilityDefectSeverity
+{
+  INFO,
+  LOW,
+  MEDIUM,
+  HIGH;
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-usability/src/main/java/de/ugoe/cs/quest/usability/UsabilityEvaluationManager.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usability/src/main/java/de/ugoe/cs/quest/usability/UsabilityEvaluationManager.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usability/src/main/java/de/ugoe/cs/quest/usability/UsabilityEvaluationManager.java	(revision 540)
@@ -0,0 +1,106 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: UsabilityEvaluationManager.java,v $
+// Version   : $Revision: 0.0 $  $Author: pharms $  $Date: 16.07.2012 $
+// Project   : UsabilityEvaluationManager
+// Creation  : 2012 by pharms
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.usability;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Logger;
+
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTree;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 16.07.2012$
+ * @author 2012, last modified by $Author: pharms$
+ */
+//-------------------------------------------------------------------------------------------------
+public class UsabilityEvaluationManager
+{
+  /** */
+  private static Logger LOG = Logger.getLogger(UsabilityEvaluationManager.class.getName());
+
+  /** */
+  private List<UsabilityEvaluationRule> mRules = new ArrayList<UsabilityEvaluationRule>();
+  
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  public UsabilityEvaluationManager()
+  {
+    super();
+    init();
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  private void init()
+  {
+    mRules.add(new TextInputStatisticsRule());
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param taskTree
+   */
+  //-----------------------------------------------------------------------------------------------
+  public UsabilityEvaluationResult evaluateUsability(TaskTree taskTree)
+  {
+    LOG.info("evaluating usability of task tree " + taskTree);
+    
+    List<UsabilityEvaluationResult> results = new ArrayList<UsabilityEvaluationResult>();
+    
+    for (UsabilityEvaluationRule rule : mRules)
+    {
+      LOG.info("applying rule " + rule.getClass().getSimpleName());
+      UsabilityEvaluationResult result = rule.evaluate(taskTree);
+      results.add(result);
+      LOG.info("the rule found " + result.getAllDefects().size() + " usability defects, of " +
+                "which " + result.getSevereDefects().size() + " are severe.");
+    }
+    
+    UsabilityEvaluationResult result = mergeResults(results);
+    LOG.info("the evaluation result contains " + result.getAllDefects().size() + " defects, of " +
+             "which " + result.getSevereDefects().size() + " are severe.");
+    return result;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param results
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  private UsabilityEvaluationResult mergeResults(List<UsabilityEvaluationResult> results)
+  {
+    UsabilityEvaluationResult result = new UsabilityEvaluationResult();
+    
+    for (UsabilityEvaluationResult ruleResult : results)
+    {
+      for (UsabilityDefect defect : ruleResult.getAllDefects())
+      {
+        result.addDefect(defect);
+      }
+    }
+    
+    return result;
+  }
+  
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-usability/src/main/java/de/ugoe/cs/quest/usability/UsabilityEvaluationResult.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usability/src/main/java/de/ugoe/cs/quest/usability/UsabilityEvaluationResult.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usability/src/main/java/de/ugoe/cs/quest/usability/UsabilityEvaluationResult.java	(revision 540)
@@ -0,0 +1,72 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: UsabilityEvaluationResult.java,v $
+// Version   : $Revision: 0.0 $  $Author: pharms $  $Date: 16.07.2012 $
+// Project   : UsabilityEvaluationManager
+// Creation  : 2012 by pharms
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.usability;
+
+import java.util.ArrayList;
+import java.util.List;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 16.07.2012$
+ * @author 2012, last modified by $Author: pharms$
+ */
+//-------------------------------------------------------------------------------------------------
+public class UsabilityEvaluationResult
+{
+  /** */
+  private List<UsabilityDefect> mDefects = new ArrayList<UsabilityDefect>();
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param defect
+   */
+  //-----------------------------------------------------------------------------------------------
+  public void addDefect(UsabilityDefect defect)
+  {
+    mDefects.add(defect);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  public List<UsabilityDefect> getAllDefects()
+  {
+    return mDefects;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  public List<UsabilityDefect> getSevereDefects()
+  {
+    List<UsabilityDefect> severeDefects = new ArrayList<UsabilityDefect>();
+    
+    for (UsabilityDefect defect : mDefects)
+    {
+      if (defect.getSeverity() == UsabilityDefectSeverity.HIGH)
+      {
+        severeDefects.add(defect);
+      }
+    }
+    
+    return severeDefects;
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-usability/src/main/java/de/ugoe/cs/quest/usability/UsabilityEvaluationRule.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usability/src/main/java/de/ugoe/cs/quest/usability/UsabilityEvaluationRule.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usability/src/main/java/de/ugoe/cs/quest/usability/UsabilityEvaluationRule.java	(revision 540)
@@ -0,0 +1,33 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: UsabilityEvaluationRule.java,v $
+// Version   : $Revision: 0.0 $  $Author: pharms $  $Date: 16.07.2012 $
+// Project   : UsabilityEvaluationManager
+// Creation  : 2012 by pharms
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.quest.usability;
+
+import de.ugoe.cs.quest.tasktrees.treeifc.TaskTree;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 16.07.2012$
+ * @author 2012, last modified by $Author: pharms$
+ */
+//-------------------------------------------------------------------------------------------------
+public interface UsabilityEvaluationRule
+{
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param taskTree
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  UsabilityEvaluationResult evaluate(TaskTree taskTree);
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-usability/src/main/resources/defectDescriptions.xsd
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usability/src/main/resources/defectDescriptions.xsd	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usability/src/main/resources/defectDescriptions.xsd	(revision 540)
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema
+  targetNamespace="http://quest"
+  xmlns:tns="http://quest"
+  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+  xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
+  jxb:version="2.0"
+  elementFormDefault="qualified">
+  
+  <xsd:element name="defectDescriptions" type="tns:DefectDescriptions" />
+
+  <xsd:complexType name="DefectDescriptions">
+    <xsd:sequence>
+      <xsd:element name="defectDescription" type="tns:DefectDescription" maxOccurs="unbounded" />
+    </xsd:sequence>
+  </xsd:complexType>
+
+  <xsd:complexType name="DefectDescription">
+    <xsd:choice maxOccurs="unbounded">
+      <xsd:element name="textFragment" type="tns:SimpleFragment" />
+      <xsd:element name="parameterFragment" type="tns:ParameterFragment" />
+    </xsd:choice>
+    <xsd:attribute name="defectId" type="xsd:string" use="required" />
+  </xsd:complexType>
+
+  <xsd:simpleType name="SimpleFragment">
+    <xsd:restriction base="xsd:string"/>
+  </xsd:simpleType>
+
+  <xsd:complexType name="ParameterFragment">
+    <xsd:attribute name="parameterName" use="required" type="xsd:string" />
+  </xsd:complexType>
+
+</xsd:schema>
Index: /tags/quest-pre-eventrefactoring/quest-core-usability/src/main/resources/defectDescriptions_en.xml
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usability/src/main/resources/defectDescriptions_en.xml	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usability/src/main/resources/defectDescriptions_en.xml	(revision 540)
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<defectDescriptions
+  xmlns="http://quest"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://quest defectDescriptions.xsd">
+  
+  <defectDescription defectId="TEXT_FIELD_INPUT_RATIO">
+    <textFragment>
+      The ratio of interactions that enter text into text fields is relatively high in comparison
+      with the other user interactions (
+    </textFragment>
+    <parameterFragment parameterName="textInputRatio" />
+    <textFragment>
+      ). This should be reduced. As an example, entering data can also be done using check boxes
+      or combo boxes in the case predefined values must be entered.
+    </textFragment>
+  </defectDescription>
+  
+  <defectDescription defectId="TEXT_FIELD_INPUT_REPETITIONS">
+    <textFragment>
+      Several interactions that enter text into text fields repeat tokens such as words or
+      specific signs (
+    </textFragment>
+    <parameterFragment parameterName="textRepetitionRatio" />
+    <textFragment>
+      ). This is an indicator that the same data must be entered several times. This could be
+      better supported by using e.g. automatic filling of input fields, provision of combo
+      boxes or lists prefilled with data that was already entered previously. 
+    </textFragment>
+  </defectDescription>
+  
+  <defectDescription defectId="TEXT_FIELD_NO_LETTER_OR_DIGIT_RATIO">
+    <textFragment>
+      Much of the text entered into text fields contains signs other than letters or digits (
+    </textFragment>
+    <parameterFragment parameterName="noLetterOrDigitRatio" />
+    <textFragment>
+      ). This is an indicator that the entered data has to follow a specific syntax. This should
+      be supported by syntax checking, auto completion or even providing the text fields in a way
+      that does not require the entering of special signs as they are already included at the right
+      positions.
+    </textFragment>
+  </defectDescription>
+</defectDescriptions>
Index: /tags/quest-pre-eventrefactoring/quest-core-usageprofiles-test/.classpath
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usageprofiles-test/.classpath	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usageprofiles-test/.classpath	(revision 540)
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/test-classes" path="src/test/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
Index: /tags/quest-pre-eventrefactoring/quest-core-usageprofiles-test/.project
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usageprofiles-test/.project	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usageprofiles-test/.project	(revision 540)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>quest-core-usageprofiles-test</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
Index: /tags/quest-pre-eventrefactoring/quest-core-usageprofiles-test/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usageprofiles-test/.settings/org.eclipse.jdt.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usageprofiles-test/.settings/org.eclipse.jdt.core.prefs	(revision 540)
@@ -0,0 +1,5 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.6
Index: /tags/quest-pre-eventrefactoring/quest-core-usageprofiles-test/.settings/org.eclipse.m2e.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usageprofiles-test/.settings/org.eclipse.m2e.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usageprofiles-test/.settings/org.eclipse.m2e.core.prefs	(revision 540)
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
Index: /tags/quest-pre-eventrefactoring/quest-core-usageprofiles-test/pom.xml
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usageprofiles-test/pom.xml	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usageprofiles-test/pom.xml	(revision 540)
@@ -0,0 +1,139 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>de.ugoe.cs.quest</groupId>
+  <artifactId>quest-core-usageprofiles-test</artifactId>
+  <version>0.0.1-SNAPSHOT</version>
+  <name>quest-core-usageprofiles-test</name>
+  <scm>
+    <url>https://quest.informatik.uni-goettingen.de/svn/quest/trunk/quest-core-usageprofiles-test</url>
+  </scm>
+  <dependencies>
+    <dependency>
+        <groupId>de.ugoe.cs.quest</groupId>
+        <artifactId>quest-core-events</artifactId>
+        <version>0.0.1-SNAPSHOT</version>
+        <scope>test</scope>
+    </dependency>
+    <dependency>
+			<groupId>de.ugoe.cs.quest</groupId>
+			<artifactId>quest-core-usageprofiles</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+			<scope>test</scope>
+		</dependency>
+    <dependency>
+        <groupId>junit</groupId>
+        <artifactId>junit</artifactId>
+        <version>4.8.1</version>
+        <scope>test</scope>
+    </dependency>
+    <dependency>
+	  <groupId>junit-addons</groupId>
+	  <artifactId>junit-addons</artifactId>
+	  <version>1.4</version>
+    </dependency>
+  </dependencies>
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.eclipse.m2e</groupId>
+          <artifactId>lifecycle-mapping</artifactId>
+          <version>1.0.0</version>
+          <configuration>
+            <lifecycleMappingMetadata>
+              <pluginExecutions>
+                <pluginExecution>
+                  <pluginExecutionFilter>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-dependency-plugin</artifactId>
+                    <versionRange>[1.0.0,)</versionRange>
+                    <goals>
+                      <goal>unpack</goal>
+                    </goals>
+                  </pluginExecutionFilter>
+                  <action>
+                    <ignore/>
+                  </action>
+                </pluginExecution>
+                <pluginExecution>
+                  <pluginExecutionFilter>
+                    <groupId>org.codehaus.mojo</groupId>
+                    <artifactId>emma-maven-plugin</artifactId>
+                    <versionRange>[1.0-alpha-3,)</versionRange>
+                    <goals>
+                      <goal>emma</goal>
+                    </goals>
+                  </pluginExecutionFilter>
+                  <action>
+                    <ignore/>
+                  </action>
+                </pluginExecution>
+              </pluginExecutions>
+            </lifecycleMappingMetadata>
+          </configuration>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>2.3.2</version>
+        <configuration>
+          <source>1.6</source>
+          <target>1.6</target>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-dependency-plugin</artifactId>
+        <version>2.4</version>
+        <executions>
+          <execution>
+            <id>unpack</id>
+            <phase>process-classes</phase>
+            <goals>
+              <goal>unpack</goal>
+            </goals>
+            <configuration>
+              <artifactItems>
+                <artifactItem>
+                  <groupId>de.ugoe.cs.quest</groupId>
+                  <artifactId>quest-core-usageprofiles</artifactId>
+                  <version>0.0.1-SNAPSHOT</version>
+                  <outputDirectory>${project.build.directory}/classes</outputDirectory>
+                </artifactItem>
+              </artifactItems>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>emma-maven-plugin</artifactId>
+        <version>1.0-alpha-3</version>
+        <inherited>true</inherited>          
+        <executions>
+          <execution>
+            <phase>process-classes</phase>
+            <goals>
+              <goal>emma</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <version>2.3.2</version>
+        <executions>
+          <execution>
+            <goals>
+              <goal>test-jar</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>
Index: /tags/quest-pre-eventrefactoring/quest-core-usageprofiles-test/src/test/java/de/ugoe/cs/quest/usageprofiles/DeterministicFiniteAutomatonTest.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usageprofiles-test/src/test/java/de/ugoe/cs/quest/usageprofiles/DeterministicFiniteAutomatonTest.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usageprofiles-test/src/test/java/de/ugoe/cs/quest/usageprofiles/DeterministicFiniteAutomatonTest.java	(revision 540)
@@ -0,0 +1,157 @@
+package de.ugoe.cs.quest.usageprofiles;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.usageprofiles.DeterministicFiniteAutomaton;
+
+import java.util.Random;
+import org.junit.*;
+
+import static org.junit.Assert.*;
+
+/**
+ * The class <code>DeterministicFiniteAutomatonTest</code> contains tests for
+ * the class <code>{@link DeterministicFiniteAutomaton}</code>.
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class DeterministicFiniteAutomatonTest {
+
+	Collection<List<? extends Event<?>>> sequences;
+
+	@Test
+	public void testDeterministicFiniteAutomaton_1() throws Exception {
+		Random r = new Random();
+
+		DeterministicFiniteAutomaton result = new DeterministicFiniteAutomaton(
+				r);
+
+		assertNotNull(result);
+		assertEquals(2, result.trieOrder);
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testDeterministicFiniteAutomaton_2() throws Exception {
+		new DeterministicFiniteAutomaton(null);
+	}
+
+	@Test
+	public void testGetProbability_1() throws Exception {
+		DeterministicFiniteAutomaton fixture = new DeterministicFiniteAutomaton(
+				new Random());
+		fixture.train(sequences);
+
+		List<Event<String>> context = new ArrayList<Event<String>>();
+		context.add(new Event<String>("a"));
+		context.add(new Event<String>("b"));
+
+		Event<String> symbol = new Event<String>("r");
+
+		double result = fixture.getProbability(context, symbol);
+
+		assertEquals(1.0d, result, 0.0001);
+	}
+
+	@Test
+	public void testGetProbability_2() throws Exception {
+		DeterministicFiniteAutomaton fixture = new DeterministicFiniteAutomaton(
+				new Random());
+		fixture.train(sequences);
+
+		List<Event<String>> context = new ArrayList<Event<String>>();
+		context.add(new Event<String>("a"));
+
+		Event<String> symbol = new Event<String>("b");
+
+		double result = fixture.getProbability(context, symbol);
+
+		assertEquals(1.0d / 4.0, result, 0.0001);
+	}
+
+	@Test
+	public void testGetProbability_3() throws Exception {
+		DeterministicFiniteAutomaton fixture = new DeterministicFiniteAutomaton(
+				new Random());
+		fixture.train(sequences);
+
+		List<Event<String>> context = new ArrayList<Event<String>>();
+		context.add(new Event<String>("a"));
+
+		Event<String> symbol = new Event<String>("c");
+
+		double result = fixture.getProbability(context, symbol);
+
+		assertEquals(1.0d / 4.0, result, 0.0001);
+	}
+
+	@Test
+	public void testGetProbability_4() throws Exception {
+		DeterministicFiniteAutomaton fixture = new DeterministicFiniteAutomaton(
+				new Random());
+		fixture.train(sequences);
+
+		List<Event<String>> context = new ArrayList<Event<String>>();
+		context.add(new Event<String>("a"));
+
+		Event<String> symbol = new Event<String>("e");
+
+		double result = fixture.getProbability(context, symbol);
+
+		assertEquals(0.0d, result, 0.0001);
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testGetProbability_5() throws Exception {
+		DeterministicFiniteAutomaton fixture = new DeterministicFiniteAutomaton(
+				new Random());
+		fixture.train(sequences);
+
+		List<Event<String>> context = new ArrayList<Event<String>>();
+		context.add(new Event<String>("a"));
+
+		Event<String> symbol = null;
+
+		fixture.getProbability(context, symbol);
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testGetProbability_6() throws Exception {
+		DeterministicFiniteAutomaton fixture = new DeterministicFiniteAutomaton(
+				new Random());
+		fixture.train(sequences);
+
+		List<Event<String>> context = null;
+
+		Event<String> symbol = new Event<String>("a");
+
+		fixture.getProbability(context, symbol);
+	}
+
+	@Before
+	public void setUp() throws Exception {
+		List<Event<?>> sequence = new ArrayList<Event<?>>();
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("b"));
+		sequence.add(new Event<String>("r"));
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("c"));
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("d"));
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("b"));
+		sequence.add(new Event<String>("r"));
+		sequence.add(new Event<String>("a"));
+
+		sequences = new ArrayList<List<? extends Event<?>>>();
+		sequences.add(sequence);
+	}
+
+	public static void main(String[] args) {
+		new org.junit.runner.JUnitCore()
+				.run(DeterministicFiniteAutomatonTest.class);
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-usageprofiles-test/src/test/java/de/ugoe/cs/quest/usageprofiles/FirstOrderMarkovModelTest.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usageprofiles-test/src/test/java/de/ugoe/cs/quest/usageprofiles/FirstOrderMarkovModelTest.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usageprofiles-test/src/test/java/de/ugoe/cs/quest/usageprofiles/FirstOrderMarkovModelTest.java	(revision 540)
@@ -0,0 +1,94 @@
+package de.ugoe.cs.quest.usageprofiles;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Random;
+import org.junit.*;
+
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.usageprofiles.FirstOrderMarkovModel;
+import de.ugoe.cs.quest.usageprofiles.FirstOrderMarkovModel.MarkovEdge;
+import static org.junit.Assert.*;
+
+/**
+ * The class <code>FirstOrderMarkovModelTest</code> contains tests for the class
+ * <code>{@link FirstOrderMarkovModel}</code>.
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class FirstOrderMarkovModelTest {
+
+	Collection<List<? extends Event<?>>> sequences;
+	
+	@Test
+	public void testFirstOrderMarkovModel_1() throws Exception {
+		Random r = new Random();
+
+		FirstOrderMarkovModel result = new FirstOrderMarkovModel(r);
+
+		assertNotNull(result);
+		assertEquals(r, result.r);
+		assertEquals(2, result.trieOrder);
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testFirstOrderMarkovModel_2() throws Exception {
+		new FirstOrderMarkovModel(null);
+	}
+	
+	@Test
+	public void testCalcEntropy() throws Exception {
+		Random r = new Random();
+		FirstOrderMarkovModel fixture = new FirstOrderMarkovModel(r);
+		fixture.train(sequences);
+		
+		double result = fixture.calcEntropy();
+		
+		assertEquals(0.7392d, result, 0.0001);
+	}
+	
+	@Test
+	public void testMarkovEdgeMarkovEdge_1() throws Exception {
+		double weight = 0.2d;
+		
+		MarkovEdge result = new MarkovEdge(weight);
+		
+		assertNotNull(result);
+		assertEquals(weight, result.weight, 0.0001);
+	}
+	
+	@Test
+	public void testMarkovEdgeToString_1() throws Exception {
+		double weight = 0.2d;
+		MarkovEdge fixture = new MarkovEdge(weight);
+		
+		String result = fixture.toString();
+		
+		assertEquals(Double.toString(0.2d), result);
+	}
+	
+	@Before
+	public void setUp() throws Exception {
+		List<Event<?>> sequence = new ArrayList<Event<?>>();
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("b"));
+		sequence.add(new Event<String>("r"));
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("c"));
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("d"));
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("b"));
+		sequence.add(new Event<String>("r"));
+		sequence.add(new Event<String>("a"));
+
+		sequences = new ArrayList<List<? extends Event<?>>>();
+		sequences.add(sequence);
+	}
+
+	public static void main(String[] args) {
+		new org.junit.runner.JUnitCore().run(FirstOrderMarkovModelTest.class);
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-usageprofiles-test/src/test/java/de/ugoe/cs/quest/usageprofiles/HighOrderMarkovModelTest.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usageprofiles-test/src/test/java/de/ugoe/cs/quest/usageprofiles/HighOrderMarkovModelTest.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usageprofiles-test/src/test/java/de/ugoe/cs/quest/usageprofiles/HighOrderMarkovModelTest.java	(revision 540)
@@ -0,0 +1,241 @@
+package de.ugoe.cs.quest.usageprofiles;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.usageprofiles.HighOrderMarkovModel;
+
+import java.util.Random;
+import org.junit.*;
+
+import static org.junit.Assert.*;
+
+/**
+ * The class <code>HighOrderMarkovModelTest</code> contains tests for the class
+ * <code>{@link HighOrderMarkovModel}</code>.
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class HighOrderMarkovModelTest {
+
+	Collection<List<? extends Event<?>>> sequences;
+
+	@Test
+	public void testHighOrderMarkovModel_1() throws Exception {
+		int maxOrder = 1;
+		Random r = new Random();
+
+		HighOrderMarkovModel result = new HighOrderMarkovModel(maxOrder, r);
+
+		assertNotNull(result);
+		assertEquals(r, result.r);
+		assertEquals(maxOrder + 1, result.trieOrder);
+	}
+
+	@Test
+	public void testHighOrderMarkovModel_2() throws Exception {
+		int maxOrder = 0;
+		Random r = new Random();
+
+		HighOrderMarkovModel result = new HighOrderMarkovModel(maxOrder, r);
+
+		assertNotNull(result);
+		assertEquals(r, result.r);
+		assertEquals(maxOrder + 1, result.trieOrder);
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testHighOrderMarkovModel_3() throws Exception {
+		int maxOrder = 1;
+		Random r = null;
+
+		new HighOrderMarkovModel(maxOrder, r);
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testHighOrderMarkovModel_4() throws Exception {
+		int maxOrder = -1;
+		Random r = new Random();
+
+		new HighOrderMarkovModel(maxOrder, r);
+	}
+
+	@Test
+	public void testGetProbability_1() throws Exception {
+		int markovOrder = 1;
+		HighOrderMarkovModel fixture = new HighOrderMarkovModel(markovOrder,
+				new Random());
+		fixture.train(sequences);
+
+		List<Event<String>> context = new ArrayList<Event<String>>();
+		context.add(new Event<String>("a"));
+
+		Event<String> symbol = new Event<String>("b");
+
+		double result = fixture.getProbability(context, symbol);
+
+		assertEquals(2.0d / 5.0, result, 0.0001);
+	}
+
+	@Test
+	public void testGetProbability_2() throws Exception {
+		int markovOrder = 1;
+		HighOrderMarkovModel fixture = new HighOrderMarkovModel(markovOrder,
+				new Random());
+		fixture.train(sequences);
+
+		List<Event<String>> context = new ArrayList<Event<String>>();
+		context.add(new Event<String>("a"));
+
+		Event<String> symbol = new Event<String>("r");
+
+		double result = fixture.getProbability(context, symbol);
+
+		assertEquals(0.0d / 5.0, result, 0.0001);
+	}
+
+	@Test
+	public void testGetProbability_3() throws Exception {
+		int markovOrder = 1;
+		HighOrderMarkovModel fixture = new HighOrderMarkovModel(markovOrder,
+				new Random());
+		fixture.train(sequences);
+
+		List<Event<String>> context = new ArrayList<Event<String>>();
+		context.add(new Event<String>("a"));
+
+		Event<String> symbol = new Event<String>("c");
+
+		double result = fixture.getProbability(context, symbol);
+
+		assertEquals(1.0d / 5.0, result, 0.0001);
+	}
+
+	@Test
+	public void testGetProbability_4() throws Exception {
+		int markovOrder = 1;
+		HighOrderMarkovModel fixture = new HighOrderMarkovModel(markovOrder,
+				new Random());
+		fixture.train(sequences);
+
+		List<Event<?>> context = new ArrayList<Event<?>>();
+		context.add(Event.STARTEVENT);
+		context.add(new Event<String>("a"));
+
+		Event<String> symbol = new Event<String>("b");
+
+		double result = fixture.getProbability(context, symbol);
+
+		assertEquals(2.0d / 5.0, result, 0.0001);
+	}
+
+	@Test
+	public void testGetProbability_5() throws Exception {
+		int markovOrder = 2;
+		HighOrderMarkovModel fixture = new HighOrderMarkovModel(markovOrder,
+				new Random());
+		fixture.train(sequences);
+
+		List<Event<?>> context = new ArrayList<Event<?>>();
+		context.add(Event.STARTEVENT);
+		context.add(new Event<String>("a"));
+
+		Event<String> symbol = new Event<String>("b");
+
+		double result = fixture.getProbability(context, symbol);
+
+		assertEquals(1.0d, result, 0.0001);
+	}
+
+	@Test
+	public void testGetProbability_6() throws Exception {
+		int markovOrder = 2;
+		HighOrderMarkovModel fixture = new HighOrderMarkovModel(markovOrder,
+				new Random());
+		fixture.train(sequences);
+
+		List<Event<?>> context = new ArrayList<Event<?>>();
+		context.add(Event.STARTEVENT);
+		context.add(new Event<String>("b"));
+
+		Event<String> symbol = new Event<String>("b");
+
+		double result = fixture.getProbability(context, symbol);
+
+		assertEquals(0.0d, result, 0.0001);
+	}
+
+	@Test
+	public void testGetProbability_7() throws Exception {
+		int markovOrder = 0;
+		HighOrderMarkovModel fixture = new HighOrderMarkovModel(markovOrder,
+				new Random());
+		fixture.train(sequences);
+
+		List<Event<?>> context = new ArrayList<Event<?>>();
+		context.add(Event.STARTEVENT);
+		context.add(new Event<String>("b"));
+
+		Event<String> symbol = new Event<String>("a");
+
+		double result = fixture.getProbability(context, symbol);
+
+		assertEquals(5.0d / 13.0, result, 0.0001);
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testGetProbability_8() throws Exception {
+		int markovOrder = 0;
+		HighOrderMarkovModel fixture = new HighOrderMarkovModel(markovOrder,
+				new Random());
+		fixture.train(sequences);
+
+		List<Event<?>> context = new ArrayList<Event<?>>();
+		context.add(Event.STARTEVENT);
+		context.add(new Event<String>("b"));
+
+		Event<String> symbol = null;
+
+		fixture.getProbability(context, symbol);
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testGetProbability_9() throws Exception {
+		int markovOrder = 0;
+		HighOrderMarkovModel fixture = new HighOrderMarkovModel(markovOrder,
+				new Random());
+		fixture.train(sequences);
+
+		List<Event<?>> context = null;
+
+		Event<String> symbol = new Event<String>("b");
+
+		fixture.getProbability(context, symbol);
+	}
+
+	@Before
+	public void setUp() throws Exception {
+		List<Event<?>> sequence = new ArrayList<Event<?>>();
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("b"));
+		sequence.add(new Event<String>("r"));
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("c"));
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("d"));
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("b"));
+		sequence.add(new Event<String>("r"));
+		sequence.add(new Event<String>("a"));
+
+		sequences = new ArrayList<List<? extends Event<?>>>();
+		sequences.add(sequence);
+	}
+
+	public static void main(String[] args) {
+		new org.junit.runner.JUnitCore().run(HighOrderMarkovModelTest.class);
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-usageprofiles-test/src/test/java/de/ugoe/cs/quest/usageprofiles/IncompleteMemoryTest.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usageprofiles-test/src/test/java/de/ugoe/cs/quest/usageprofiles/IncompleteMemoryTest.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usageprofiles-test/src/test/java/de/ugoe/cs/quest/usageprofiles/IncompleteMemoryTest.java	(revision 540)
@@ -0,0 +1,152 @@
+package de.ugoe.cs.quest.usageprofiles;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.junit.*;
+
+import de.ugoe.cs.quest.usageprofiles.IncompleteMemory;
+import static org.junit.Assert.*;
+
+/**
+ * The class <code>IncompleteMemoryTest</code> contains tests for the class <code>{@link IncompleteMemory}</code>.
+ *
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class IncompleteMemoryTest {
+
+	@Test
+	public void testIncompleteMemory_1()
+		throws Exception {
+		int length = 1;
+
+		IncompleteMemory<String> result = new IncompleteMemory<String>(length);
+
+		assertNotNull(result);
+		assertEquals(0, result.getLast(1).size());
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testIncompleteMemory_2()
+		throws Exception {
+		int length = 0;
+
+		new IncompleteMemory<String>(length);
+	}
+
+	@Test
+	public void testGetLast_1()
+		throws Exception {
+		int length = 2;
+		IncompleteMemory<String> fixture = new IncompleteMemory<String>(length);
+		fixture.add("1");
+		fixture.add("2");
+		fixture.add("3");
+		int num = -1;
+
+		List<String> result = fixture.getLast(num);
+
+		assertNotNull(result);
+		assertEquals(0, result.size());
+	}
+
+	@Test
+	public void testGetLast_2()
+		throws Exception {
+		int length = 2;
+		IncompleteMemory<String> fixture = new IncompleteMemory<String>(length);
+		fixture.add("1");
+		fixture.add("2");
+		fixture.add("3");
+		int num = 1;
+		
+		List<String> expected = new ArrayList<String>();
+		expected.add("3");
+
+		List<String> result = fixture.getLast(num);
+
+		assertNotNull(result);
+		assertEquals(expected, result);
+	}
+
+	@Test
+	public void testGetLast_3()
+		throws Exception {
+		int length = 2;
+		IncompleteMemory<String> fixture = new IncompleteMemory<String>(length);
+		fixture.add("1");
+		fixture.add("2");
+		fixture.add("3");
+		int num = 2;
+		
+		List<String> expected = new ArrayList<String>();
+		expected.add("2");
+		expected.add("3");
+
+		List<String> result = fixture.getLast(num);
+
+		assertNotNull(result);
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testGetLast_4()
+		throws Exception {
+		int length = 2;
+		IncompleteMemory<String> fixture = new IncompleteMemory<String>(length);
+		fixture.add("1");
+		fixture.add("2");
+		fixture.add("3");
+		int num = 3;
+		
+		List<String> expected = new ArrayList<String>();
+		expected.add("2");
+		expected.add("3");
+
+		List<String> result = fixture.getLast(num);
+
+		assertNotNull(result);
+		assertEquals(expected, result);
+	}
+
+	@Test
+	public void testGetLength_1()
+		throws Exception {
+		int length = 2;
+		IncompleteMemory<String> fixture = new IncompleteMemory<String>(length);
+		
+		int result = fixture.getLength(); 
+
+		assertEquals(0, result);
+	}
+	
+	@Test
+	public void testGetLength_2()
+		throws Exception {
+		int length = 2;
+		IncompleteMemory<String> fixture = new IncompleteMemory<String>(length);
+		fixture.add("1");
+		
+		int result = fixture.getLength(); 
+
+		assertEquals(1, result);
+	}
+	
+	@Test
+	public void testGetLength_3()
+		throws Exception {
+		int length = 2;
+		IncompleteMemory<String> fixture = new IncompleteMemory<String>(length);
+		fixture.add("1");
+		fixture.add("2");
+		fixture.add("3");
+		
+		int result = fixture.getLength(); 
+
+		assertEquals(2, result);
+	}
+
+	public static void main(String[] args) {
+		new org.junit.runner.JUnitCore().run(IncompleteMemoryTest.class);
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-usageprofiles-test/src/test/java/de/ugoe/cs/quest/usageprofiles/MockTrieBasedModel.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usageprofiles-test/src/test/java/de/ugoe/cs/quest/usageprofiles/MockTrieBasedModel.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usageprofiles-test/src/test/java/de/ugoe/cs/quest/usageprofiles/MockTrieBasedModel.java	(revision 540)
@@ -0,0 +1,31 @@
+package de.ugoe.cs.quest.usageprofiles;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.usageprofiles.TrieBasedModel;
+
+public class MockTrieBasedModel extends TrieBasedModel {
+	private static final long serialVersionUID = 1L;
+
+	public MockTrieBasedModel(int markovOrder, Random r) {
+		super(markovOrder, r);
+	}
+
+	@Override
+	public double getProbability(List<? extends Event<?>> context,
+			Event<?> symbol) {
+		List<Event<?>> list = new ArrayList<Event<?>>();
+		if( context.isEmpty() ) {
+			return 2;
+		}
+		list.add(context.get(context.size()-1));
+		if( trie.find(list).getFollowingSymbols().contains(symbol) ) {
+			return 1;
+		} else {
+			return 0;
+		}
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-usageprofiles-test/src/test/java/de/ugoe/cs/quest/usageprofiles/ModelFlattenerTest.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usageprofiles-test/src/test/java/de/ugoe/cs/quest/usageprofiles/ModelFlattenerTest.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usageprofiles-test/src/test/java/de/ugoe/cs/quest/usageprofiles/ModelFlattenerTest.java	(revision 540)
@@ -0,0 +1,148 @@
+package de.ugoe.cs.quest.usageprofiles;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Random;
+import org.junit.*;
+
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.usageprofiles.FirstOrderMarkovModel;
+import de.ugoe.cs.quest.usageprofiles.HighOrderMarkovModel;
+import de.ugoe.cs.quest.usageprofiles.ModelFlattener;
+import de.ugoe.cs.quest.usageprofiles.PredictionByPartialMatch;
+import de.ugoe.cs.quest.usageprofiles.TrieNode;
+import static org.junit.Assert.*;
+
+/**
+ * The class <code>ModelFlattenerTest</code> contains tests for the class <code>{@link ModelFlattener}</code>.
+ *
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class ModelFlattenerTest {
+	
+	List<Event<?>> sequence;
+	
+	private static void assertCollectionContent(Collection<?> c1, Collection<?> c2) {
+		assertEquals(c1.size(), c2.size());
+		for( Object obj : c1 ) {
+			assertTrue(c2.contains(obj));
+		}
+	}
+	
+	@Test
+	public void testFlattenHighOrderMarkovModel_1()
+		throws Exception {
+		ModelFlattener fixture = new ModelFlattener();
+		HighOrderMarkovModel model = new HighOrderMarkovModel(2, new Random());
+		Collection<List<? extends Event<?>>> sequences = new ArrayList<List<? extends Event<?>>>();
+		sequences.add(sequence);
+		model.train(sequences);
+		
+		Collection<Event<?>> expectedSymbols = new HashSet<Event<?>>();
+		expectedSymbols.add(new Event<Object>("a-=-END"));
+		expectedSymbols.add(new Event<Object>("a-=-b"));
+		expectedSymbols.add(new Event<Object>("a-=-c"));
+		expectedSymbols.add(new Event<Object>("a-=-d"));
+		expectedSymbols.add(new Event<Object>("b-=-r"));
+		expectedSymbols.add(new Event<Object>("c-=-a"));
+		expectedSymbols.add(new Event<Object>("d-=-a"));
+		expectedSymbols.add(new Event<Object>("r-=-a"));
+		expectedSymbols.add(new Event<Object>("START-=-a"));
+
+		FirstOrderMarkovModel result = fixture.flattenHighOrderMarkovModel(model);
+		
+		assertCollectionContent(expectedSymbols, result.getEvents());
+		
+		TrieNode<Event<?>> root = result.trie.find(null);
+		TrieNode<Event<?>> root_aEnd = root.getChild(new Event<Object>("a-=-END"));
+		TrieNode<Event<?>> root_ab = root.getChild(new Event<Object>("a-=-b"));
+		TrieNode<Event<?>> root_ab_br = root_ab.getChild(new Event<Object>("b-=-r"));
+		TrieNode<Event<?>> root_ac = root.getChild(new Event<Object>("a-=-c"));
+		TrieNode<Event<?>> root_ac_ca = root_ac.getChild(new Event<Object>("c-=-a"));
+		TrieNode<Event<?>> root_ad = root.getChild(new Event<Object>("a-=-d"));
+		TrieNode<Event<?>> root_ad_da = root_ad.getChild(new Event<Object>("d-=-a"));
+		TrieNode<Event<?>> root_br = root.getChild(new Event<Object>("b-=-r"));
+		TrieNode<Event<?>> root_br_ra = root_br.getChild(new Event<Object>("r-=-a"));
+		TrieNode<Event<?>> root_ca = root.getChild(new Event<Object>("c-=-a"));
+		TrieNode<Event<?>> root_ca_ad = root_ca.getChild(new Event<Object>("a-=-d"));
+		TrieNode<Event<?>> root_da = root.getChild(new Event<Object>("d-=-a"));
+		TrieNode<Event<?>> root_da_ab = root_da.getChild(new Event<Object>("a-=-b"));
+		TrieNode<Event<?>> root_ra = root.getChild(new Event<Object>("r-=-a"));
+		TrieNode<Event<?>> root_ra_ac = root_ra.getChild(new Event<Object> ("a-=-c"));
+		TrieNode<Event<?>> root_ra_aEnd = root_ra.getChild(new Event<Object>("a-=-END"));
+		TrieNode<Event<?>> root_startA = root.getChild(new Event<Object>("START-=-a"));
+		TrieNode<Event<?>> root_startA_ab = root_startA.getChild(new Event<Object>("a-=-b"));
+		
+		assertEquals(1, root_aEnd.getCount());
+		assertTrue(root_aEnd.isLeaf());
+		assertEquals(2, root_ab.getCount());
+		assertEquals(1, root_ab.getChildren().size());
+		assertEquals(2, root_ab_br.getCount());
+		assertTrue(root_ab_br.isLeaf());
+		assertEquals(1, root_ac.getCount());
+		assertEquals(1, root_ac.getChildren().size());
+		assertEquals(1, root_ac_ca.getCount());
+		assertTrue(root_ac_ca.isLeaf());
+		assertEquals(1, root_ad.getCount());
+		assertEquals(1, root_ad.getChildren().size());
+		assertEquals(1, root_ad_da.getCount());
+		assertTrue(root_ad_da.isLeaf());
+		assertEquals(2, root_br.getCount());
+		assertEquals(1, root_br.getChildren().size());
+		assertEquals(2, root_br_ra.getCount());
+		assertTrue(root_br_ra.isLeaf());
+		assertEquals(1, root_ca.getCount());
+		assertEquals(1, root_ca.getChildren().size());
+		assertEquals(1, root_ca_ad.getCount());
+		assertTrue(root_ca_ad.isLeaf());
+		assertEquals(1, root_da.getCount());
+		assertEquals(1, root_da.getChildren().size());
+		assertEquals(1, root_da_ab.getCount());
+		assertTrue(root_da_ab.isLeaf());
+		assertEquals(2, root_ra.getCount());
+		assertEquals(2, root_ra.getChildren().size());
+		assertEquals(1, root_ra_ac.getCount());
+		assertTrue(root_ra_ac.isLeaf());
+		assertEquals(1, root_ra_aEnd.getCount());
+		assertTrue(root_ra_aEnd.isLeaf());
+		assertEquals(1, root_startA.getCount());
+		assertEquals(1, root_startA.getChildren().size());
+		assertEquals(1, root_startA_ab.getCount());
+		assertTrue(root_startA_ab.isLeaf());		
+	}
+
+	@Test
+	public void testFlattenPredictionByPartialMatch_1()
+		throws Exception {
+		ModelFlattener fixture = new ModelFlattener();
+		PredictionByPartialMatch model = new PredictionByPartialMatch(1, new Random());
+
+		FirstOrderMarkovModel result = fixture.flattenPredictionByPartialMatch(model);
+		
+		assertEquals(null, result);
+	}
+
+	@Before
+	public void setUp()
+		throws Exception {
+		sequence = new ArrayList<Event<?>>();
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("b"));
+		sequence.add(new Event<String>("r"));
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("c"));
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("d"));
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("b"));
+		sequence.add(new Event<String>("r"));
+		sequence.add(new Event<String>("a"));
+	}
+
+	public static void main(String[] args) {
+		new org.junit.runner.JUnitCore().run(ModelFlattenerTest.class);
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-usageprofiles-test/src/test/java/de/ugoe/cs/quest/usageprofiles/PredictionByPartialMatchTest.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usageprofiles-test/src/test/java/de/ugoe/cs/quest/usageprofiles/PredictionByPartialMatchTest.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usageprofiles-test/src/test/java/de/ugoe/cs/quest/usageprofiles/PredictionByPartialMatchTest.java	(revision 540)
@@ -0,0 +1,365 @@
+package de.ugoe.cs.quest.usageprofiles;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.usageprofiles.PredictionByPartialMatch;
+
+import java.util.Random;
+import org.junit.*;
+
+import static org.junit.Assert.*;
+
+/**
+ * The class <code>PredictionByPartialMatchTest</code> contains tests for the
+ * class <code>{@link PredictionByPartialMatch}</code>.
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class PredictionByPartialMatchTest {
+
+	Collection<List<? extends Event<?>>> sequences;
+
+	@Test
+	public void testPredictionByPartialMatch_1() throws Exception {
+		int markovOrder = 2;
+		Random r = new Random();
+
+		PredictionByPartialMatch result = new PredictionByPartialMatch(
+				markovOrder, r);
+
+		assertNotNull(result);
+		assertEquals(markovOrder+1, result.trieOrder);
+		assertEquals(0, result.minOrder);
+		assertEquals(r, result.r);
+		assertEquals(0.1, result.probEscape, 0.0001);
+	}
+	
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testPredictionByPartialMatch_2() throws Exception {
+		int markovOrder = -1;
+		Random r = new Random();
+
+		new PredictionByPartialMatch(markovOrder, r);
+	}
+	
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testPredictionByPartialMatch_3() throws Exception {
+		int markovOrder = 2;
+		Random r = null;
+
+		new PredictionByPartialMatch(markovOrder, r);
+	}
+	
+	@Test
+	public void testPredictionByPartialMatch_4() throws Exception {
+		int markovOrder = 2;
+		Random r = new Random();
+		double probEscape = 0.2;
+
+		PredictionByPartialMatch result = new PredictionByPartialMatch(
+				markovOrder, r, probEscape);
+
+		assertNotNull(result);
+		assertEquals(markovOrder+1, result.trieOrder);
+		assertEquals(0, result.minOrder);
+		assertEquals(r, result.r);
+		assertEquals(probEscape, result.probEscape, 0.0001);
+	}
+	
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testPredictionByPartialMatch_5() throws Exception {
+		int markovOrder = -1;
+		Random r = new Random();
+		double probEscape = 0.2;
+
+		new PredictionByPartialMatch(markovOrder, r, probEscape);
+	}
+	
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testPredictionByPartialMatch_6() throws Exception {
+		int markovOrder = 2;
+		Random r = null;
+		double probEscape = 0.2;
+
+		new PredictionByPartialMatch(markovOrder, r, probEscape);
+	}
+	
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testPredictionByPartialMatch_7() throws Exception {
+		int markovOrder = 2;
+		Random r = new Random();
+		double probEscape = 0.0;
+
+		new PredictionByPartialMatch(markovOrder, r, probEscape);
+	}
+	
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testPredictionByPartialMatch_8() throws Exception {
+		int markovOrder = 2;
+		Random r = new Random();
+		double probEscape = 1.0;
+
+		new PredictionByPartialMatch(markovOrder, r, probEscape);
+	}
+	
+	@Test
+	public void testPredictionByPartialMatch_9() throws Exception {
+		int markovOrder = 2;
+		Random r = new Random();
+		double probEscape = 0.2;
+		int minOrder = 1;
+
+		PredictionByPartialMatch result = new PredictionByPartialMatch(
+				markovOrder, minOrder, r, probEscape);
+
+		assertNotNull(result);
+		assertEquals(markovOrder+1, result.trieOrder);
+		assertEquals(minOrder, result.minOrder);
+		assertEquals(r, result.r);
+		assertEquals(probEscape, result.probEscape, 0.0001);
+	}
+	
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testPredictionByPartialMatch_10() throws Exception {
+		int markovOrder = -1;
+		Random r = new Random();
+		double probEscape = 0.2;
+		int minOrder = 1;
+
+		new PredictionByPartialMatch(markovOrder, minOrder, r, probEscape);
+	}
+	
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testPredictionByPartialMatch_11() throws Exception {
+		int markovOrder = 2;
+		Random r = null;
+		double probEscape = 0.2;
+		int minOrder = 1;
+
+		new PredictionByPartialMatch(markovOrder, minOrder, r, probEscape);
+	}
+	
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testPredictionByPartialMatch_12() throws Exception {
+		int markovOrder = 2;
+		Random r = new Random();
+		double probEscape = 0.0;
+		int minOrder = 1;
+
+		new PredictionByPartialMatch(markovOrder, minOrder, r, probEscape);
+	}
+	
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testPredictionByPartialMatch_13() throws Exception {
+		int markovOrder = 2;
+		Random r = new Random();
+		double probEscape = 1.0;
+		int minOrder = 1;
+
+		new PredictionByPartialMatch(markovOrder, minOrder, r, probEscape);
+	}
+	
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testPredictionByPartialMatch_14() throws Exception {
+		int markovOrder = 2;
+		Random r = new Random();
+		double probEscape = 0.2;
+		int minOrder = 3;
+
+		new PredictionByPartialMatch(markovOrder, minOrder, r, probEscape);
+	}
+	
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testPredictionByPartialMatch_15() throws Exception {
+		int markovOrder = 2;
+		Random r = new Random();
+		double probEscape = 0.2;
+		int minOrder = -1;
+
+		new PredictionByPartialMatch(markovOrder, minOrder, r, probEscape);
+	}
+
+	@Test
+	public void testGetProbEscape_1() throws Exception {
+		int markovOrder = 2;
+		Random r = new Random();
+		double probEscape = 0.2;
+		int minOrder = 1;
+
+		PredictionByPartialMatch fixture = new PredictionByPartialMatch(markovOrder, minOrder, r, probEscape);
+		fixture.probEscape = probEscape;
+		
+		double result = fixture.getProbEscape();
+
+		assertEquals(probEscape, result, 0.0001);
+	}
+
+	@Test
+	public void testGetProbability_1() throws Exception {
+		int markovOrder = 2;
+		Random r = new Random();
+		double probEscape = 0.2;
+		int minOrder = 1;
+
+		PredictionByPartialMatch fixture = new PredictionByPartialMatch(markovOrder, minOrder, r, probEscape);
+		fixture.train(sequences);
+		
+		List<Event<?>> context = new ArrayList<Event<?>>();
+		context.add(Event.STARTEVENT);
+		context.add(new Event<String>("a"));
+
+		Event<String> symbol = new Event<String>("b");
+		
+		double result = fixture.getProbability(context, symbol);
+		
+		assertEquals(0.88d, result, 0.0001);
+	}
+	
+	@Test
+	public void testGetProbability_2() throws Exception {
+		int markovOrder = 2;
+		Random r = new Random();
+		double probEscape = 0.2;
+		int minOrder = 1;
+
+		PredictionByPartialMatch fixture = new PredictionByPartialMatch(markovOrder, minOrder, r, probEscape);
+		fixture.train(sequences);
+		
+		List<Event<?>> context = new ArrayList<Event<?>>();
+		context.add(Event.STARTEVENT);
+		context.add(new Event<String>("a"));
+
+		Event<String> symbol = new Event<String>("c");
+		
+		double result = fixture.getProbability(context, symbol);
+		
+		assertEquals(0.04d, result, 0.0001);
+	}
+	
+	@Test
+	public void testGetProbability_3() throws Exception {
+		int markovOrder = 2;
+		Random r = new Random();
+		double probEscape = 0.2;
+		int minOrder = 2;
+
+		PredictionByPartialMatch fixture = new PredictionByPartialMatch(markovOrder, minOrder, r, probEscape);
+		fixture.train(sequences);
+		
+		List<Event<?>> context = new ArrayList<Event<?>>();
+		context.add(Event.STARTEVENT);
+		context.add(new Event<String>("a"));
+
+		Event<String> symbol = new Event<String>("b");
+		
+		double result = fixture.getProbability(context, symbol);
+		
+		assertEquals(1.0d, result, 0.0001);
+	}
+	
+	@Test
+	public void testGetProbability_4() throws Exception {
+		int markovOrder = 2;
+		Random r = new Random();
+		double probEscape = 0.2;
+		int minOrder = 2;
+
+		PredictionByPartialMatch fixture = new PredictionByPartialMatch(markovOrder, minOrder, r, probEscape);
+		fixture.train(sequences);
+		
+		List<Event<?>> context = new ArrayList<Event<?>>();
+		context.add(Event.STARTEVENT);
+		context.add(new Event<String>("a"));
+
+		Event<String> symbol = new Event<String>("c");
+		
+		double result = fixture.getProbability(context, symbol);
+		
+		assertEquals(0.0d, result, 0.0001);
+	}
+	
+	@Test
+	public void testGetProbability_5() throws Exception {
+		int markovOrder = 2;
+		Random r = new Random();
+		double probEscape = 0.2;
+		int minOrder = 0;
+
+		PredictionByPartialMatch fixture = new PredictionByPartialMatch(markovOrder, minOrder, r, probEscape);
+		fixture.train(sequences);
+		
+		List<Event<?>> context = new ArrayList<Event<?>>();
+		context.add(Event.STARTEVENT);
+		context.add(new Event<String>("a"));
+
+		Event<String> symbol = new Event<String>("b");
+		
+		double result = fixture.getProbability(context, symbol);
+		
+		assertEquals(0.8701d, result, 0.0001);
+	}
+	
+	@Test
+	public void testGetProbability_6() throws Exception {
+		int markovOrder = 2;
+		Random r = new Random();
+		double probEscape = 0.2;
+		int minOrder = 0;
+
+		PredictionByPartialMatch fixture = new PredictionByPartialMatch(markovOrder, minOrder, r, probEscape);
+		fixture.train(sequences);
+		
+		List<Event<?>> context = new ArrayList<Event<?>>();
+		context.add(Event.STARTEVENT);
+		context.add(new Event<String>("a"));
+
+		Event<String> symbol = new Event<String>("c");
+		
+		double result = fixture.getProbability(context, symbol);
+		
+		assertEquals(0.0350, result, 0.0001);
+	}
+
+	@Test
+	public void testSetProbEscape_1() throws Exception {
+		int markovOrder = 2;
+		Random r = new Random();
+		double probEscape = 0.2;
+		int minOrder = 1;
+		double newProbEscape = 0.3;
+
+		PredictionByPartialMatch fixture = new PredictionByPartialMatch(markovOrder, minOrder, r, probEscape);
+				
+		fixture.setProbEscape(newProbEscape);
+
+		assertEquals(newProbEscape, fixture.probEscape, 0.0001);
+	}
+
+	@Before
+	public void setUp() throws Exception {
+		List<Event<?>> sequence = new ArrayList<Event<?>>();
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("b"));
+		sequence.add(new Event<String>("r"));
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("c"));
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("d"));
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("b"));
+		sequence.add(new Event<String>("r"));
+		sequence.add(new Event<String>("a"));
+
+		sequences = new ArrayList<List<? extends Event<?>>>();
+		sequences.add(sequence);
+	}
+
+	public static void main(String[] args) {
+		new org.junit.runner.JUnitCore()
+				.run(PredictionByPartialMatchTest.class);
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-usageprofiles-test/src/test/java/de/ugoe/cs/quest/usageprofiles/TrieBasedModelTest.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usageprofiles-test/src/test/java/de/ugoe/cs/quest/usageprofiles/TrieBasedModelTest.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usageprofiles-test/src/test/java/de/ugoe/cs/quest/usageprofiles/TrieBasedModelTest.java	(revision 540)
@@ -0,0 +1,635 @@
+package de.ugoe.cs.quest.usageprofiles;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Random;
+
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.usageprofiles.Trie;
+import de.ugoe.cs.quest.usageprofiles.TrieBasedModel;
+import de.ugoe.cs.quest.usageprofiles.TrieNode;
+
+import org.junit.*;
+import static org.junit.Assert.*;
+
+/**
+ * The class <code>TrieBasedModelTest</code> contains tests for the class
+ * <code>{@link TrieBasedModel}</code>.
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class TrieBasedModelTest {
+
+	List<Event<?>> sequence;
+	Collection<Event<?>> symbols;
+
+	private void assertTrieStructure(Trie<Event<?>> trie, int numSequences) {
+		TrieNode<Event<?>> root = trie.find(null);
+		TrieNode<Event<?>> root_a = root.getChild(new Event<String>("a"));
+		TrieNode<Event<?>> root_a_a = root_a.getChild(new Event<String>("a"));
+		TrieNode<Event<?>> root_a_b = root_a.getChild(new Event<String>("b"));
+		TrieNode<Event<?>> root_a_b_a = root_a_b
+				.getChild(new Event<String>("a"));
+		TrieNode<Event<?>> root_a_b_b = root_a_b
+				.getChild(new Event<String>("b"));
+		TrieNode<Event<?>> root_a_b_c = root_a_b
+				.getChild(new Event<String>("c"));
+		TrieNode<Event<?>> root_a_b_d = root_a_b
+				.getChild(new Event<String>("d"));
+		TrieNode<Event<?>> root_a_b_r = root_a_b
+				.getChild(new Event<String>("r"));
+		TrieNode<Event<?>> root_a_c = root_a.getChild(new Event<String>("c"));
+		TrieNode<Event<?>> root_a_c_a = root_a_c
+				.getChild(new Event<String>("a"));
+		TrieNode<Event<?>> root_a_c_b = root_a_c
+				.getChild(new Event<String>("b"));
+		TrieNode<Event<?>> root_a_c_c = root_a_c
+				.getChild(new Event<String>("c"));
+		TrieNode<Event<?>> root_a_c_d = root_a_c
+				.getChild(new Event<String>("d"));
+		TrieNode<Event<?>> root_a_c_r = root_a_c
+				.getChild(new Event<String>("r"));
+		TrieNode<Event<?>> root_a_d = root_a.getChild(new Event<String>("d"));
+		TrieNode<Event<?>> root_a_d_a = root_a_d
+				.getChild(new Event<String>("a"));
+		TrieNode<Event<?>> root_a_d_b = root_a_d
+				.getChild(new Event<String>("b"));
+		TrieNode<Event<?>> root_a_d_c = root_a_d
+				.getChild(new Event<String>("c"));
+		TrieNode<Event<?>> root_a_d_d = root_a_d
+				.getChild(new Event<String>("d"));
+		TrieNode<Event<?>> root_a_d_r = root_a_d
+				.getChild(new Event<String>("r"));
+		TrieNode<Event<?>> root_a_r = root_a.getChild(new Event<String>("r"));
+		TrieNode<Event<?>> root_b = root.getChild(new Event<String>("b"));
+		TrieNode<Event<?>> root_b_a = root_b.getChild(new Event<String>("a"));
+		TrieNode<Event<?>> root_b_b = root_b.getChild(new Event<String>("b"));
+		TrieNode<Event<?>> root_b_c = root_b.getChild(new Event<String>("c"));
+		TrieNode<Event<?>> root_b_d = root_b.getChild(new Event<String>("d"));
+		TrieNode<Event<?>> root_b_r = root_b.getChild(new Event<String>("r"));
+		TrieNode<Event<?>> root_b_r_a = root_b_r
+				.getChild(new Event<String>("a"));
+		TrieNode<Event<?>> root_b_r_b = root_b_r
+				.getChild(new Event<String>("b"));
+		TrieNode<Event<?>> root_b_r_c = root_b_r
+				.getChild(new Event<String>("c"));
+		TrieNode<Event<?>> root_b_r_d = root_b_r
+				.getChild(new Event<String>("d"));
+		TrieNode<Event<?>> root_b_r_r = root_b_r
+				.getChild(new Event<String>("r"));
+		TrieNode<Event<?>> root_c = root.getChild(new Event<String>("c"));
+		TrieNode<Event<?>> root_c_a = root_c.getChild(new Event<String>("a"));
+		TrieNode<Event<?>> root_c_a_a = root_c_a
+				.getChild(new Event<String>("a"));
+		TrieNode<Event<?>> root_c_a_b = root_c_a
+				.getChild(new Event<String>("b"));
+		TrieNode<Event<?>> root_c_a_c = root_c_a
+				.getChild(new Event<String>("c"));
+		TrieNode<Event<?>> root_c_a_d = root_c_a
+				.getChild(new Event<String>("d"));
+		TrieNode<Event<?>> root_c_a_r = root_c_a
+				.getChild(new Event<String>("r"));
+		TrieNode<Event<?>> root_c_b = root_c.getChild(new Event<String>("b"));
+		TrieNode<Event<?>> root_c_c = root_c.getChild(new Event<String>("c"));
+		TrieNode<Event<?>> root_c_d = root_c.getChild(new Event<String>("d"));
+		TrieNode<Event<?>> root_c_r = root_c.getChild(new Event<String>("r"));
+		TrieNode<Event<?>> root_d = root.getChild(new Event<String>("d"));
+		TrieNode<Event<?>> root_d_a = root_d.getChild(new Event<String>("a"));
+		TrieNode<Event<?>> root_d_a_a = root_d_a
+				.getChild(new Event<String>("a"));
+		TrieNode<Event<?>> root_d_a_b = root_d_a
+				.getChild(new Event<String>("b"));
+		TrieNode<Event<?>> root_d_a_c = root_d_a
+				.getChild(new Event<String>("c"));
+		TrieNode<Event<?>> root_d_a_d = root_d_a
+				.getChild(new Event<String>("d"));
+		TrieNode<Event<?>> root_d_a_r = root_d_a
+				.getChild(new Event<String>("r"));
+		TrieNode<Event<?>> root_d_b = root_d.getChild(new Event<String>("b"));
+		TrieNode<Event<?>> root_d_c = root_d.getChild(new Event<String>("c"));
+		TrieNode<Event<?>> root_d_d = root_d.getChild(new Event<String>("d"));
+		TrieNode<Event<?>> root_d_r = root_d.getChild(new Event<String>("r"));
+		TrieNode<Event<?>> root_r = root.getChild(new Event<String>("r"));
+		TrieNode<Event<?>> root_r_a = root_r.getChild(new Event<String>("a"));
+		TrieNode<Event<?>> root_r_a_a = root_r_a
+				.getChild(new Event<String>("a"));
+		TrieNode<Event<?>> root_r_a_b = root_r_a
+				.getChild(new Event<String>("b"));
+		TrieNode<Event<?>> root_r_a_c = root_r_a
+				.getChild(new Event<String>("c"));
+		TrieNode<Event<?>> root_r_a_d = root_r_a
+				.getChild(new Event<String>("d"));
+		TrieNode<Event<?>> root_r_a_r = root_r_a
+				.getChild(new Event<String>("r"));
+		TrieNode<Event<?>> root_r_a_end = root_r_a.getChild(Event.ENDEVENT);
+		TrieNode<Event<?>> root_r_b = root_r.getChild(new Event<String>("b"));
+		TrieNode<Event<?>> root_r_c = root_r.getChild(new Event<String>("c"));
+		TrieNode<Event<?>> root_r_d = root_r.getChild(new Event<String>("d"));
+		TrieNode<Event<?>> root_r_r = root_r.getChild(new Event<String>("r"));
+		TrieNode<Event<?>> root_start = root.getChild(Event.STARTEVENT);
+		TrieNode<Event<?>> root_start_a = root_start
+				.getChild(new Event<String>("a"));
+		TrieNode<Event<?>> root_start_a_a = root_start_a
+				.getChild(new Event<String>("a"));
+		TrieNode<Event<?>> root_start_a_b = root_start_a
+				.getChild(new Event<String>("b"));
+		TrieNode<Event<?>> root_start_a_c = root_start_a
+				.getChild(new Event<String>("c"));
+		TrieNode<Event<?>> root_start_a_d = root_start_a
+				.getChild(new Event<String>("d"));
+		TrieNode<Event<?>> root_start_a_r = root_start_a
+				.getChild(new Event<String>("r"));
+		TrieNode<Event<?>> root_start_b = root_start
+				.getChild(new Event<String>("b"));
+		TrieNode<Event<?>> root_start_c = root_start
+				.getChild(new Event<String>("c"));
+		TrieNode<Event<?>> root_start_d = root_start
+				.getChild(new Event<String>("d"));
+		TrieNode<Event<?>> root_start_r = root_start
+				.getChild(new Event<String>("r"));
+
+		assertEquals(numSequences * 5, root_a.getCount());
+		assertNull(root_a_a);
+		assertEquals(numSequences * 2, root_a_b.getCount());
+		assertNull(root_a_b_a);
+		assertNull(root_a_b_b);
+		assertNull(root_a_b_c);
+		assertNull(root_a_b_d);
+		assertEquals(numSequences * 2, root_a_b_r.getCount());
+		assertEquals(numSequences * 1, root_a_c.getCount());
+		assertEquals(numSequences * 1, root_a_c_a.getCount());
+		assertNull(root_a_c_b);
+		assertNull(root_a_c_c);
+		assertNull(root_a_c_d);
+		assertNull(root_a_c_r);
+		assertEquals(numSequences * 1, root_a_d.getCount());
+		assertEquals(numSequences * 1, root_a_d_a.getCount());
+		assertNull(root_a_d_b);
+		assertNull(root_a_d_c);
+		assertNull(root_a_d_d);
+		assertNull(root_a_d_r);
+		assertNull(root_a_r);
+
+		assertEquals(numSequences * 2, root_b.getCount());
+		assertNull(root_b_a);
+		assertNull(root_b_b);
+		assertNull(root_b_c);
+		assertNull(root_b_d);
+		assertEquals(numSequences * 2, root_b_r.getCount());
+		assertEquals(numSequences * 2, root_b_r_a.getCount());
+		assertNull(root_b_r_b);
+		assertNull(root_b_r_c);
+		assertNull(root_b_r_d);
+		assertNull(root_b_r_r);
+
+		assertEquals(numSequences * 1, root_c.getCount());
+		assertEquals(numSequences * 1, root_c_a.getCount());
+		assertNull(root_c_a_a);
+		assertNull(root_c_a_b);
+		assertNull(root_c_a_c);
+		assertEquals(numSequences * 1, root_c_a_d.getCount());
+		assertNull(root_c_a_r);
+		assertNull(root_c_b);
+		assertNull(root_c_c);
+		assertNull(root_c_d);
+		assertNull(root_c_r);
+
+		assertEquals(numSequences * 1, root_d.getCount());
+		assertEquals(numSequences * 1, root_d_a.getCount());
+		assertNull(root_d_a_a);
+		assertEquals(numSequences * 1, root_d_a_b.getCount());
+		assertNull(root_d_a_c);
+		assertNull(root_d_a_d);
+		assertNull(root_d_a_r);
+		assertNull(root_d_b);
+		assertNull(root_d_c);
+		assertNull(root_d_d);
+		assertNull(root_d_r);
+
+		assertEquals(numSequences * 2, root_r.getCount());
+		assertEquals(numSequences * 2, root_r_a.getCount());
+		assertNull(root_r_a_a);
+		assertNull(root_r_a_b);
+		assertEquals(numSequences * 1, root_r_a_c.getCount());
+		assertNull(root_r_a_d);
+		assertNull(root_r_a_r);
+		assertEquals(numSequences * 1, root_r_a_end.getCount());
+		assertNull(root_r_b);
+		assertNull(root_r_c);
+		assertNull(root_r_d);
+		assertNull(root_r_r);
+
+		assertEquals(numSequences * 1, root_start.getCount());
+		assertEquals(numSequences * 1, root_start_a.getCount());
+		assertNull(root_start_a_a);
+		assertEquals(numSequences * 1, root_start_a_b.getCount());
+		assertNull(root_start_a_c);
+		assertNull(root_start_a_d);
+		assertNull(root_start_a_r);
+		assertNull(root_start_b);
+		assertNull(root_start_c);
+		assertNull(root_start_d);
+		assertNull(root_start_r);
+
+		// check if leafs are really leafs
+		assertTrue(root_a_b_r.isLeaf());
+		assertTrue(root_a_c_a.isLeaf());
+		assertTrue(root_a_d_a.isLeaf());
+		assertTrue(root_b_r_a.isLeaf());
+		assertTrue(root_c_a_d.isLeaf());
+		assertTrue(root_d_a_b.isLeaf());
+		assertTrue(root_r_a_c.isLeaf());
+		assertTrue(root_r_a_end.isLeaf());
+	}
+
+	private static void assertCollectionContent(Collection<?> c1,
+			Collection<?> c2) {
+		assertEquals(c1.size(), c2.size());
+		for (Object obj : c1) {
+			assertTrue(c2.contains(obj));
+		}
+	}
+
+	@Test
+	public void testTrieBasedModel_1() throws Exception {
+		int markovOrder = 2;
+		Random r = new Random();
+
+		MockTrieBasedModel result = new MockTrieBasedModel(markovOrder, r);
+
+		assertNotNull(result);
+		assertEquals(markovOrder + 1, result.trieOrder);
+		assertEquals(r, result.r);
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testTrieBasedModel_2() throws Exception {
+		int markovOrder = -1;
+		Random r = new Random();
+
+		new MockTrieBasedModel(markovOrder, r);
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testTrieBasedModel_3() throws Exception {
+		int markovOrder = 2;
+		Random r = null;
+
+		new MockTrieBasedModel(markovOrder, r);
+	}
+
+	@Test
+	public void testGenerateSequences_1() throws Exception {
+		int markovOrder = 2;
+		MockTrieBasedModel fixture = new MockTrieBasedModel(markovOrder,
+				new Random());
+		Collection<List<? extends Event<?>>> sequences = new ArrayList<List<? extends Event<?>>>();
+		sequences.add(sequence);
+		fixture.train(sequences);
+		int length = 2;
+
+		Collection<List<Event<?>>> expected = new HashSet<List<Event<?>>>();
+		ArrayList<Event<?>> list;
+		list = new ArrayList<Event<?>>();
+		list.add(new Event<String>("a"));
+		list.add(Event.ENDEVENT);
+		expected.add(list);
+		list = new ArrayList<Event<?>>();
+		list.add(new Event<String>("a"));
+		list.add(new Event<String>("b"));
+		expected.add(list);
+		list = new ArrayList<Event<?>>();
+		list.add(new Event<String>("a"));
+		list.add(new Event<String>("c"));
+		expected.add(list);
+		list = new ArrayList<Event<?>>();
+		list.add(new Event<String>("a"));
+		list.add(new Event<String>("d"));
+		expected.add(list);
+		list = new ArrayList<Event<?>>();
+		list.add(new Event<String>("b"));
+		list.add(new Event<String>("r"));
+		expected.add(list);
+		list = new ArrayList<Event<?>>();
+		list.add(new Event<String>("c"));
+		list.add(new Event<String>("a"));
+		expected.add(list);
+		list = new ArrayList<Event<?>>();
+		list.add(new Event<String>("d"));
+		list.add(new Event<String>("a"));
+		expected.add(list);
+		list = new ArrayList<Event<?>>();
+		list.add(new Event<String>("r"));
+		list.add(new Event<String>("a"));
+		expected.add(list);
+		list = new ArrayList<Event<?>>();
+		list.add(Event.STARTEVENT);
+		list.add(new Event<String>("a"));
+		expected.add(list);
+
+		Collection<List<? extends Event<?>>> result = fixture
+				.generateSequences(length);
+
+		assertCollectionContent(expected, result);
+	}
+
+	@Test
+	public void testGenerateSequences_2() throws Exception {
+		int markovOrder = 2;
+		MockTrieBasedModel fixture = new MockTrieBasedModel(markovOrder,
+				new Random());
+		Collection<List<? extends Event<?>>> sequences = new ArrayList<List<? extends Event<?>>>();
+		sequences.add(sequence);
+		fixture.train(sequences);
+		int length = 3;
+
+		Collection<List<Event<?>>> expected = new HashSet<List<Event<?>>>();
+		ArrayList<Event<?>> list;
+		list = new ArrayList<Event<?>>();
+		list.add(Event.STARTEVENT);
+		list.add(new Event<String>("a"));
+		list.add(Event.ENDEVENT);
+		expected.add(list);
+		list = new ArrayList<Event<?>>();
+		list.add(Event.STARTEVENT);
+		list.add(new Event<String>("a"));
+		list.add(new Event<String>("b"));
+		expected.add(list);
+		list = new ArrayList<Event<?>>();
+		list.add(Event.STARTEVENT);
+		list.add(new Event<String>("a"));
+		list.add(new Event<String>("c"));
+		expected.add(list);
+		list = new ArrayList<Event<?>>();
+		list.add(Event.STARTEVENT);
+		list.add(new Event<String>("a"));
+		list.add(new Event<String>("d"));
+		expected.add(list);
+
+		Collection<List<? extends Event<?>>> result = fixture
+				.generateSequences(length, true);
+
+		assertCollectionContent(expected, result);
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testGenerateSequences_3() throws Exception {
+		int markovOrder = 2;
+		MockTrieBasedModel fixture = new MockTrieBasedModel(markovOrder,
+				new Random());
+		Collection<List<? extends Event<?>>> sequences = new ArrayList<List<? extends Event<?>>>();
+		sequences.add(sequence);
+		fixture.train(sequences);
+		int length = 0;
+
+		fixture.generateSequences(length, false);
+	}
+
+	@Test
+	public void testGenerateValidSequences_1() throws Exception {
+		int markovOrder = 2;
+		MockTrieBasedModel fixture = new MockTrieBasedModel(markovOrder,
+				new Random());
+		Collection<List<? extends Event<?>>> sequences = new ArrayList<List<? extends Event<?>>>();
+		sequences.add(sequence);
+		fixture.train(sequences);
+		int length = 5;
+
+		Collection<List<Event<?>>> expected = new HashSet<List<Event<?>>>();
+		ArrayList<Event<?>> list;
+		list = new ArrayList<Event<?>>();
+		list.add(Event.STARTEVENT);
+		list.add(new Event<String>("a"));
+		list.add(new Event<String>("c"));
+		list.add(new Event<String>("a"));
+		list.add(Event.ENDEVENT);
+		expected.add(list);
+		list = new ArrayList<Event<?>>();
+		list.add(Event.STARTEVENT);
+		list.add(new Event<String>("a"));
+		list.add(new Event<String>("d"));
+		list.add(new Event<String>("a"));
+		list.add(Event.ENDEVENT);
+		expected.add(list);
+
+		Collection<List<? extends Event<?>>> result = fixture
+				.generateValidSequences(length);
+
+		assertCollectionContent(expected, result);
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testGenerateValidSequences_2() throws Exception {
+		int markovOrder = 2;
+		MockTrieBasedModel fixture = new MockTrieBasedModel(markovOrder,
+				new Random());
+		Collection<List<? extends Event<?>>> sequences = new ArrayList<List<? extends Event<?>>>();
+		sequences.add(sequence);
+		fixture.train(sequences);
+		int length = 0;
+
+		fixture.generateValidSequences(length);
+	}
+
+	@Test
+	public void testGetEvents_1() throws Exception {
+		int markovOrder = 2;
+		MockTrieBasedModel fixture = new MockTrieBasedModel(markovOrder,
+				new Random());
+		Collection<List<? extends Event<?>>> sequences = new ArrayList<List<? extends Event<?>>>();
+		sequences.add(sequence);
+
+		fixture.train(sequences);
+
+		Collection<? extends Event<?>> result = fixture.getEvents();
+
+		assertCollectionContent(symbols, result);
+	}
+
+	@Test
+	public void testGetEvents_2() throws Exception {
+		int markovOrder = 2;
+		MockTrieBasedModel fixture = new MockTrieBasedModel(markovOrder,
+				new Random());
+
+		Collection<? extends Event<?>> result = fixture.getEvents();
+
+		assertCollectionContent(new HashSet<Event<?>>(), result);
+	}
+
+	@Test
+	public void testGetNumFOMStates_1() throws Exception {
+		int markovOrder = 2;
+		MockTrieBasedModel fixture = new MockTrieBasedModel(markovOrder,
+				new Random());
+		Collection<List<? extends Event<?>>> sequences = new ArrayList<List<? extends Event<?>>>();
+		sequences.add(sequence);
+
+		fixture.train(sequences);
+
+		int result = fixture.getNumFOMStates();
+
+		assertEquals(10, result);
+	}
+
+	@Test
+	public void testGetNumFOMStates_2() throws Exception {
+		int markovOrder = 2;
+		MockTrieBasedModel fixture = new MockTrieBasedModel(markovOrder,
+				new Random());
+		;
+
+		int result = fixture.getNumFOMStates();
+
+		assertEquals(0, result);
+	}
+
+	@Test
+	public void testGetNumSymbols_1() throws Exception {
+		int markovOrder = 2;
+		MockTrieBasedModel fixture = new MockTrieBasedModel(markovOrder,
+				new Random());
+		Collection<List<? extends Event<?>>> sequences = new ArrayList<List<? extends Event<?>>>();
+		sequences.add(sequence);
+		fixture.train(sequences);
+
+		int result = fixture.getNumSymbols();
+
+		assertEquals(7, result);
+	}
+
+	@Test
+	public void testGetNumSymbols_2() throws Exception {
+		int markovOrder = 2;
+		MockTrieBasedModel fixture = new MockTrieBasedModel(markovOrder,
+				new Random());
+
+		int result = fixture.getNumSymbols();
+
+		assertEquals(0, result);
+	}
+
+	@Test
+	public void testGetNumTransitions_1() throws Exception {
+		int markovOrder = 2;
+		MockTrieBasedModel fixture = new MockTrieBasedModel(markovOrder,
+				new Random());
+		Collection<List<? extends Event<?>>> sequences = new ArrayList<List<? extends Event<?>>>();
+		sequences.add(sequence);
+		fixture.train(sequences);
+
+		int result = fixture.getNumTransitions();
+
+		assertEquals(11, result);
+	}
+
+	@Test
+	public void testGetNumTransitions_2() throws Exception {
+		int markovOrder = 2;
+		MockTrieBasedModel fixture = new MockTrieBasedModel(markovOrder,
+				new Random());
+
+		int result = fixture.getNumTransitions();
+
+		assertEquals(0, result);
+	}
+
+	@Test
+	public void testTrain_1() throws Exception {
+		int markovOrder = 2;
+		MockTrieBasedModel fixture = new MockTrieBasedModel(markovOrder,
+				new Random());
+		Collection<List<? extends Event<?>>> sequences = new ArrayList<List<? extends Event<?>>>();
+		sequences.add(sequence);
+
+		fixture.train(sequences);
+
+		assertCollectionContent(symbols, fixture.getEvents());
+
+		assertTrieStructure(fixture.trie, 1);
+	}
+
+	@Test
+	public void testTrain_2() throws Exception {
+		int markovOrder = 2;
+		MockTrieBasedModel fixture = new MockTrieBasedModel(markovOrder,
+				new Random());
+		Collection<List<? extends Event<?>>> sequences = new ArrayList<List<? extends Event<?>>>();
+		sequences.add(sequence);
+		sequences.add(sequence);
+
+		fixture.train(sequences);
+
+		assertCollectionContent(symbols, fixture.getEvents());
+
+		assertTrieStructure(fixture.trie, 2);
+	}
+	
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testTrain_3() throws Exception {
+		int markovOrder = 2;
+		MockTrieBasedModel fixture = new MockTrieBasedModel(markovOrder,
+				new Random());
+		Collection<List<? extends Event<?>>> sequences = null;
+
+		fixture.train(sequences);
+	}
+
+	@Test
+	public void testUpdate_1() throws Exception {
+		int markovOrder = 2;
+		MockTrieBasedModel fixture = new MockTrieBasedModel(markovOrder,
+				new Random());
+		Collection<List<? extends Event<?>>> sequences = new ArrayList<List<? extends Event<?>>>();
+		sequences.add(sequence);
+		fixture.train(sequences);
+
+		fixture.update(sequences);
+
+		assertCollectionContent(symbols, fixture.getEvents());
+		assertTrieStructure(fixture.trie, 2);
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testUpdate_2() throws Exception {
+		int markovOrder = 2;
+		MockTrieBasedModel fixture = new MockTrieBasedModel(markovOrder,
+				new Random());
+		Collection<List<? extends Event<?>>> sequences = null;
+		fixture.trie = null;
+
+		fixture.update(sequences);
+	}
+
+	@Before
+	public void setUp() throws Exception {
+		sequence = new ArrayList<Event<?>>();
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("b"));
+		sequence.add(new Event<String>("r"));
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("c"));
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("d"));
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("b"));
+		sequence.add(new Event<String>("r"));
+		sequence.add(new Event<String>("a"));
+
+		symbols = new HashSet<Event<?>>();
+		symbols.add(new Event<String>("a"));
+		symbols.add(new Event<String>("b"));
+		symbols.add(new Event<String>("c"));
+		symbols.add(new Event<String>("d"));
+		symbols.add(new Event<String>("r"));
+		symbols.add(Event.STARTEVENT);
+		symbols.add(Event.ENDEVENT);
+	}
+
+	public static void main(String[] args) {
+		new org.junit.runner.JUnitCore().run(TrieBasedModelTest.class);
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-usageprofiles-test/src/test/java/de/ugoe/cs/quest/usageprofiles/TrieTest.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usageprofiles-test/src/test/java/de/ugoe/cs/quest/usageprofiles/TrieTest.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usageprofiles-test/src/test/java/de/ugoe/cs/quest/usageprofiles/TrieTest.java	(revision 540)
@@ -0,0 +1,727 @@
+package de.ugoe.cs.quest.usageprofiles;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+
+import junitx.framework.ListAssert;
+
+import org.junit.*;
+
+import de.ugoe.cs.quest.usageprofiles.Trie;
+import de.ugoe.cs.quest.usageprofiles.TrieNode;
+import de.ugoe.cs.quest.usageprofiles.Trie.Edge;
+import de.ugoe.cs.quest.usageprofiles.Trie.TrieVertex;
+import static org.junit.Assert.*;
+
+/**
+ * The class <code>TrieTest</code> contains tests for the class
+ * <code>{@link Trie}</code>.
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class TrieTest {
+
+	List<String> sequence;
+	Collection<String> symbols;
+
+	private static void assertCollectionContent(Collection<?> c1,
+			Collection<?> c2) {
+		assertEquals(c1.size(), c2.size());
+		for (Object obj : c1) {
+			assertTrue(c2.contains(obj));
+		}
+	}
+
+	@Test
+	public void testTrie_1() throws Exception {
+
+		Trie<String> result = new Trie<String>();
+
+		assertNotNull(result);
+		assertEquals(0, result.getNumLeafs());
+		assertEquals(0, result.getNumSymbols());
+		assertEquals(0, result.getNumLeafAncestors());
+		assertTrue(result.getKnownSymbols().isEmpty());
+	}
+
+	@Test
+	public void testTrie_2() throws Exception {
+		Trie<String> trie1 = new Trie<String>();
+		trie1.train(sequence, 3);
+
+		Trie<String> result = new Trie<String>(trie1);
+
+		assertEquals(trie1, result);
+		assertNotSame(trie1, result);
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testTrie_3() throws Exception {
+		new Trie<String>(null);
+	}
+
+	@Test
+	public void testAdd_1() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		List<String> seq = new ArrayList<String>();
+		seq.add("a");
+		seq.add("b");
+
+		fixture.add(seq);
+
+		assertEquals(1, fixture.getChild("a").getCount());
+		assertEquals(1, fixture.getChild("a").getChild("b").getCount());
+		assertNull(fixture.getChild("b"));
+	}
+
+	@Test
+	public void testAdd_2() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+
+		fixture.add(new ArrayList<String>());
+
+		assertEquals(0, fixture.getNumSymbols());
+	}
+
+	@Test
+	public void testAdd_3() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+
+		fixture.add(null);
+
+		assertEquals(0, fixture.getNumSymbols());
+	}
+
+	@Test
+	public void testFind_1() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 3);
+		List<String> findSequence = new ArrayList<String>();
+		findSequence.add("a");
+		findSequence.add("b");
+		findSequence.add("r");
+		TrieNode<String> expected = fixture.getChild("a").getChild("b")
+				.getChild("r");
+
+		TrieNode<String> result = fixture.find(findSequence);
+
+		assertEquals(expected, result);
+	}
+
+	@Test
+	public void testFind_2() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 3);
+		List<String> findSequence = new ArrayList<String>();
+		findSequence.add("c");
+		findSequence.add("a");
+		TrieNode<String> expected = fixture.getChild("c").getChild("a");
+
+		TrieNode<String> result = fixture.find(findSequence);
+
+		assertEquals(expected, result);
+	}
+
+	@Test
+	public void testFind_3() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 3);
+		List<String> findSequence = new ArrayList<String>();
+
+		TrieNode<String> result = fixture.find(findSequence);
+
+		assertTrue(result.isRoot());
+	}
+
+	@Test
+	public void testFind_4() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 3);
+
+		TrieNode<String> result = fixture.find(null);
+
+		assertTrue(result.isRoot());
+	}
+
+	@Test
+	public void testGetChildCreate_1() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		String symbol = "a";
+
+		TrieNode<String> result = fixture.getChildCreate(symbol);
+
+		assertEquals(symbol, result.getSymbol());
+		assertEquals(0, result.getCount());
+		assertTrue(result.isLeaf());
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testGetChildCreate_2() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.getChildCreate(null);
+	}
+
+	@Test
+	public void testGetContextSuffix_1() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 3);
+		List<String> context = new ArrayList<String>();
+		context.add("a");
+		context.add("a");
+		context.add("b");
+		List<String> expected = new ArrayList<String>();
+		expected.add("a");
+		expected.add("b");
+
+		List<String> result = fixture.getContextSuffix(context);
+
+		ListAssert.assertEquals(expected, result);
+	}
+
+	@Test
+	public void testGetContextSuffix_2() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 3);
+		List<String> context = new ArrayList<String>();
+		context.add("a");
+		context.add("a");
+		context.add("b");
+		context.add("r");
+		List<String> expected = new ArrayList<String>();
+		expected.add("b");
+		expected.add("r");
+
+		List<String> result = fixture.getContextSuffix(context);
+
+		ListAssert.assertEquals(expected, result);
+	}
+
+	@Test
+	public void testGetContextSuffix_3() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 3);
+		List<String> context = new ArrayList<String>();
+		context.add("a");
+		context.add("a");
+		context.add("b");
+		context.add("x");
+		List<String> expected = new ArrayList<String>();
+
+		List<String> result = fixture.getContextSuffix(context);
+
+		ListAssert.assertEquals(expected, result);
+	}
+
+	@Test
+	public void testGetContextSuffix_4() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+
+		List<String> result = fixture.getContextSuffix(null);
+
+		// add additional test code here
+		assertNotNull(result);
+		assertEquals(0, result.size());
+	}
+
+	@Test
+	public void testGetContextSuffix_5() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 3);
+		List<String> context = new ArrayList<String>();
+		context.add("a");
+		context.add("a");
+		context.add("b");
+		List<String> expected = new ArrayList<String>();
+		expected.add("a");
+		expected.add("b");
+
+		List<String> result = fixture.getContextSuffix(context);
+
+		ListAssert.assertEquals(expected, result);
+	}
+
+	@Test
+	public void testGetCount_1() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 3);
+		List<String> subSequence = new ArrayList<String>();
+		subSequence.add("a");
+
+		int result = fixture.getCount(subSequence);
+
+		assertEquals(5, result);
+	}
+
+	@Test
+	public void testGetCount_2() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 3);
+		List<String> subSequence = new ArrayList<String>();
+		subSequence.add("a");
+		subSequence.add("b");
+
+		int result = fixture.getCount(subSequence);
+
+		assertEquals(2, result);
+	}
+
+	@Test
+	public void testGetCount_3() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 3);
+		List<String> subSequence = new ArrayList<String>();
+		subSequence.add("x");
+
+		int result = fixture.getCount(subSequence);
+
+		assertEquals(0, result);
+	}
+
+	@Test
+	public void testGetCount_4() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 3);
+		List<String> subSequence = new ArrayList<String>();
+
+		int result = fixture.getCount(subSequence, "a");
+
+		assertEquals(5, result);
+	}
+
+	@Test
+	public void testGetCount_5() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 3);
+		List<String> subSequence = new ArrayList<String>();
+		subSequence.add("a");
+		subSequence.add("b");
+
+		int result = fixture.getCount(subSequence, "r");
+
+		assertEquals(2, result);
+	}
+
+	@Test
+	public void testGetCount_6() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 3);
+		List<String> subSequence = new ArrayList<String>();
+
+		int result = fixture.getCount(subSequence, "x");
+
+		assertEquals(0, result);
+	}
+
+	@Test
+	public void testGetFollowingSymbols_1() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 3);
+		List<String> subSequence = new ArrayList<String>();
+		subSequence.add("a");
+		Collection<String> expected = new ArrayList<String>();
+		expected.add("b");
+		expected.add("c");
+		expected.add("d");
+
+		Collection<String> result = fixture.getFollowingSymbols(subSequence);
+
+		assertCollectionContent(expected, result);
+	}
+
+	@Test
+	public void testGetFollowingSymbols_2() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 3);
+		List<String> subSequence = new ArrayList<String>();
+		subSequence.add("a");
+		subSequence.add("b");
+		subSequence.add("r");
+
+		Collection<String> result = fixture.getFollowingSymbols(subSequence);
+
+		assertEquals(0, result.size());
+	}
+
+	@Test
+	public void testGetFollowingSymbols_3() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 3);
+		List<String> subSequence = new ArrayList<String>();
+		subSequence.add("x");
+
+		Collection<String> result = fixture.getFollowingSymbols(subSequence);
+
+		assertEquals(0, result.size());
+	}
+
+	@Test
+	public void testGetNumLeafAncestors_1() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 3);
+
+		int result = fixture.getNumLeafAncestors();
+
+		assertEquals(7, result);
+	}
+
+	@Test
+	public void testGetNumLeafs_1() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 3);
+
+		int result = fixture.getNumLeafs();
+
+		assertEquals(7, result);
+	}
+
+	@Test
+	public void testGetNumSymbols_1() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 3);
+
+		int result = fixture.getNumSymbols();
+
+		assertEquals(5, result);
+	}
+
+	@Test
+	public void testTrain_1() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		int maxOrder = 3;
+
+		fixture.train(sequence, maxOrder);
+
+		// check if symbols are correct
+		assertCollectionContent(symbols, fixture.getKnownSymbols());
+
+		// check if counters are correct and only the correct nodes exist
+		TrieNode<String> root = fixture.find(new ArrayList<String>());
+		TrieNode<String> root_a = root.getChild("a");
+		TrieNode<String> root_a_a = root_a.getChild("a");
+		TrieNode<String> root_a_b = root_a.getChild("b");
+		TrieNode<String> root_a_b_a = root_a_b.getChild("a");
+		TrieNode<String> root_a_b_b = root_a_b.getChild("b");
+		TrieNode<String> root_a_b_c = root_a_b.getChild("c");
+		TrieNode<String> root_a_b_d = root_a_b.getChild("d");
+		TrieNode<String> root_a_b_r = root_a_b.getChild("r");
+		TrieNode<String> root_a_c = root_a.getChild("c");
+		TrieNode<String> root_a_c_a = root_a_c.getChild("a");
+		TrieNode<String> root_a_c_b = root_a_c.getChild("b");
+		TrieNode<String> root_a_c_c = root_a_c.getChild("c");
+		TrieNode<String> root_a_c_d = root_a_c.getChild("d");
+		TrieNode<String> root_a_c_r = root_a_c.getChild("r");
+		TrieNode<String> root_a_d = root_a.getChild("d");
+		TrieNode<String> root_a_d_a = root_a_d.getChild("a");
+		TrieNode<String> root_a_d_b = root_a_d.getChild("b");
+		TrieNode<String> root_a_d_c = root_a_d.getChild("c");
+		TrieNode<String> root_a_d_d = root_a_d.getChild("d");
+		TrieNode<String> root_a_d_r = root_a_d.getChild("r");
+		TrieNode<String> root_a_r = root_a.getChild("r");
+		TrieNode<String> root_b = root.getChild("b");
+		TrieNode<String> root_b_a = root_b.getChild("a");
+		TrieNode<String> root_b_b = root_b.getChild("b");
+		TrieNode<String> root_b_c = root_b.getChild("c");
+		TrieNode<String> root_b_d = root_b.getChild("d");
+		TrieNode<String> root_b_r = root_b.getChild("r");
+		TrieNode<String> root_b_r_a = root_b_r.getChild("a");
+		TrieNode<String> root_b_r_b = root_b_r.getChild("b");
+		TrieNode<String> root_b_r_c = root_b_r.getChild("c");
+		TrieNode<String> root_b_r_d = root_b_r.getChild("d");
+		TrieNode<String> root_b_r_r = root_b_r.getChild("r");
+		TrieNode<String> root_c = root.getChild("c");
+		TrieNode<String> root_c_a = root_c.getChild("a");
+		TrieNode<String> root_c_a_a = root_c_a.getChild("a");
+		TrieNode<String> root_c_a_b = root_c_a.getChild("b");
+		TrieNode<String> root_c_a_c = root_c_a.getChild("c");
+		TrieNode<String> root_c_a_d = root_c_a.getChild("d");
+		TrieNode<String> root_c_a_r = root_c_a.getChild("r");
+		TrieNode<String> root_c_b = root_c.getChild("b");
+		TrieNode<String> root_c_c = root_c.getChild("c");
+		TrieNode<String> root_c_d = root_c.getChild("d");
+		TrieNode<String> root_c_r = root_c.getChild("r");
+		TrieNode<String> root_d = root.getChild("d");
+		TrieNode<String> root_d_a = root_d.getChild("a");
+		TrieNode<String> root_d_a_a = root_d_a.getChild("a");
+		TrieNode<String> root_d_a_b = root_d_a.getChild("b");
+		TrieNode<String> root_d_a_c = root_d_a.getChild("c");
+		TrieNode<String> root_d_a_d = root_d_a.getChild("d");
+		TrieNode<String> root_d_a_r = root_d_a.getChild("r");
+		TrieNode<String> root_d_b = root_d.getChild("b");
+		TrieNode<String> root_d_c = root_d.getChild("c");
+		TrieNode<String> root_d_d = root_d.getChild("d");
+		TrieNode<String> root_d_r = root_d.getChild("r");
+		TrieNode<String> root_r = root.getChild("r");
+		TrieNode<String> root_r_a = root_r.getChild("a");
+		TrieNode<String> root_r_a_a = root_r_a.getChild("a");
+		TrieNode<String> root_r_a_b = root_r_a.getChild("b");
+		TrieNode<String> root_r_a_c = root_r_a.getChild("c");
+		TrieNode<String> root_r_a_d = root_r_a.getChild("d");
+		TrieNode<String> root_r_a_r = root_r_a.getChild("r");
+		TrieNode<String> root_r_b = root_r.getChild("b");
+		TrieNode<String> root_r_c = root_r.getChild("c");
+		TrieNode<String> root_r_d = root_r.getChild("d");
+		TrieNode<String> root_r_r = root_r.getChild("r");
+
+		assertEquals(5, root_a.getCount());
+		assertNull(root_a_a);
+		assertEquals(2, root_a_b.getCount());
+		assertNull(root_a_b_a);
+		assertNull(root_a_b_b);
+		assertNull(root_a_b_c);
+		assertNull(root_a_b_d);
+		assertEquals(2, root_a_b_r.getCount());
+		assertEquals(1, root_a_c.getCount());
+		assertEquals(1, root_a_c_a.getCount());
+		assertNull(root_a_c_b);
+		assertNull(root_a_c_c);
+		assertNull(root_a_c_d);
+		assertNull(root_a_c_r);
+		assertEquals(1, root_a_d.getCount());
+		assertEquals(1, root_a_d_a.getCount());
+		assertNull(root_a_d_b);
+		assertNull(root_a_d_c);
+		assertNull(root_a_d_d);
+		assertNull(root_a_d_r);
+		assertNull(root_a_r);
+
+		assertEquals(2, root_b.getCount());
+		assertNull(root_b_a);
+		assertNull(root_b_b);
+		assertNull(root_b_c);
+		assertNull(root_b_d);
+		assertEquals(2, root_b_r.getCount());
+		assertEquals(2, root_b_r_a.getCount());
+		assertNull(root_b_r_b);
+		assertNull(root_b_r_c);
+		assertNull(root_b_r_d);
+		assertNull(root_b_r_r);
+
+		assertEquals(1, root_c.getCount());
+		assertEquals(1, root_c_a.getCount());
+		assertNull(root_c_a_a);
+		assertNull(root_c_a_b);
+		assertNull(root_c_a_c);
+		assertEquals(1, root_c_a_d.getCount());
+		assertNull(root_c_a_r);
+		assertNull(root_c_b);
+		assertNull(root_c_c);
+		assertNull(root_c_d);
+		assertNull(root_c_r);
+
+		assertEquals(1, root_d.getCount());
+		assertEquals(1, root_d_a.getCount());
+		assertNull(root_d_a_a);
+		assertEquals(1, root_d_a_b.getCount());
+		assertNull(root_d_a_c);
+		assertNull(root_d_a_d);
+		assertNull(root_d_a_r);
+		assertNull(root_d_b);
+		assertNull(root_d_c);
+		assertNull(root_d_d);
+		assertNull(root_d_r);
+
+		assertEquals(2, root_r.getCount());
+		assertEquals(2, root_r_a.getCount());
+		assertNull(root_r_a_a);
+		assertNull(root_r_a_b);
+		assertEquals(1, root_r_a_c.getCount());
+		assertNull(root_r_a_d);
+		assertNull(root_r_a_r);
+		assertNull(root_r_b);
+		assertNull(root_r_c);
+		assertNull(root_r_d);
+		assertNull(root_r_r);
+
+		// check if leafs are really leafs
+		assertTrue(root_a_b_r.isLeaf());
+		assertTrue(root_a_c_a.isLeaf());
+		assertTrue(root_a_d_a.isLeaf());
+		assertTrue(root_b_r_a.isLeaf());
+		assertTrue(root_c_a_d.isLeaf());
+		assertTrue(root_d_a_b.isLeaf());
+		assertTrue(root_r_a_c.isLeaf());
+	}
+
+	@Test
+	public void testTrain_2() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		int maxOrder = 0;
+
+		fixture.train(sequence, maxOrder);
+
+		assertTrue(fixture.getKnownSymbols().isEmpty());
+	}
+
+	@Test
+	public void testTrain_3() throws Exception {
+		Trie<Object> fixture = new Trie<Object>();
+		List<Object> sequence = new ArrayList<Object>();
+		int maxOrder = 1;
+
+		fixture.train(sequence, maxOrder);
+
+		assertTrue(fixture.getKnownSymbols().isEmpty());
+	}
+
+	@Test
+	public void testTrain_4() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		List<String> sequence = new ArrayList<String>();
+		sequence.add("a");
+		sequence.add("b");
+		int maxOrder = 3;
+
+		fixture.train(sequence, maxOrder);
+
+		assertCollectionContent(sequence, fixture.getKnownSymbols());
+		TrieNode<String> root = fixture.find(new ArrayList<String>());
+		TrieNode<String> root_a = root.getChild("a");
+		TrieNode<String> root_a_a = root_a.getChild("a");
+		TrieNode<String> root_a_b = root_a.getChild("b");
+		TrieNode<String> root_b = root.getChild("b");
+		TrieNode<String> root_b_a = root_b.getChild("a");
+		TrieNode<String> root_b_b = root_b.getChild("b");
+
+		assertEquals(1, root_a.getCount());
+		assertNull(root_a_a);
+		assertEquals(1, root_a_b.getCount());
+		assertEquals(1, root_b.getCount());
+		assertNull(root_b_a);
+		assertNull(root_b_b);
+
+		assertTrue(root_a_b.isLeaf());
+		assertTrue(root_b.isLeaf());
+	}
+
+	@Test
+	public void testEdgeEdge_1() throws Exception {
+		Edge result = new Edge();
+
+		assertNotNull(result);
+	}
+
+	@Test
+	public void testTrieVertexTrieVertex_1() throws Exception {
+		String id = "idString";
+
+		TrieVertex result = new TrieVertex(id);
+
+		assertNotNull(result);
+	}
+
+	@Test
+	public void testTrieVertexToString_1() throws Exception {
+		String id = "idString";
+		TrieVertex fixture = new TrieVertex(id);
+
+		String result = fixture.toString();
+
+		assertEquals(id, result);
+	}
+
+	@Test
+	public void testEquals_1() throws Exception {
+		Trie<String> trieOther = new Trie<String>();
+		Trie<String> fixture = new Trie<String>();
+
+		boolean result = fixture.equals(trieOther);
+
+		assertEquals(true, result);
+	}
+
+	@Test
+	public void testEquals_2() throws Exception {
+		Trie<String> trieOther = new Trie<String>();
+		trieOther.train(sequence, 2);
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 2);
+
+		boolean result = fixture.equals(trieOther);
+
+		assertEquals(true, result);
+	}
+
+	@Test
+	public void testEquals_3() throws Exception {
+		Trie<String> trieOther = new Trie<String>();
+		trieOther.train(sequence, 2);
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 3);
+
+		boolean result = fixture.equals(trieOther);
+
+		assertEquals(false, result);
+	}
+
+	@Test
+	public void testEquals_4() throws Exception {
+		Trie<String> trieOther = new Trie<String>();
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 2);
+
+		boolean result = fixture.equals(trieOther);
+
+		assertEquals(false, result);
+	}
+
+	@Test
+	public void testEquals_5() throws Exception {
+		Trie<String> trieOther = new Trie<String>();
+		trieOther.train(sequence, 2);
+		Trie<String> fixture = new Trie<String>();
+
+		boolean result = fixture.equals(trieOther);
+
+		assertEquals(false, result);
+	}
+
+	@Test
+	public void testEquals_6() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 2);
+
+		boolean result = fixture.equals(fixture);
+
+		assertEquals(true, result);
+	}
+
+	@Test
+	public void testEquals_7() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 2);
+
+		boolean result = fixture.equals(null);
+
+		assertEquals(false, result);
+	}
+
+	@Before
+	public void setUp() throws Exception {
+		sequence = new ArrayList<String>();
+		sequence.add("a");
+		sequence.add("b");
+		sequence.add("r");
+		sequence.add("a");
+		sequence.add("c");
+		sequence.add("a");
+		sequence.add("d");
+		sequence.add("a");
+		sequence.add("b");
+		sequence.add("r");
+		sequence.add("a");
+
+		symbols = new HashSet<String>();
+		symbols.add("a");
+		symbols.add("b");
+		symbols.add("c");
+		symbols.add("d");
+		symbols.add("r");
+	}
+
+	public static void main(String[] args) {
+		new org.junit.runner.JUnitCore().run(TrieTest.class);
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/.classpath
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/.classpath	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/.classpath	(revision 540)
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/classes" path="src/main/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
Index: /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/.project
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/.project	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/.project	(revision 540)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>quest-core-usageprofiles</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
Index: /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/.settings/org.eclipse.jdt.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/.settings/org.eclipse.jdt.core.prefs	(revision 540)
@@ -0,0 +1,5 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.6
Index: /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/.settings/org.eclipse.m2e.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/.settings/org.eclipse.m2e.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/.settings/org.eclipse.m2e.core.prefs	(revision 540)
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
Index: /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/pom.xml
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/pom.xml	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/pom.xml	(revision 540)
@@ -0,0 +1,30 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>de.ugoe.cs.quest</groupId>
+	<artifactId>quest-core-usageprofiles</artifactId>
+	<version>0.0.1-SNAPSHOT</version>
+	<name>quest-core-usageprofiles</name>
+	<scm>
+		<url>https://quest.informatik.uni-goettingen.de/svn/quest/trunk/quest-core-usageprofiles</url>
+	</scm>
+	<dependencies>
+		<dependency>
+			<groupId>de.ugoe.cs.quest</groupId>
+			<artifactId>quest-core-events</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+		</dependency>
+	</dependencies>
+	<build>
+		<plugins>
+			<plugin>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>2.3.2</version>
+				<configuration>
+					<source>1.6</source>
+					<target>1.6</target>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+</project>
Index: /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/src/main/java/de/ugoe/cs/quest/usageprofiles/DeterministicFiniteAutomaton.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/src/main/java/de/ugoe/cs/quest/usageprofiles/DeterministicFiniteAutomaton.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/src/main/java/de/ugoe/cs/quest/usageprofiles/DeterministicFiniteAutomaton.java	(revision 540)
@@ -0,0 +1,80 @@
+package de.ugoe.cs.quest.usageprofiles;
+
+import java.security.InvalidParameterException;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Random;
+
+import de.ugoe.cs.quest.eventcore.Event;
+
+/**
+ * <p>
+ * Implements a Deterministic Finite Automata (DFA) capable of random session
+ * generation. It is a special case of a first-order Markov model, where the
+ * transition probability is equally high for all following states.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class DeterministicFiniteAutomaton extends FirstOrderMarkovModel {
+
+	/**
+	 * <p>
+	 * Id for object serialization.
+	 * </p>
+	 */
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new DeterministicFiniteAutomaton.
+	 * </p>
+	 * 
+	 * @param r
+	 *            random number generator used by probabilistic methods of the
+	 *            class
+	 */
+	public DeterministicFiniteAutomaton(Random r) {
+		super(r);
+	}
+
+	/**
+	 * <p>
+	 * Calculates the proability of the next state. Each of the following states
+	 * in the automaton is equally probable.
+	 * </p>
+	 * 
+	 * @see de.ugoe.cs.quest.usageprofiles.IStochasticProcess#getProbability(java.util.List,
+	 *      de.ugoe.cs.quest.eventcore.Event)
+	 */
+	@Override
+	public double getProbability(List<? extends Event<?>> context,
+			Event<?> symbol) {
+		if( context==null ) {
+			throw new InvalidParameterException("context must not be null");
+		}
+		if( symbol==null ) {
+			throw new InvalidParameterException("symbol must not be null");
+		}
+		double result = 0.0d;
+
+		List<Event<?>> contextCopy;
+		if (context.size() >= trieOrder) {
+			contextCopy = new LinkedList<Event<?>>(context.subList(
+					context.size() - trieOrder + 1, context.size()));
+		} else {
+			contextCopy = new LinkedList<Event<?>>(context);
+		}
+
+		Collection<Event<?>> followers = trie.getFollowingSymbols(contextCopy);
+
+		if (followers.size() != 0 && followers.contains(symbol)) {
+			result = 1.0d / followers.size();
+		}
+
+		return result;
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/src/main/java/de/ugoe/cs/quest/usageprofiles/FirstOrderMarkovModel.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/src/main/java/de/ugoe/cs/quest/usageprofiles/FirstOrderMarkovModel.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/src/main/java/de/ugoe/cs/quest/usageprofiles/FirstOrderMarkovModel.java	(revision 540)
@@ -0,0 +1,264 @@
+package de.ugoe.cs.quest.usageprofiles;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Random;
+
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.util.StringTools;
+import de.ugoe.cs.util.console.Console;
+import edu.uci.ics.jung.graph.Graph;
+import edu.uci.ics.jung.graph.SparseMultigraph;
+import edu.uci.ics.jung.graph.util.EdgeType;
+
+import Jama.Matrix;
+
+/**
+ * <p>
+ * Implements first-order Markov models. The implementation is based on
+ * {@link HighOrderMarkovModel} and restricts the Markov order to 1. In
+ * comparison to {@link HighOrderMarkovModel}, more calculations are possible
+ * with first-order models, e.g., the calculation of the entropy (
+ * {@link #calcEntropy()}).
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class FirstOrderMarkovModel extends HighOrderMarkovModel implements
+		IDotCompatible {
+
+	/**
+	 * <p>
+	 * Id for object serialization.
+	 * </p>
+	 */
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * <p>
+	 * Maximum number of iterations when calculating the stationary distribution
+	 * as the limit of multiplying the transmission matrix with itself.
+	 * </p>
+	 */
+	final static int MAX_STATDIST_ITERATIONS = 1000;
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new FirstOrderMarkovModel.
+	 * </p>
+	 * 
+	 * @param r
+	 *            random number generator used by probabilistic methods of the
+	 *            class
+	 */
+	public FirstOrderMarkovModel(Random r) {
+		super(1, r);
+	}
+
+	/**
+	 * <p>
+	 * Generates the transmission matrix of the Markov model.
+	 * </p>
+	 * 
+	 * @return transmission matrix
+	 */
+	private Matrix getTransmissionMatrix() {
+		List<Event<?>> knownSymbols = new ArrayList<Event<?>>(
+				trie.getKnownSymbols());
+		int numStates = knownSymbols.size();
+		Matrix transmissionMatrix = new Matrix(numStates, numStates);
+
+		for (int i = 0; i < numStates; i++) {
+			Event<?> currentSymbol = knownSymbols.get(i);
+			List<Event<?>> context = new ArrayList<Event<?>>();
+			context.add(currentSymbol);
+			for (int j = 0; j < numStates; j++) {
+				Event<?> follower = knownSymbols.get(j);
+				double prob = getProbability(context, follower);
+				transmissionMatrix.set(i, j, prob);
+			}
+		}
+		return transmissionMatrix;
+	}
+
+	/**
+	 * <p>
+	 * Calculates the entropy of the model. To make it possible that the model
+	 * is stationary, a transition from {@link Event#ENDEVENT} to
+	 * {@link Event#STARTEVENT} is added.
+	 * </p>
+	 * 
+	 * @return entropy of the model or NaN if it could not be calculated
+	 */
+	public double calcEntropy() {
+		Matrix transmissionMatrix = getTransmissionMatrix();
+		List<Event<?>> knownSymbols = new ArrayList<Event<?>>(
+				trie.getKnownSymbols());
+		int numStates = knownSymbols.size();
+
+		List<Integer> startIndexList = new LinkedList<Integer>();
+		List<Integer> endIndexList = new LinkedList<Integer>();
+		for( int i=0 ; i<knownSymbols.size() ; i++ ) {
+			String id = knownSymbols.get(i).getStandardId();
+			if( id.equals(Event.STARTEVENT.getStandardId()) || id.contains(Event.STARTEVENT.getStandardId()+"-=-") ) {
+				startIndexList.add(i);
+			}
+			if( id.equals(Event.ENDEVENT.getStandardId()) || id.contains("-=-"+Event.ENDEVENT.getStandardId()) ) {
+				endIndexList.add(i);
+			}
+		}
+		
+		if (startIndexList.isEmpty()) {	
+			Console.printerrln("Error calculating entropy. Initial state of markov chain not found.");
+			return Double.NaN;
+		}
+		if (endIndexList.isEmpty()) {
+			Console.printerrln("Error calculating entropy. End state of markov chain not found.");
+			return Double.NaN;
+		}
+		for( Integer i : endIndexList ) {
+			for(Integer j : startIndexList ) {
+				transmissionMatrix.set(i, j, 1);
+			}
+		}
+
+		// Calculate stationary distribution by raising the power of the
+		// transmission matrix.
+		// The rank of the matrix should fall to 1 and each two should be the
+		// vector of the stationory distribution.
+		int iter = 0;
+		int rank = transmissionMatrix.rank();
+		Matrix stationaryMatrix = (Matrix) transmissionMatrix.clone();
+		while (iter < MAX_STATDIST_ITERATIONS && rank > 1) {
+			stationaryMatrix = stationaryMatrix.times(stationaryMatrix);
+			rank = stationaryMatrix.rank();
+			iter++;
+		}
+
+		if (rank != 1) {
+			Console.traceln("rank: " + rank);
+			Console.printerrln("Unable to calculate stationary distribution.");
+			return Double.NaN;
+		}
+
+		double entropy = 0.0;
+		for (int i = 0; i < numStates; i++) {
+			for (int j = 0; j < numStates; j++) {
+				if (transmissionMatrix.get(i, j) != 0 && transmissionMatrix.get(i, j)!=1) {
+					double tmp = stationaryMatrix.get(0, i);
+					tmp *= transmissionMatrix.get(i, j);
+					tmp *= Math.log(transmissionMatrix.get(i, j)) / Math.log(2);
+					entropy -= tmp;
+				}
+			}
+		}
+		return entropy;
+	}
+
+	/**
+	 * <p>
+	 * The dot represenation of {@link FirstOrderMarkovModel}s is its graph
+	 * representation with the states as nodes and directed edges weighted with
+	 * transition probabilities.
+	 * </p>
+	 * 
+	 * @see de.ugoe.cs.quest.usageprofiles.IDotCompatible#getDotRepresentation()
+	 */
+	@Override
+	public String getDotRepresentation() {
+		StringBuilder stringBuilder = new StringBuilder();
+		stringBuilder.append("digraph model {" + StringTools.ENDLINE);
+
+		List<Event<?>> knownSymbols = new ArrayList<Event<?>>(
+				trie.getKnownSymbols());
+		for (Event<?> symbol : knownSymbols) {
+			final String thisSaneId = symbol.getShortId().replace("\"", "\\\"")
+					.replaceAll("[\r\n]", "");
+			stringBuilder.append(" " + knownSymbols.indexOf(symbol) + " [label=\""
+					+ thisSaneId + "\"];" + StringTools.ENDLINE);
+			List<Event<?>> context = new ArrayList<Event<?>>();
+			context.add(symbol);
+			Collection<Event<?>> followers = trie.getFollowingSymbols(context);
+			for (Event<?> follower : followers) {
+				stringBuilder.append(" " + knownSymbols.indexOf(symbol) + " -> "
+						+ knownSymbols.indexOf(follower) + " ");
+				stringBuilder.append("[label=\""
+						+ getProbability(context, follower) + "\"];"
+						+ StringTools.ENDLINE);
+			}
+		}
+		stringBuilder.append('}' + StringTools.ENDLINE);
+		return stringBuilder.toString();
+	}
+
+	/**
+	 * <p>
+	 * Returns a {@link Graph} representation of the model with the states as
+	 * nodes and directed edges weighted with transition probabilities.
+	 * </p>
+	 * 
+	 * @return {@link Graph} of the model
+	 */
+	public Graph<String, MarkovEdge> getGraph() {
+		Graph<String, MarkovEdge> graph = new SparseMultigraph<String, MarkovEdge>();
+
+		List<Event<?>> knownSymbols = new ArrayList<Event<?>>(
+				trie.getKnownSymbols());
+
+		for (Event<?> symbol : knownSymbols) {
+			String from = symbol.getShortId();
+			List<Event<?>> context = new ArrayList<Event<?>>();
+			context.add(symbol);
+
+			Collection<Event<?>> followers = trie.getFollowingSymbols(context);
+
+			for (Event<?> follower : followers) {
+				String to = follower.getShortId();
+				MarkovEdge prob = new MarkovEdge(getProbability(context,
+						follower));
+				graph.addEdge(prob, from, to, EdgeType.DIRECTED);
+			}
+		}
+		return graph;
+	}
+
+	/**
+	 * Inner class used for the {@link Graph} representation of the model.
+	 * 
+	 * @author Steffen Herbold
+	 * @version 1.0
+	 */
+	static public class MarkovEdge {
+		/**
+		 * <p>
+		 * Weight of the edge, i.e., its transition probability.
+		 * </p>
+		 */
+		double weight;
+
+		/**
+		 * <p>
+		 * Constructor. Creates a new MarkovEdge.
+		 * </p>
+		 * 
+		 * @param weight
+		 *            weight of the edge, i.e., its transition probability
+		 */
+		MarkovEdge(double weight) {
+			this.weight = weight;
+		}
+
+		/**
+		 * <p>
+		 * The weight of the edge as {@link String}.
+		 * </p>
+		 */
+		public String toString() {
+			return "" + weight;
+		}
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/src/main/java/de/ugoe/cs/quest/usageprofiles/HighOrderMarkovModel.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/src/main/java/de/ugoe/cs/quest/usageprofiles/HighOrderMarkovModel.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/src/main/java/de/ugoe/cs/quest/usageprofiles/HighOrderMarkovModel.java	(revision 540)
@@ -0,0 +1,87 @@
+package de.ugoe.cs.quest.usageprofiles;
+
+import java.security.InvalidParameterException;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Random;
+
+import de.ugoe.cs.quest.eventcore.Event;
+
+/**
+ * <p>
+ * Implements high-order Markov models.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class HighOrderMarkovModel extends TrieBasedModel {
+
+	/**
+	 * <p>
+	 * Id for object serialization.
+	 * </p>
+	 */
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new HighOrderMarkovModel with a defined Markov
+	 * order.
+	 * </p>
+	 * 
+	 * @param maxOrder
+	 *            Markov order of the model
+	 * @param r
+	 *            random number generator used by probabilistic methods of the
+	 *            class
+	 */
+	public HighOrderMarkovModel(int maxOrder, Random r) {
+		super(maxOrder, r);
+	}
+
+	/**
+	 * <p>
+	 * Calculates the probability of the next Event being symbol based on the
+	 * order of the Markov model. The order is defined in the constructor
+	 * {@link #HighOrderMarkovModel(int, Random)}.
+	 * </p>
+	 * 
+	 * @see de.ugoe.cs.quest.usageprofiles.IStochasticProcess#getProbability(java.util.List,
+	 *      de.ugoe.cs.quest.eventcore.Event)
+	 */
+	@Override
+	public double getProbability(List<? extends Event<?>> context,
+			Event<?> symbol) {
+		if (context == null) {
+			throw new InvalidParameterException("context must not be null");
+		}
+		if (symbol == null) {
+			throw new InvalidParameterException("symbol must not be null");
+		}
+		double result = 0.0d;
+
+		List<Event<?>> contextCopy;
+		if (context.size() >= trieOrder) {
+			contextCopy = new LinkedList<Event<?>>(context.subList(
+					context.size() - trieOrder + 1, context.size()));
+		} else {
+			contextCopy = new LinkedList<Event<?>>(context);
+		}
+
+		Collection<Event<?>> followers = trie.getFollowingSymbols(contextCopy);
+		int sumCountFollowers = 0; // N(s\sigma')
+		for (Event<?> follower : followers) {
+			sumCountFollowers += trie.getCount(contextCopy, follower);
+		}
+
+		int countSymbol = trie.getCount(contextCopy, symbol);
+		if (sumCountFollowers != 0) {
+			result = ((double) countSymbol / sumCountFollowers);
+		}
+
+		return result;
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/src/main/java/de/ugoe/cs/quest/usageprofiles/IDotCompatible.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/src/main/java/de/ugoe/cs/quest/usageprofiles/IDotCompatible.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/src/main/java/de/ugoe/cs/quest/usageprofiles/IDotCompatible.java	(revision 540)
@@ -0,0 +1,22 @@
+package de.ugoe.cs.quest.usageprofiles;
+
+/**
+ * <p>
+ * Models implementing this interface provide a graph representation of
+ * themselves as a {@link String} with Dot syntax.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public interface IDotCompatible {
+
+	/**
+	 * <p>
+	 * Returns a Dot representation of the model.
+	 * </p>
+	 * 
+	 * @return string with Dot syntax that describes the model.
+	 */
+	public abstract String getDotRepresentation();
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/src/main/java/de/ugoe/cs/quest/usageprofiles/IMemory.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/src/main/java/de/ugoe/cs/quest/usageprofiles/IMemory.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/src/main/java/de/ugoe/cs/quest/usageprofiles/IMemory.java	(revision 540)
@@ -0,0 +1,40 @@
+package de.ugoe.cs.quest.usageprofiles;
+
+import java.util.List;
+
+/**
+ * <p>
+ * This interface defines basic functions for classes that implement a memory
+ * about the recent events of a sequences.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ * 
+ * @param <T>
+ *            Type of the sequence elements that are memorized.
+ */
+public interface IMemory<T> {
+
+	/**
+	 * Adds an element to the end of the memory.
+	 * 
+	 * @param element
+	 *            Element to be added.
+	 */
+	public void add(T element);
+
+	/**
+	 * <p>
+	 * Returns the last <code>num</code> memorized elements. If the history is
+	 * shorter than <code>num</code>, the length of the returned
+	 * {@link java.util.List} may be less than <code>num</code>.
+	 * </p>
+	 * 
+	 * @param num
+	 *            Number of states from the end of the memory to be returned.
+	 * @return {@link java.util.List} of memorized elements.
+	 */
+	public List<T> getLast(int num);
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/src/main/java/de/ugoe/cs/quest/usageprofiles/IStochasticProcess.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/src/main/java/de/ugoe/cs/quest/usageprofiles/IStochasticProcess.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/src/main/java/de/ugoe/cs/quest/usageprofiles/IStochasticProcess.java	(revision 540)
@@ -0,0 +1,194 @@
+package de.ugoe.cs.quest.usageprofiles;
+
+import java.io.Serializable;
+import java.security.InvalidParameterException;
+import java.util.Collection;
+import java.util.List;
+
+import de.ugoe.cs.quest.eventcore.Event;
+
+/**
+ * <p>
+ * This interface defines the functionalities provided by stochastic processes.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public interface IStochasticProcess extends Serializable {
+
+	/**
+	 * <p>
+	 * Returns the probability, that the next event is {@code symbol} given the
+	 * last events are {@code context}. The last element of {@code context} is
+	 * the most recent in the history, the first element is the oldest.
+	 * </p>
+	 * 
+	 * @param context
+	 *            recently observed symbols
+	 * @param symbol
+	 *            event for which the probability is calculated
+	 * @return probabilty the {@code symbol} is the next event, given the last
+	 *         events {@code context}
+	 * @throws InvalidParameterException
+	 *             thrown if context or symbol is null
+	 */
+	double getProbability(List<? extends Event<?>> context, Event<?> symbol);
+
+	/**
+	 * <p>
+	 * Returns the probabilitiy that a given sequence is generated by the
+	 * stochastic process.
+	 * </p>
+	 * 
+	 * @param sequence
+	 *            sequences of which the probability is calculated
+	 * @return probability of the sequences; 1.0 if sequence is empty or null
+	 * @throws InvalidParameterException
+	 *             thrown if sequence is null
+	 */
+	double getProbability(List<? extends Event<?>> sequence);
+
+	/**
+	 * <p>
+	 * Generates a random sequence of events. The sequence starts with
+	 * {@link Event#STARTEVENT} and finishes with {@link Event#ENDEVENT}.
+	 * </p>
+	 * 
+	 * @return randomly generated sequence
+	 */
+	public List<? extends Event<?>> randomSequence();
+
+	/**
+	 * <p>
+	 * Generates a random sequence of events. The sequence starts with
+	 * {@link Event#STARTEVENT} and finishes with
+	 * <ul>
+	 * <li>{@link Event#ENDEVENT} if validEnd==true.</li>
+	 * <li>b) if a generated sequences reaches {@link Event#ENDEVENT} before
+	 * maxLength, the sequence finishes and is shorter than maxLenght.
+	 * Otherwise, the sequence finishes as soon as maxLength is reached and the
+	 * final event of the sequence must not be {@link Event#ENDEVENT}.</li>
+	 * </ul>
+	 * </p>
+	 * 
+	 * @param maxLength
+	 *            maximum length of the generated sequence
+	 * @param validEnd
+	 *            if true, only sequences that finish with
+	 *            {@link Event#ENDEVENT} are generated
+	 * @return randomly generated sequence
+	 * 
+	 */
+	public List<? extends Event<?>> randomSequence(int maxLength,
+			boolean validEnd);
+
+	/**
+	 * <p>
+	 * Generates all sequences of a given length are possible, i.e., have a
+	 * positive probability.<br>
+	 * All states are used as possible starting states.
+	 * </p>
+	 * 
+	 * @param length
+	 *            length of the generated sequences
+	 * @return generated sequences
+	 * @see #generateSequences(int, boolean)
+	 * @throws InvalidParameterException
+	 *             thrown if length is less than or equal to 0
+	 */
+	public Collection<List<? extends Event<?>>> generateSequences(int length);
+
+	/**
+	 * <p>
+	 * Generates all sequences of given length that can are possible, i.e., have
+	 * positive probability.<br>
+	 * If {@code fromStart==true}, all generated sequences start in
+	 * {@link Event#STARTEVENT}. Otherwise this method is the same as
+	 * {@link #generateSequences(int)}.
+	 * </p>
+	 * 
+	 * @param length
+	 *            length of the generated sequences
+	 * @param fromStart
+	 *            if true, all generated sequences start with
+	 *            {@link Event#STARTEVENT}
+	 * @return generated sequences
+	 * @throws InvalidParameterException
+	 *             thrown if length is less than or equal to 0
+	 */
+	public Collection<List<? extends Event<?>>> generateSequences(int length,
+			boolean fromStart);
+
+	/**
+	 * <p>
+	 * Generates all sequences starting with {@link Event#STARTEVENT} and
+	 * finishing with {@link Event#ENDEVENT} of a given length. It is possible
+	 * that no such sequence exists with the defined length and the returned set
+	 * is empty. If {@code length} is less than 2 the returned set is always
+	 * empty.
+	 * </p>
+	 * 
+	 * @param length
+	 * @return generated sequences
+	 * @throws InvalidParameterException
+	 *             thrown if length is less than or equal to 0
+	 */
+	public Collection<List<? extends Event<?>>> generateValidSequences(
+			int length);
+
+	/**
+	 * <p>
+	 * Returns the number of states known by the stochastic process, i.e., the
+	 * size of its alphabet.
+	 * </p>
+	 * 
+	 * @return number of states
+	 */
+	public int getNumSymbols();
+
+	/**
+	 * <p>
+	 * Returns a string representation of all known states.
+	 * </p>
+	 * 
+	 * @return string representation for all known states
+	 */
+	public String[] getSymbolStrings();
+
+	/**
+	 * <p>
+	 * Returns the number of states the process would have if it would be
+	 * flattened through state-splitting to a first-order Markov model.
+	 * </p>
+	 * <p>
+	 * If it is not possible to flatten the model, -1 is returned.
+	 * </p>
+	 * 
+	 * @return number of states an equivalent FOM would have; -1 if not
+	 *         available
+	 */
+	public int getNumFOMStates();
+
+	/**
+	 * <p>
+	 * Returns the number of transitions the process would have if it would be
+	 * flattened through state-splitting to a first-order Markov model.
+	 * </p>
+	 * 
+	 * @return number of transitions an equivalent FOM would have; -1 if not
+	 *         available
+	 */
+	public int getNumTransitions();
+
+	/**
+	 * <p>
+	 * Returns all states known by the stochastic process, i.e., its
+	 * {@link Event}s.
+	 * </p>
+	 * 
+	 * @return events known by the process
+	 */
+	public Collection<? extends Event<?>> getEvents();
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/src/main/java/de/ugoe/cs/quest/usageprofiles/IncompleteMemory.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/src/main/java/de/ugoe/cs/quest/usageprofiles/IncompleteMemory.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/src/main/java/de/ugoe/cs/quest/usageprofiles/IncompleteMemory.java	(revision 540)
@@ -0,0 +1,95 @@
+package de.ugoe.cs.quest.usageprofiles;
+
+import java.security.InvalidParameterException;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * <p>
+ * Implements a round-trip buffered memory of a specified length that can be
+ * used to remember the recent history. Every event that happend longer ago than
+ * the length of the memory is forgotten, hence the memory is incomplete.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ * 
+ * @param <T>
+ *            Type which is memorized.
+ */
+public class IncompleteMemory<T> implements IMemory<T> {
+
+	/**
+	 * <p>
+	 * Maximum length of the memory.
+	 * </p>
+	 */
+	private int length;
+
+	/**
+	 * <p>
+	 * Internal storage of the history.
+	 * </p>
+	 */
+	private List<T> history;
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new IncompleteMemory.
+	 * </p>
+	 * 
+	 * @param length
+	 *            number of recent events that are remembered
+	 * @throws InvalidParameterException
+	 *             This exception is thrown if the length is smaller than 1
+	 */
+	public IncompleteMemory(int length) {
+		if (length < 1) {
+			throw new InvalidParameterException(
+					"Length of IncompleteMemory must be at least 1.");
+		}
+		this.length = length;
+		history = new LinkedList<T>();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.usageprofiles.IMemory#add(java.lang.Object)
+	 */
+	@Override
+	public void add(T state) {
+		if (history.size() == length) {
+			history.remove(0);
+		}
+		history.add(state);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.usageprofiles.IMemory#getLast(int)
+	 */
+	@Override
+	public List<T> getLast(int num) {
+		if( num<1 ) {
+			return new LinkedList<T>();
+		} else {
+		return new LinkedList<T>(history.subList(
+				Math.max(0, history.size() - num),
+				history.size())); // defensive copy
+		}
+	}
+
+	/**
+	 * <p>
+	 * Returns the current length of the memory. This can be less than
+	 * {@link #length}, if the overall history is less than {@link #length}.
+	 * </p>
+	 * 
+	 * @return length of the current memory
+	 */
+	public int getLength() {
+		return history.size();
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/src/main/java/de/ugoe/cs/quest/usageprofiles/ModelFlattener.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/src/main/java/de/ugoe/cs/quest/usageprofiles/ModelFlattener.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/src/main/java/de/ugoe/cs/quest/usageprofiles/ModelFlattener.java	(revision 540)
@@ -0,0 +1,137 @@
+package de.ugoe.cs.quest.usageprofiles;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Random;
+
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.eventcore.ReplayableEvent;
+
+/**
+ * <p>
+ * This class provides functions to create flattened first-order Markov models
+ * from {@link HighOrderMarkovModel}s and {@link PredictionByPartialMatch}
+ * models through state splitting.
+ * </p>
+ * <p>
+ * If possible, the normal high-order markov model should be used, as the Events
+ * may be broken by the flattener, as, e.g., the information
+ * {@link ReplayableEvent}s contain is not preserved.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class ModelFlattener {
+
+	private static final String EVENT_SEPARATOR = "-=-";
+
+	Trie<Event<?>> firstOrderTrie;
+
+	/**
+	 * <p>
+	 * Takes a {@link HighOrderMarkovModel} and returns a
+	 * {@link FirstOrderMarkovModel} that conserves the high-order memory
+	 * through state splitting.
+	 * </p>
+	 * 
+	 * @param model
+	 *            model that is flattened
+	 * @return flattened first-order Markov model
+	 */
+	public FirstOrderMarkovModel flattenHighOrderMarkovModel(
+			HighOrderMarkovModel model) {
+		int markovOrder = model.trieOrder - 1;
+		FirstOrderMarkovModel firstOrderModel = new FirstOrderMarkovModel(
+				new Random());
+		firstOrderModel.trieOrder = 2;
+		if (markovOrder == 1) {
+			firstOrderModel.trie = new Trie<Event<?>>(model.trie);
+			firstOrderModel.trieOrder = 2;
+		} else {
+			firstOrderTrie = new Trie<Event<?>>();
+			TrieNode<Event<?>> rootNode = model.trie.find(null);
+			generateFirstOrderTrie(rootNode, new LinkedList<String>(), markovOrder);
+			firstOrderTrie.updateKnownSymbols();
+			firstOrderModel.trie = firstOrderTrie;
+		}
+
+		return firstOrderModel;
+	}
+
+	/**
+	 * <p>
+	 * <b>This method is not available yet and always return null!</b>
+	 * </p>
+	 * <p>
+	 * Takes a {@link PredictionByPartialMatch} model and returns a
+	 * {@link FirstOrderMarkovModel} that conserves the high-order memory
+	 * through state splitting.
+	 * </p>
+	 * 
+	 * @param model
+	 *            model that is flattened
+	 * @return flattened first-order Markov model
+	 */
+	public FirstOrderMarkovModel flattenPredictionByPartialMatch(
+			PredictionByPartialMatch model) {
+		// TODO implement method
+		return null;
+	}
+
+	/**
+	 * <p>
+	 * Converts all nodes of the given depth into first-order node through
+	 * state-splitting. For each node at the given depth a new node is created
+	 * and appropriate transitions will be added.
+	 * </p>
+	 * <p>
+	 * This method traverses through the tree recursively. If the recursion
+	 * reaches the desired depth in the tree, node are added.
+	 * </p>
+	 * 
+	 * @param currentNode
+	 *            node whose sub-trie is currently traversed
+	 * @param parentIDs
+	 *            ID strings of the ancestors of the currentNode
+	 * @param depth
+	 *            depth to go - NOT the current depth.
+	 */
+	private void generateFirstOrderTrie(TrieNode<Event<?>> currentNode,
+			List<String> parentIDs, int depth) {
+		for (TrieNode<Event<?>> child : currentNode.getChildren()) {
+			String currentId = child.getSymbol().getStandardId();
+			if (depth > 1) {
+				List<String> childParentIDs = new LinkedList<String>(parentIDs);
+				childParentIDs.add(currentId);
+				generateFirstOrderTrie(child, childParentIDs, depth - 1);
+
+			} else {
+				StringBuilder firstOrderID = new StringBuilder();
+				for (String parentID : parentIDs) {
+					firstOrderID.append(parentID + EVENT_SEPARATOR);
+				}
+				firstOrderID.append(currentId);
+				TrieNode<Event<?>> firstOrderNode = firstOrderTrie
+						.getChildCreate(new Event<Object>(firstOrderID
+								.toString()));
+				firstOrderNode.setCount(child.getCount());
+				for (TrieNode<Event<?>> transitionChild : child.getChildren()) {
+					StringBuilder transitionID = new StringBuilder();
+					for (String parentID : parentIDs.subList(1,
+							parentIDs.size())) {
+						transitionID.append(parentID + EVENT_SEPARATOR);
+					}
+					transitionID.append(currentId + EVENT_SEPARATOR);
+					transitionID.append(transitionChild.getSymbol()
+							.getStandardId());
+					TrieNode<Event<?>> firstOrderTransitionChild = firstOrderNode
+							.getChildCreate(new Event<Object>(transitionID
+									.toString()));
+					firstOrderTransitionChild.setCount(transitionChild
+							.getCount());
+				}
+			}
+		}
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/src/main/java/de/ugoe/cs/quest/usageprofiles/PredictionByPartialMatch.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/src/main/java/de/ugoe/cs/quest/usageprofiles/PredictionByPartialMatch.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/src/main/java/de/ugoe/cs/quest/usageprofiles/PredictionByPartialMatch.java	(revision 540)
@@ -0,0 +1,200 @@
+package de.ugoe.cs.quest.usageprofiles;
+
+import java.security.InvalidParameterException;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Random;
+
+import de.ugoe.cs.quest.eventcore.Event;
+
+/**
+ * <p>
+ * Implements Prediction by Partial Match (PPM) based on the following formula
+ * (LaTeX-style notation):<br>
+ * P_{PPM}(X_n|X_{n-1},...,X_{n-k}) = \sum_{i=k}^min escape^{k-i} P_{MM^i}(X_n
+ * |X_{n-1},...,X_{n-i})(1-escape)+escape^(k-min)P(X_n|X_{n-i},... ,X_{n-min})<br>
+ * P_{MM^i} denotes the probability in an i-th order Markov model.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * 
+ */
+public class PredictionByPartialMatch extends TrieBasedModel {
+
+	/**
+	 * <p>
+	 * Id for object serialization.
+	 * </p>
+	 */
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * <p>
+	 * Minimum order of the Markov model.
+	 * </p>
+	 */
+	protected int minOrder;
+
+	/**
+	 * <p>
+	 * Probability to use a lower-order Markov model
+	 * </p>
+	 */
+	protected double probEscape;
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new PredictionByPartialMatch model with a given
+	 * Markov order and a default escape probability of 0.1.
+	 * </p>
+	 * 
+	 * @param markovOrder
+	 *            Markov order of the model
+	 * @param r
+	 *            random number generator used by probabilistic methods of the
+	 *            class
+	 */
+	public PredictionByPartialMatch(int markovOrder, Random r) {
+		this(markovOrder, r, 0.1);
+	}
+
+	/**
+	 * <p>
+	 * Creates a new PredictionByPartialMatch model with a given Markov order
+	 * and escape probability.
+	 * </p>
+	 * 
+	 * @param markovOrder
+	 *            Markov order of the model
+	 * @param r
+	 *            random number generator used by probabilistic methods of the
+	 *            class
+	 * @param probEscape
+	 *            escape probability used by the model
+	 */
+	public PredictionByPartialMatch(int markovOrder, Random r, double probEscape) {
+		this(markovOrder, 0, r, probEscape);
+	}
+
+	/**
+	 * <p>
+	 * Creates a new PredictionByPartialMatch model with a given Markov order
+	 * and escape probability.
+	 * </p>
+	 * 
+	 * @param markovOrder
+	 *            Markov order of the model
+	 * @param minOrder
+	 *            minimum order of the model; if this order is reached, there is
+	 *            no escape
+	 * @param r
+	 *            random number generator used by probabilistic methods of the
+	 *            class
+	 * @param probEscape
+	 *            escape probability used by the model
+	 * @throws InvalidParameterException thrown if minOrder is less than 0 or greater than markovOrder or probEscape is not in the interval (0,1)
+	 */
+	public PredictionByPartialMatch(int markovOrder, int minOrder, Random r,
+			double probEscape) {
+		super(markovOrder, r);
+		if( minOrder< 0 ) {
+			throw new InvalidParameterException("minOrder must be greather than or equal to 0");
+		}
+		if( minOrder>markovOrder) {
+			throw new InvalidParameterException("minOrder must be less than or equal to markovOrder");
+		}
+		if( probEscape<=0.0 || probEscape>=1.0) {
+			throw new InvalidParameterException("probEscape must be in the interval (0,1)");
+		}
+		this.probEscape = probEscape;
+		this.minOrder = minOrder;
+	}
+
+	/**
+	 * <p>
+	 * Sets the escape probability of the model.
+	 * </p>
+	 * 
+	 * @param probEscape
+	 *            new escape probability
+	 */
+	public void setProbEscape(double probEscape) {
+		this.probEscape = probEscape;
+	}
+
+	/**
+	 * <p>
+	 * Returns the escape probability of the model.
+	 * </p>
+	 * 
+	 * @return escape probability of the model
+	 */
+	public double getProbEscape() {
+		return probEscape;
+	}
+
+	/**
+	 * <p>
+	 * Calculates the probability of the next event based on the formula:<br>
+	 * P_{PPM}(X_n|X_{n-1},...,X_{n-k}) = \sum_{i=k}^min escape^{k-i}
+	 * P_{MM^i}(X_n
+	 * |X_{n-1},...,X_{n-i})(1-escape)+escape^(k-min)P(X_n|X_{n-i},...
+	 * ,X_{n-min})<br>
+	 * P_{MM^i} denotes the probability in an i-th order Markov model.
+	 * </p>
+	 * 
+	 * @see de.ugoe.cs.quest.usageprofiles.IStochasticProcess#getProbability(java.util.List,
+	 *      de.ugoe.cs.quest.eventcore.Event)
+	 */
+	@Override
+	public double getProbability(List<? extends Event<?>> context,
+			Event<?> symbol) {
+		if (context == null) {
+			throw new InvalidParameterException("context must not be null");
+		}
+		if (symbol == null) {
+			throw new InvalidParameterException("symbol must not be null");
+		}
+		double result = 0.0d;
+		double resultCurrentContex = 0.0d;
+		double resultShorterContex = 0.0d;
+
+		List<Event<?>> contextCopy;
+		if (context.size() >= trieOrder) {
+			contextCopy = new LinkedList<Event<?>>(context.subList(
+					context.size() - trieOrder + 1, context.size()));
+		} else {
+			contextCopy = new LinkedList<Event<?>>(context);
+		}
+
+		Collection<Event<?>> followers = trie.getFollowingSymbols(contextCopy); // \Sigma'
+		int sumCountFollowers = 0; // N(s\sigma')
+		for (Event<?> follower : followers) {
+			sumCountFollowers += trie.getCount(contextCopy, follower);
+		}
+
+		int countSymbol = trie.getCount(contextCopy, symbol); // N(s\sigma)
+		if (sumCountFollowers == 0) {
+			resultCurrentContex = 0.0;
+		} else {
+			resultCurrentContex = (double) countSymbol / sumCountFollowers;
+		}
+		if (contextCopy.size() > minOrder) {
+			resultCurrentContex *= (1 - probEscape);
+			contextCopy.remove(0);
+			if (contextCopy.size() >= minOrder) {
+				double probSuffix = getProbability(contextCopy, symbol);
+
+				if (followers.size() == 0) {
+					resultShorterContex = probSuffix;
+				} else {
+					resultShorterContex = probEscape * probSuffix;
+				}
+			}
+		}
+		result = resultCurrentContex + resultShorterContex;
+
+		return result;
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/src/main/java/de/ugoe/cs/quest/usageprofiles/Trie.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/src/main/java/de/ugoe/cs/quest/usageprofiles/Trie.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/src/main/java/de/ugoe/cs/quest/usageprofiles/Trie.java	(revision 540)
@@ -0,0 +1,472 @@
+package de.ugoe.cs.quest.usageprofiles;
+
+import java.io.Serializable;
+import java.security.InvalidParameterException;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+
+import de.ugoe.cs.util.StringTools;
+
+import edu.uci.ics.jung.graph.DelegateTree;
+import edu.uci.ics.jung.graph.Graph;
+import edu.uci.ics.jung.graph.Tree;
+
+/**
+ * <p>
+ * This class implements a <it>trie</it>, i.e., a tree of sequences that the
+ * occurence of subsequences up to a predefined length. This length is the trie
+ * order.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * 
+ * @param <T>
+ *            Type of the symbols that are stored in the trie.
+ * 
+ * @see TrieNode
+ */
+public class Trie<T> implements IDotCompatible, Serializable {
+
+	/**
+	 * <p>
+	 * Id for object serialization.
+	 * </p>
+	 */
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * <p>
+	 * Collection of all symbols occuring in the trie.
+	 * </p>
+	 */
+	private Collection<T> knownSymbols;
+
+	/**
+	 * <p>
+	 * Reference to the root of the trie.
+	 * </p>
+	 */
+	private final TrieNode<T> rootNode;
+
+	/**
+	 * <p>
+	 * Contructor. Creates a new Trie.
+	 * </p>
+	 */
+	public Trie() {
+		rootNode = new TrieNode<T>();
+		knownSymbols = new LinkedHashSet<T>();
+	}
+
+	/**
+	 * <p>
+	 * Copy-Constructor. Creates a new Trie as the copy of other. The other trie
+	 * must noch be null.
+	 * </p>
+	 * 
+	 * @param other
+	 *            Trie that is copied
+	 */
+	public Trie(Trie<T> other) {
+		if (other == null) {
+			throw new InvalidParameterException("other trie must not be null");
+		}
+		rootNode = new TrieNode<T>(other.rootNode);
+		knownSymbols = new LinkedHashSet<T>(other.knownSymbols);
+	}
+
+	/**
+	 * <p>
+	 * Returns a collection of all symbols occuring in the trie.
+	 * </p>
+	 * 
+	 * @return symbols occuring in the trie
+	 */
+	public Collection<T> getKnownSymbols() {
+		return new LinkedHashSet<T>(knownSymbols);
+	}
+
+	/**
+	 * <p>
+	 * Trains the current trie using the given sequence and adds all subsequence
+	 * of length {@code maxOrder}.
+	 * </p>
+	 * 
+	 * @param sequence
+	 *            sequence whose subsequences are added to the trie
+	 * @param maxOrder
+	 *            maximum length of the subsequences added to the trie
+	 */
+	public void train(List<T> sequence, int maxOrder) {
+		if (maxOrder < 1) {
+			return;
+		}
+		IncompleteMemory<T> latestActions = new IncompleteMemory<T>(maxOrder);
+		int i = 0;
+		for (T currentEvent : sequence) {
+			latestActions.add(currentEvent);
+			knownSymbols.add(currentEvent);
+			i++;
+			if (i >= maxOrder) {
+				add(latestActions.getLast(maxOrder));
+			}
+		}
+		int sequenceLength = sequence.size();
+		for (int j = maxOrder - 1; j > 0; j--) {
+			add(sequence.subList(sequenceLength - j, sequenceLength));
+		}
+	}
+
+	/**
+	 * <p>
+	 * Adds a given subsequence to the trie and increases the counters
+	 * accordingly.
+	 * </p>
+	 * 
+	 * @param subsequence
+	 *            subsequence whose counters are increased
+	 * @see TrieNode#add(List)
+	 */
+	protected void add(List<T> subsequence) {
+		if (subsequence != null && !subsequence.isEmpty()) {
+			knownSymbols.addAll(subsequence);
+			subsequence = new LinkedList<T>(subsequence); // defensive copy!
+			T firstSymbol = subsequence.get(0);
+			TrieNode<T> node = getChildCreate(firstSymbol);
+			node.add(subsequence);
+		}
+	}
+
+	/**
+	 * <p>
+	 * Returns the child of the root node associated with the given symbol or
+	 * creates it if it does not exist yet.
+	 * </p>
+	 * 
+	 * @param symbol
+	 *            symbol whose node is required
+	 * @return node associated with the symbol
+	 * @see TrieNode#getChildCreate(Object)
+	 */
+	protected TrieNode<T> getChildCreate(T symbol) {
+		return rootNode.getChildCreate(symbol);
+	}
+
+	/**
+	 * <p>
+	 * Returns the child of the root node associated with the given symbol or
+	 * null if it does not exist.
+	 * </p>
+	 * 
+	 * @param symbol
+	 *            symbol whose node is required
+	 * @return node associated with the symbol; null if no such node exists
+	 * @see TrieNode#getChild(Object)
+	 */
+	protected TrieNode<T> getChild(T symbol) {
+		return rootNode.getChild(symbol);
+	}
+
+	/**
+	 * <p>
+	 * Returns the number of occurences of the given sequence.
+	 * </p>
+	 * 
+	 * @param sequence
+	 *            sequence whose number of occurences is required
+	 * @return number of occurences of the sequence
+	 */
+	public int getCount(List<T> sequence) {
+		int count = 0;
+		TrieNode<T> node = find(sequence);
+		if (node != null) {
+			count = node.getCount();
+		}
+		return count;
+	}
+
+	/**
+	 * <p>
+	 * Returns the number of occurences of the given prefix and a symbol that
+	 * follows it.<br>
+	 * Convenience function to simplify usage of {@link #getCount(List)}.
+	 * </p>
+	 * 
+	 * @param sequence
+	 *            prefix of the sequence
+	 * @param follower
+	 *            suffix of the sequence
+	 * @return number of occurences of the sequence
+	 * @see #getCount(List)
+	 */
+	public int getCount(List<T> sequence, T follower) {
+		List<T> tmpSequence = new LinkedList<T>(sequence);
+		tmpSequence.add(follower);
+		return getCount(tmpSequence);
+
+	}
+
+	/**
+	 * <p>
+	 * Searches the trie for a given sequence and returns the node associated
+	 * with the sequence or null if no such node is found.
+	 * </p>
+	 * 
+	 * @param sequence
+	 *            sequence that is searched for
+	 * @return node associated with the sequence
+	 * @see TrieNode#find(List)
+	 */
+	public TrieNode<T> find(List<T> sequence) {
+		if (sequence == null || sequence.isEmpty()) {
+			return rootNode;
+		}
+		List<T> sequenceCopy = new LinkedList<T>(sequence);
+		TrieNode<T> result = null;
+		TrieNode<T> node = getChild(sequenceCopy.get(0));
+		if (node != null) {
+			sequenceCopy.remove(0);
+			result = node.find(sequenceCopy);
+		}
+		return result;
+	}
+
+	/**
+	 * <p>
+	 * Returns a collection of all symbols that follow a given sequence in the
+	 * trie. In case the sequence is not found or no symbols follow the sequence
+	 * the result will be empty.
+	 * </p>
+	 * 
+	 * @param sequence
+	 *            sequence whose followers are returned
+	 * @return symbols following the given sequence
+	 * @see TrieNode#getFollowingSymbols()
+	 */
+	public Collection<T> getFollowingSymbols(List<T> sequence) {
+		Collection<T> result = new LinkedList<T>();
+		TrieNode<T> node = find(sequence);
+		if (node != null) {
+			result = node.getFollowingSymbols();
+		}
+		return result;
+	}
+
+	/**
+	 * <p>
+	 * Returns the longest suffix of the given context that is contained in the
+	 * tree and whose children are leaves.
+	 * </p>
+	 * 
+	 * @param context
+	 *            context whose suffix is searched for
+	 * @return longest suffix of the context
+	 */
+	public List<T> getContextSuffix(List<T> context) {
+		List<T> contextSuffix;
+		if (context != null) {
+			contextSuffix = new LinkedList<T>(context); // defensive copy
+		} else {
+			contextSuffix = new LinkedList<T>();
+		}
+		boolean suffixFound = false;
+
+		while (!suffixFound) {
+			if (contextSuffix.isEmpty()) {
+				suffixFound = true; // suffix is the empty word
+			} else {
+				TrieNode<T> node = find(contextSuffix);
+				if (node != null) {
+					if (!node.getFollowingSymbols().isEmpty()) {
+						suffixFound = true;
+					}
+				}
+				if (!suffixFound) {
+					contextSuffix.remove(0);
+				}
+			}
+		}
+
+		return contextSuffix;
+	}
+
+	/**
+	 * <p>
+	 * Helper class for graph visualization of a trie.
+	 * </p>
+	 * 
+	 * @author Steffen Herbold
+	 * @version 1.0
+	 */
+	static public class Edge {
+	}
+
+	/**
+	 * <p>
+	 * Helper class for graph visualization of a trie.
+	 * </p>
+	 * 
+	 * @author Steffen Herbold
+	 * @version 1.0
+	 */
+	static public class TrieVertex {
+
+		/**
+		 * <p>
+		 * Id of the vertex.
+		 * </p>
+		 */
+		private String id;
+
+		/**
+		 * <p>
+		 * Contructor. Creates a new TrieVertex.
+		 * </p>
+		 * 
+		 * @param id
+		 *            id of the vertex
+		 */
+		protected TrieVertex(String id) {
+			this.id = id;
+		}
+
+		/**
+		 * <p>
+		 * Returns the id of the vertex.
+		 * </p>
+		 * 
+		 * @see java.lang.Object#toString()
+		 */
+		@Override
+		public String toString() {
+			return id;
+		}
+	}
+
+	/**
+	 * <p>
+	 * Returns a {@link Graph} representation of the trie.
+	 * </p>
+	 * 
+	 * @return {@link Graph} representation of the trie
+	 */
+	protected Tree<TrieVertex, Edge> getGraph() {
+		DelegateTree<TrieVertex, Edge> graph = new DelegateTree<TrieVertex, Edge>();
+		rootNode.getGraph(null, graph);
+		return graph;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.usageprofiles.IDotCompatible#getDotRepresentation()
+	 */
+	public String getDotRepresentation() {
+		StringBuilder stringBuilder = new StringBuilder();
+		stringBuilder.append("digraph model {" + StringTools.ENDLINE);
+		rootNode.appendDotRepresentation(stringBuilder);
+		stringBuilder.append('}' + StringTools.ENDLINE);
+		return stringBuilder.toString();
+	}
+
+	/**
+	 * <p>
+	 * Returns the string representation of the root node.
+	 * </p>
+	 * 
+	 * @see TrieNode#toString()
+	 * @see java.lang.Object#toString()
+	 */
+	@Override
+	public String toString() {
+		return rootNode.toString();
+	}
+
+	/**
+	 * <p>
+	 * Returns the number of symbols contained in the trie.
+	 * </p>
+	 * 
+	 * @return number of symbols contained in the trie
+	 */
+	public int getNumSymbols() {
+		return knownSymbols.size();
+	}
+
+	/**
+	 * <p>
+	 * Returns the number of trie nodes that are ancestors of a leaf. This is
+	 * the equivalent to the number of states a first-order markov model would
+	 * have.
+	 * <p>
+	 * 
+	 * @return number of trie nodes that are ancestors of leafs.
+	 */
+	public int getNumLeafAncestors() {
+		List<TrieNode<T>> ancestors = new LinkedList<TrieNode<T>>();
+		rootNode.getLeafAncestors(ancestors);
+		return ancestors.size();
+	}
+
+	/**
+	 * <p>
+	 * Returns the number of trie nodes that are leafs.
+	 * </p>
+	 * 
+	 * @return number of leafs in the trie
+	 */
+	public int getNumLeafs() {
+		return rootNode.getNumLeafs();
+	}
+
+	/**
+	 * <p>
+	 * Updates the list of known symbols by replacing it with all symbols that
+	 * are found in the child nodes of the root node. This should be the same as
+	 * all symbols that are contained in the trie.
+	 * </p>
+	 */
+	public void updateKnownSymbols() {
+		knownSymbols = new HashSet<T>();
+		for (TrieNode<T> node : rootNode.getChildren()) {
+			knownSymbols.add(node.getSymbol());
+		}
+	}
+
+	/**
+	 * <p>
+	 * Two Tries are defined as equal, if their {@link #rootNode} are equal.
+	 * </p>
+	 * 
+	 * @see java.lang.Object#equals(java.lang.Object)
+	 */
+	@SuppressWarnings("rawtypes")
+	@Override
+	public boolean equals(Object other) {
+		if (other == this) {
+			return true;
+		}
+		if (other instanceof Trie) {
+			return rootNode.equals(((Trie) other).rootNode);
+		}
+		return false;
+	}
+	
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see java.lang.Object#hashCode()
+	 */
+	@Override
+	public int hashCode() {
+		int multiplier = 17;
+		int hash = 42;
+		if (rootNode != null) {
+			hash = multiplier * hash + rootNode.hashCode();
+		}
+		return hash;
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/src/main/java/de/ugoe/cs/quest/usageprofiles/TrieBasedModel.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/src/main/java/de/ugoe/cs/quest/usageprofiles/TrieBasedModel.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/src/main/java/de/ugoe/cs/quest/usageprofiles/TrieBasedModel.java	(revision 540)
@@ -0,0 +1,416 @@
+package de.ugoe.cs.quest.usageprofiles;
+
+import java.security.InvalidParameterException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Random;
+import java.util.Set;
+
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.usageprofiles.Trie.Edge;
+import de.ugoe.cs.quest.usageprofiles.Trie.TrieVertex;
+import edu.uci.ics.jung.graph.Tree;
+
+/**
+ * <p>
+ * Implements a skeleton for stochastic processes that can calculate
+ * probabilities based on a trie. The skeleton provides all functionalities of
+ * {@link IStochasticProcess} except
+ * {@link IStochasticProcess#getProbability(List, Event)}.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public abstract class TrieBasedModel implements IStochasticProcess {
+
+	/**
+	 * <p>
+	 * Id for object serialization.
+	 * </p>
+	 */
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * <p>
+	 * The order of the trie, i.e., the maximum length of subsequences stored in
+	 * the trie.
+	 * </p>
+	 */
+	protected int trieOrder;
+
+	/**
+	 * <p>
+	 * Trie on which the probability calculations are based.
+	 * </p>
+	 */
+	protected Trie<Event<?>> trie = null;
+
+	/**
+	 * <p>
+	 * Random number generator used by probabilistic sequence generation
+	 * methods.
+	 * </p>
+	 */
+	protected final Random r;
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new TrieBasedModel that can be used for stochastic
+	 * processes with a Markov order less than or equal to {@code markovOrder}.
+	 * </p>
+	 * 
+	 * @param markovOrder
+	 *            Markov order of the model
+	 * @param r
+	 *            random number generator used by probabilistic methods of the
+	 *            class
+	 * @throws InvalidParameterException
+	 *             thrown if markovOrder is less than 0 or the random number
+	 *             generator r is null
+	 */
+	public TrieBasedModel(int markovOrder, Random r) {
+		super();
+		if (markovOrder < 0) {
+			throw new InvalidParameterException(
+					"markov order must not be less than 0");
+		}
+		if (r == null) {
+			throw new InvalidParameterException(
+					"random number generator r must not be null");
+		}
+		this.trieOrder = markovOrder + 1;
+		this.r = r;
+	}
+
+	/**
+	 * <p>
+	 * Trains the model by generating a trie from which probabilities are
+	 * calculated. The trie is newly generated based solely on the passed
+	 * sequences. If an existing model should only be updated, use
+	 * {@link #update(Collection)} instead.
+	 * </p>
+	 * 
+	 * @param sequences
+	 *            training data
+	 * @throws InvalidParameterException
+	 *             thrown is sequences is null
+	 */
+	public void train(Collection<List<? extends Event<?>>> sequences) {
+		trie = null;
+		update(sequences);
+	}
+
+	/**
+	 * <p>
+	 * Trains the model by updating the trie from which the probabilities are
+	 * calculated. This function updates an existing trie. In case no trie
+	 * exists yet, a new trie is generated and the function behaves like
+	 * {@link #train(Collection)}.
+	 * </p>
+	 * 
+	 * @param sequences
+	 *            training data
+	 * @throws InvalidParameterException
+	 *             thrown is sequences is null
+	 */
+	public void update(Collection<List<? extends Event<?>>> sequences) {
+		if (sequences == null) {
+			throw new InvalidParameterException("sequences must not be null");
+		}
+		if (trie == null) {
+			trie = new Trie<Event<?>>();
+		}
+		for (List<? extends Event<?>> sequence : sequences) {
+			List<Event<?>> currentSequence = new LinkedList<Event<?>>(sequence); // defensive
+																					// copy
+			currentSequence.add(0, Event.STARTEVENT);
+			currentSequence.add(Event.ENDEVENT);
+
+			trie.train(currentSequence, trieOrder);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.usageprofiles.IStochasticProcess#randomSequence()
+	 */
+	@Override
+	public List<? extends Event<?>> randomSequence() {
+		return randomSequence(Integer.MAX_VALUE, true);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.usageprofiles.IStochasticProcess#randomSequence()
+	 */
+	@Override
+	public List<? extends Event<?>> randomSequence(int maxLength,
+			boolean validEnd) {
+		List<Event<?>> sequence = new LinkedList<Event<?>>();
+		if (trie != null) {
+			boolean endFound = false;
+			while (!endFound) { // outer loop for length checking
+				sequence = new LinkedList<Event<?>>();
+				IncompleteMemory<Event<?>> context = new IncompleteMemory<Event<?>>(
+						trieOrder - 1);
+				context.add(Event.STARTEVENT);
+
+				while (!endFound && sequence.size() <= maxLength) {
+					double randVal = r.nextDouble();
+					double probSum = 0.0;
+					List<Event<?>> currentContext = context.getLast(trieOrder);
+					for (Event<?> symbol : trie.getKnownSymbols()) {
+						probSum += getProbability(currentContext, symbol);
+						if (probSum >= randVal) {
+							if (!(Event.STARTEVENT.equals(symbol) || Event.ENDEVENT
+									.equals(symbol))) {
+								// only add the symbol the sequence if it is not
+								// START or END
+								context.add(symbol);
+								sequence.add(symbol);
+							}
+							endFound = (Event.ENDEVENT.equals(symbol))
+									|| (!validEnd && sequence.size() == maxLength);
+							break;
+						}
+					}
+				}
+			}
+		}
+		return sequence;
+	}
+
+	/**
+	 * <p>
+	 * Returns a Dot representation of the internal trie.
+	 * </p>
+	 * 
+	 * @return dot representation of the internal trie
+	 */
+	public String getTrieDotRepresentation() {
+		if (trie == null) {
+			return "";
+		} else {
+			return trie.getDotRepresentation();
+		}
+	}
+
+	/**
+	 * <p>
+	 * Returns a {@link Tree} of the internal trie that can be used for
+	 * visualization.
+	 * </p>
+	 * 
+	 * @return {@link Tree} depicting the internal trie
+	 */
+	public Tree<TrieVertex, Edge> getTrieGraph() {
+		if (trie == null) {
+			return null;
+		} else {
+			return trie.getGraph();
+		}
+	}
+
+	/**
+	 * <p>
+	 * The string representation of the model is {@link Trie#toString()} of
+	 * {@link #trie}.
+	 * </p>
+	 * 
+	 * @see java.lang.Object#toString()
+	 */
+	@Override
+	public String toString() {
+		if (trie == null) {
+			return "";
+		} else {
+			return trie.toString();
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.usageprofiles.IStochasticProcess#getNumStates()
+	 */
+	@Override
+	public int getNumSymbols() {
+		if (trie == null) {
+			return 0;
+		} else {
+			return trie.getNumSymbols();
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.usageprofiles.IStochasticProcess#getStateStrings()
+	 */
+	@Override
+	public String[] getSymbolStrings() {
+		if (trie == null) {
+			return new String[0];
+		}
+		String[] stateStrings = new String[getNumSymbols()];
+		int i = 0;
+		for (Event<?> symbol : trie.getKnownSymbols()) {
+			if (symbol.toString() == null) {
+				stateStrings[i] = "null";
+			} else {
+				stateStrings[i] = symbol.toString();
+			}
+			i++;
+		}
+		return stateStrings;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.usageprofiles.IStochasticProcess#getEvents()
+	 */
+	@Override
+	public Collection<? extends Event<?>> getEvents() {
+		if (trie == null) {
+			return new HashSet<Event<?>>();
+		} else {
+			return trie.getKnownSymbols();
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * de.ugoe.cs.quest.usageprofiles.IStochasticProcess#generateSequences(int)
+	 */
+	@Override
+	public Collection<List<? extends Event<?>>> generateSequences(int length) {
+		return generateSequences(length, false);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * de.ugoe.cs.quest.usageprofiles.IStochasticProcess#generateSequences(int,
+	 * boolean)
+	 */
+	@Override
+	public Set<List<? extends Event<?>>> generateSequences(int length,
+			boolean fromStart) {
+		Set<List<? extends Event<?>>> sequenceSet = new LinkedHashSet<List<? extends Event<?>>>();
+		if (length < 1) {
+			throw new InvalidParameterException(
+					"Length of generated subsequences must be at least 1.");
+		}
+		if (length == 1) {
+			if (fromStart) {
+				List<Event<?>> subSeq = new LinkedList<Event<?>>();
+				subSeq.add(Event.STARTEVENT);
+				sequenceSet.add(subSeq);
+			} else {
+				for (Event<?> event : getEvents()) {
+					List<Event<?>> subSeq = new LinkedList<Event<?>>();
+					subSeq.add(event);
+					sequenceSet.add(subSeq);
+				}
+			}
+			return sequenceSet;
+		}
+		Collection<? extends Event<?>> events = getEvents();
+		Collection<List<? extends Event<?>>> seqsShorter = generateSequences(
+				length - 1, fromStart);
+		for (Event<?> event : events) {
+			for (List<? extends Event<?>> seqShorter : seqsShorter) {
+				Event<?> lastEvent = event;
+				if (getProbability(seqShorter, lastEvent) > 0.0) {
+					List<Event<?>> subSeq = new ArrayList<Event<?>>(seqShorter);
+					subSeq.add(lastEvent);
+					sequenceSet.add(subSeq);
+				}
+			}
+		}
+		return sequenceSet;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * de.ugoe.cs.quest.usageprofiles.IStochasticProcess#generateValidSequences
+	 * (int)
+	 */
+	@Override
+	public Collection<List<? extends Event<?>>> generateValidSequences(
+			int length) {
+		// check for min-length implicitly done by generateSequences
+		Collection<List<? extends Event<?>>> allSequences = generateSequences(
+				length, true);
+		Collection<List<? extends Event<?>>> validSequences = new LinkedHashSet<List<? extends Event<?>>>();
+		for (List<? extends Event<?>> sequence : allSequences) {
+			if (sequence.size() == length
+					&& Event.ENDEVENT.equals(sequence.get(sequence.size() - 1))) {
+				validSequences.add(sequence);
+			}
+		}
+		return validSequences;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * de.ugoe.cs.quest.usageprofiles.IStochasticProcess#getProbability(java.util
+	 * .List)
+	 */
+	@Override
+	public double getProbability(List<? extends Event<?>> sequence) {
+		if (sequence == null) {
+			throw new InvalidParameterException("sequence must not be null");
+		}
+		double prob = 1.0;
+		List<Event<?>> context = new LinkedList<Event<?>>();
+		for (Event<?> event : sequence) {
+			prob *= getProbability(context, event);
+			context.add(event);
+		}
+		return prob;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.usageprofiles.IStochasticProcess#getNumFOMStates()
+	 */
+	@Override
+	public int getNumFOMStates() {
+		if (trie == null) {
+			return 0;
+		} else {
+			return trie.getNumLeafAncestors();
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.usageprofiles.IStochasticProcess#getNumTransitions()
+	 */
+	@Override
+	public int getNumTransitions() {
+		if (trie == null) {
+			return 0;
+		} else {
+			return trie.getNumLeafs();
+		}
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/src/main/java/de/ugoe/cs/quest/usageprofiles/TrieNode.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/src/main/java/de/ugoe/cs/quest/usageprofiles/TrieNode.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-core-usageprofiles/src/main/java/de/ugoe/cs/quest/usageprofiles/TrieNode.java	(revision 540)
@@ -0,0 +1,443 @@
+package de.ugoe.cs.quest.usageprofiles;
+
+import java.io.Serializable;
+import java.security.InvalidParameterException;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+
+import de.ugoe.cs.quest.usageprofiles.Trie.Edge;
+import de.ugoe.cs.quest.usageprofiles.Trie.TrieVertex;
+import de.ugoe.cs.util.StringTools;
+import edu.uci.ics.jung.graph.DelegateTree;
+import edu.uci.ics.jung.graph.Tree;
+
+/**
+ * <p>
+ * This class implements a node of a trie. Each node is associated with a symbol
+ * and has a counter. The counter marks the number of occurences of the sequence
+ * defined by the path from the root of the trie to this node.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * 
+ * @param <T>
+ *            Type of the symbols that are stored in the trie.
+ * @see Trie
+ */
+class TrieNode<T> implements Serializable {
+
+	/**
+	 * <p>
+	 * Id for object serialization.
+	 * </p>
+	 */
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * <p>
+	 * Counter for the number of occurences of the sequence.
+	 * </p>
+	 */
+	private int count;
+
+	/**
+	 * <p>
+	 * Symbol associated with the node.
+	 * </p>
+	 */
+	private final T symbol;
+
+	/**
+	 * <p>
+	 * Child nodes of this node. If the node is a leaf this collection is empty.
+	 * </p>
+	 */
+	private Collection<TrieNode<T>> children;
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new TrieNode without a symbol associated.<br>
+	 * <b>This constructor should only be used to create the root node of the
+	 * trie!</b>
+	 * </p>
+	 */
+	TrieNode() {
+		this.symbol = null;
+		count = 0;
+		children = new LinkedList<TrieNode<T>>();
+	}
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new TrieNode. The symbol must not be null.
+	 * </p>
+	 * 
+	 * @param symbol
+	 *            symbol associated with the trie node
+	 */
+	TrieNode(T symbol) {
+		if (symbol == null) {
+			throw new InvalidParameterException(
+					"symbol must not be null. null is reserved for root node!");
+		}
+		this.symbol = symbol;
+		count = 0;
+		children = new LinkedList<TrieNode<T>>();
+	}
+
+	/**
+	 * <p>
+	 * Copy-Constructor. Creates a new TrieNode as copy of other. Other must not
+	 * be null.
+	 * </p>
+	 * 
+	 * @param other
+	 */
+	TrieNode(TrieNode<T> other) {
+		if (other == null) {
+			throw new InvalidParameterException("other must not be null");
+		}
+		symbol = other.symbol;
+		count = other.count;
+		children = new LinkedList<TrieNode<T>>();
+		for (TrieNode<T> child : other.children) {
+			children.add(new TrieNode<T>(child));
+		}
+	}
+
+	/**
+	 * <p>
+	 * Adds a given subsequence to the trie and increases the counters
+	 * accordingly.
+	 * </p>
+	 * 
+	 * @param subsequence
+	 *            subsequence whose counters are increased
+	 * @see Trie#add(List)
+	 */
+	public void add(List<T> subsequence) {
+		if (!subsequence.isEmpty()) {
+			if (!symbol.equals(subsequence.get(0))) { // should be guaranteed by
+														// the
+														// recursion/TrieRoot!
+				throw new AssertionError("Invalid trie operation!");
+			}
+			count++;
+			subsequence.remove(0);
+			if (!subsequence.isEmpty()) {
+				T nextSymbol = subsequence.get(0);
+				getChildCreate(nextSymbol).add(subsequence);
+			}
+		}
+	}
+
+	/**
+	 * <p>
+	 * Returns the symbol associated with the node.
+	 * </p>
+	 * 
+	 * @return symbol associated with the node
+	 */
+	public T getSymbol() {
+		return symbol;
+	}
+
+	/**
+	 * <p>
+	 * Returns the number of occurences of the sequence represented by the node.
+	 * </p>
+	 * 
+	 * @return number of occurences of the sequence represented by the node
+	 */
+	public int getCount() {
+		return count;
+	}
+
+	/**
+	 * <p>
+	 * Returns the child of the node associated with the given symbol or creates
+	 * it if it does not exist yet.
+	 * </p>
+	 * 
+	 * @param symbol
+	 *            symbol whose node is required
+	 * @return node associated with the symbol
+	 * @see Trie#getChildCreate(Object)
+	 */
+	protected TrieNode<T> getChildCreate(T symbol) {
+		TrieNode<T> node = getChild(symbol);
+		if (node == null) {
+			node = new TrieNode<T>(symbol);
+			children.add(node);
+		}
+		return node;
+	}
+
+	/**
+	 * <p>
+	 * Returns the child of the node associated with the given symbol or null if
+	 * it does not exist.
+	 * </p>
+	 * 
+	 * @param symbol
+	 *            symbol whose node is required
+	 * @return node associated with the symbol; null if no such node exists
+	 * @see Trie#getChild(Object)
+	 */
+	protected TrieNode<T> getChild(T symbol) {
+		for (TrieNode<T> child : children) {
+			if (child.getSymbol().equals(symbol)) {
+				return child;
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * <p>
+	 * Returns all children of this node.
+	 * </p>
+	 * 
+	 * @return children of this node
+	 */
+	protected Collection<TrieNode<T>> getChildren() {
+		return children;
+	}
+
+	/**
+	 * <p>
+	 * Searches the sub-trie of this trie node for a given sequence and returns
+	 * the node associated with the sequence or null if no such node is found.
+	 * </p>
+	 * 
+	 * @param sequence
+	 *            sequence that is searched for
+	 * @return node associated with the sequence
+	 * @see Trie#find(List)
+	 */
+	public TrieNode<T> find(List<T> subsequence) {
+		TrieNode<T> result = null;
+		if (subsequence.isEmpty()) {
+			result = this;
+		} else {
+			TrieNode<T> node = getChild(subsequence.get(0));
+			if (node != null) {
+				subsequence.remove(0);
+				result = node.find(subsequence);
+			}
+		}
+		return result;
+	}
+
+	/**
+	 * <p>
+	 * Returns a collection of all symbols that follow a this node, i.e., the
+	 * symbols associated with the children of this node.
+	 * </p>
+	 * 
+	 * @return symbols follow this node
+	 * @see TrieNode#getFollowingSymbols()
+	 */
+	public Collection<T> getFollowingSymbols() {
+		Collection<T> followingSymbols = new LinkedList<T>();
+		for (TrieNode<T> child : children) {
+			followingSymbols.add(child.getSymbol());
+		}
+		return followingSymbols;
+	}
+
+	/**
+	 * <p>
+	 * The string representation of a node is {@code symbol.toString()#count}
+	 * </p>
+	 * 
+	 * @see java.lang.Object#toString()
+	 */
+	@Override
+	public String toString() {
+		String str = symbol.toString() + " #" + count;
+		if (!children.isEmpty()) {
+			str += StringTools.ENDLINE + children.toString();
+		}
+		return str;
+	}
+
+	/**
+	 * <p>
+	 * Generates a {@link Tree} represenation of the trie.
+	 * </p>
+	 * 
+	 * @param parent
+	 *            parent vertex in the generated tree
+	 * @param graph
+	 *            complete tree
+	 */
+	void getGraph(TrieVertex parent, DelegateTree<TrieVertex, Edge> graph) {
+		TrieVertex currentVertex;
+		if (isRoot()) {
+			currentVertex = new TrieVertex("root");
+			graph.addVertex(currentVertex);
+		} else {
+			currentVertex = new TrieVertex(getSymbol().toString() + "#"
+					+ getCount());
+			graph.addChild(new Edge(), parent, currentVertex);
+		}
+		for (TrieNode<T> node : children) {
+			node.getGraph(currentVertex, graph);
+		}
+	}
+
+	/**
+	 * <p>
+	 * Appends the current node to the dot representation of the trie.
+	 * </p>
+	 * 
+	 * @param stringBuilder
+	 *            {@link StringBuilder} to which the dot representation is
+	 *            appended
+	 */
+	void appendDotRepresentation(StringBuilder stringBuilder) {
+		String thisSaneId;
+		if (isRoot()) {
+			thisSaneId = "root";
+		} else {
+			thisSaneId = symbol.toString().replace("\"", "\\\"")
+					.replaceAll("[\r\n]", "")
+					+ "#" + count;
+		}
+		stringBuilder.append(" " + hashCode() + " [label=\"" + thisSaneId
+				+ "\"];" + StringTools.ENDLINE);
+		for (TrieNode<T> childNode : children) {
+			stringBuilder.append(" " + hashCode() + " -> "
+					+ childNode.hashCode() + ";" + StringTools.ENDLINE);
+		}
+		for (TrieNode<T> childNode : children) {
+			childNode.appendDotRepresentation(stringBuilder);
+		}
+	}
+
+	/**
+	 * <p>
+	 * Checks if the node is a leaf.
+	 * </p>
+	 * 
+	 * @return true if the node is a leaf, false otherwise.
+	 */
+	protected boolean isLeaf() {
+		return children.isEmpty();
+	}
+
+	/**
+	 * <p>
+	 * Checks if the node is the root.
+	 * </p>
+	 * 
+	 * @return true if the node is the root of the trie, false otherwise
+	 */
+	protected boolean isRoot() {
+		return symbol == null;
+	}
+
+	/**
+	 * <p>
+	 * Recursive methods that collects all nodes that are ancestors of leafs and
+	 * stores them in the set.
+	 * </p>
+	 * 
+	 * @param ancestors
+	 *            set of all ancestors of leafs
+	 */
+	protected void getLeafAncestors(List<TrieNode<T>> ancestors) {
+		boolean isAncestor = false;
+		for (TrieNode<T> child : children) {
+			child.getLeafAncestors(ancestors);
+			isAncestor |= child.isLeaf();
+		}
+		if (isAncestor) {
+			ancestors.add(this);
+		}
+	}
+
+	/**
+	 * <p>
+	 * Returns the number of descendants of this node that are leafs. This does
+	 * not only include direct children of this node, but all leafs in the
+	 * sub-trie with this node as root.
+	 * </p>
+	 * 
+	 * @return number of leafs in this sub-trie
+	 */
+	protected int getNumLeafs() {
+		int numLeafs = 0;
+		for (TrieNode<T> child : children) {
+			if (child.isLeaf()) {
+				numLeafs++;
+			} else {
+				numLeafs += child.getNumLeafs();
+			}
+		}
+		return numLeafs;
+	}
+
+	/**
+	 * <p>
+	 * Sets the {@link #count} of this node.
+	 * </p>
+	 * <p>
+	 * This function should only be used sparingly and very carefully! The count
+	 * is usually maintained automatically by the training procedures.
+	 * </p>
+	 * 
+	 * @param count
+	 *            new count
+	 */
+	protected void setCount(int count) {
+		this.count = count;
+	}
+
+	/**
+	 * <p>
+	 * Two TrieNodes are defined as equal, if their {@link #count},
+	 * {@link #symbol}, and {@link #children} are equal.
+	 * </p>
+	 * 
+	 * @see java.lang.Object#equals(java.lang.Object)
+	 */
+	@SuppressWarnings("rawtypes")
+	@Override
+	public boolean equals(Object other) {
+		if (other == this) {
+			return true;
+		}
+		if (other instanceof TrieNode) {
+			TrieNode otherNode = (TrieNode) other;
+			if (symbol == null) {
+				return count == otherNode.count && otherNode.symbol == null
+						&& children.equals(otherNode.children);
+			} else {
+				return count == otherNode.count
+						&& symbol.equals(((TrieNode) other).symbol)
+						&& children.equals(((TrieNode) other).children);
+			}
+		}
+		return false;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see java.lang.Object#hashCode()
+	 */
+	@Override
+	public int hashCode() {
+		int multiplier = 17;
+		int hash = 42;
+		if (symbol != null) {
+			hash = multiplier * hash + symbol.hashCode();
+		}
+		hash = multiplier * hash + count;
+		hash = multiplier * hash + children.hashCode();
+		return hash;
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-misc-test/.classpath
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc-test/.classpath	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc-test/.classpath	(revision 540)
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/test-classes" path="src/test/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="src" output="target/classes" path="src/main/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
Index: /tags/quest-pre-eventrefactoring/quest-misc-test/.project
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc-test/.project	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc-test/.project	(revision 540)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>quest-misc-test</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
Index: /tags/quest-pre-eventrefactoring/quest-misc-test/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc-test/.settings/org.eclipse.jdt.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc-test/.settings/org.eclipse.jdt.core.prefs	(revision 540)
@@ -0,0 +1,5 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.6
Index: /tags/quest-pre-eventrefactoring/quest-misc-test/.settings/org.eclipse.m2e.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc-test/.settings/org.eclipse.m2e.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc-test/.settings/org.eclipse.m2e.core.prefs	(revision 540)
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
Index: /tags/quest-pre-eventrefactoring/quest-misc-test/pom.xml
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc-test/pom.xml	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc-test/pom.xml	(revision 540)
@@ -0,0 +1,128 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>de.ugoe.cs.quest</groupId>
+  <artifactId>quest-misc-test</artifactId>
+  <version>0.0.1-SNAPSHOT</version>
+  <name>quest-misc-test</name>
+  <scm>
+    <url>https://quest.informatik.uni-goettingen.de/svn/quest/trunk/quest-misc-test</url>
+  </scm>
+  <dependencies>
+    <dependency>
+      <groupId>de.ugoe.cs.quest</groupId>
+      <artifactId>quest-misc</artifactId>
+      <version>0.0.1-SNAPSHOT</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+        <groupId>junit</groupId>
+        <artifactId>junit</artifactId>
+        <version>4.8.1</version>
+        <scope>test</scope>
+    </dependency>
+  </dependencies>
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.eclipse.m2e</groupId>
+          <artifactId>lifecycle-mapping</artifactId>
+          <version>1.0.0</version>
+          <configuration>
+            <lifecycleMappingMetadata>
+              <pluginExecutions>
+                <pluginExecution>
+                  <pluginExecutionFilter>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-dependency-plugin</artifactId>
+                    <versionRange>[1.0.0,)</versionRange>
+                    <goals>
+                      <goal>unpack</goal>
+                    </goals>
+                  </pluginExecutionFilter>
+                  <action>
+                    <ignore/>
+                  </action>
+                </pluginExecution>
+                <pluginExecution>
+                  <pluginExecutionFilter>
+                    <groupId>org.codehaus.mojo</groupId>
+                    <artifactId>emma-maven-plugin</artifactId>
+                    <versionRange>[1.0-alpha-3,)</versionRange>
+                    <goals>
+                      <goal>emma</goal>
+                    </goals>
+                  </pluginExecutionFilter>
+                  <action>
+                    <ignore/>
+                  </action>
+                </pluginExecution>
+              </pluginExecutions>
+            </lifecycleMappingMetadata>
+          </configuration>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>2.3.2</version>
+        <configuration>
+          <source>1.6</source>
+          <target>1.6</target>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-dependency-plugin</artifactId>
+        <version>2.4</version>
+        <executions>
+          <execution>
+            <id>unpack</id>
+            <phase>process-classes</phase>
+            <goals>
+              <goal>unpack</goal>
+            </goals>
+            <configuration>
+              <artifactItems>
+                <artifactItem>
+                  <groupId>de.ugoe.cs.quest</groupId>
+                  <artifactId>quest-misc</artifactId>
+                  <version>0.0.1-SNAPSHOT</version>
+                  <outputDirectory>${project.build.directory}/classes</outputDirectory>
+                </artifactItem>
+              </artifactItems>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>emma-maven-plugin</artifactId>
+        <version>1.0-alpha-3</version>
+        <inherited>true</inherited>          
+        <executions>
+          <execution>
+            <phase>process-classes</phase>
+            <goals>
+              <goal>emma</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <version>2.3.2</version>
+        <executions>
+          <execution>
+            <goals>
+              <goal>test-jar</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>
Index: /tags/quest-pre-eventrefactoring/quest-misc-test/src/test/java/de/ugoe/cs/tasktree/keyboardmaps/KeyboardMapTest.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc-test/src/test/java/de/ugoe/cs/tasktree/keyboardmaps/KeyboardMapTest.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc-test/src/test/java/de/ugoe/cs/tasktree/keyboardmaps/KeyboardMapTest.java	(revision 540)
@@ -0,0 +1,456 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: KeyboardMapTest.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 11.07.2012 $
+// Project   : KeyboardMaps
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.tasktree.keyboardmaps;
+
+import static org.junit.Assert.*;
+
+import java.util.Locale;
+
+import org.junit.Before;
+import org.junit.Test;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 11.07.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public class KeyboardMapTest
+{
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Before
+  public void setUp()
+  {
+    //Logger.getLogger("").getHandlers()[0].setFormatter(new SimpleLogFormatter());
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Test
+  public void testInitialization()
+  {
+    KeyboardMap map = KeyboardMapFactory.createKeyboardMap(Locale.ENGLISH);
+    assertNotNull(map);
+    
+    map = KeyboardMapFactory.createKeyboardMap(Locale.FRENCH);
+    assertNotNull(map);
+    
+    map = KeyboardMapFactory.createKeyboardMap(Locale.GERMAN);
+    assertNotNull(map);
+    
+    map = KeyboardMapFactory.createKeyboardMap(Locale.ITALIAN);
+    assertNotNull(map);
+    
+    map = KeyboardMapFactory.createKeyboardMap(Locale.JAPANESE);
+    assertNotNull(map);
+    
+    map = KeyboardMapFactory.createKeyboardMap(Locale.KOREAN);
+    assertNotNull(map);
+    
+    try
+    {
+      map = KeyboardMapFactory.createKeyboardMap(Locale.CHINESE);
+      fail("expected exception did not occur");
+    }
+    catch (IllegalArgumentException e)
+    {
+      // was expected and is ignored
+    }
+    
+    try
+    {
+      map = KeyboardMapFactory.createKeyboardMap(Locale.SIMPLIFIED_CHINESE);
+      fail("expected exception did not occur");
+    }
+    catch (IllegalArgumentException e)
+    {
+      // was expected and is ignored
+    }
+    
+    try
+    {
+      map = KeyboardMapFactory.createKeyboardMap(Locale.TRADITIONAL_CHINESE);
+      fail("expected exception did not occur");
+    }
+    catch (IllegalArgumentException e)
+    {
+      // was expected and is ignored
+    }
+    
+    map = KeyboardMapFactory.createKeyboardMap(Locale.FRANCE);
+    assertNotNull(map);
+    
+    map = KeyboardMapFactory.createKeyboardMap(Locale.GERMANY);
+    assertNotNull(map);
+    
+    map = KeyboardMapFactory.createKeyboardMap(Locale.ITALY);
+    assertNotNull(map);
+    
+    map = KeyboardMapFactory.createKeyboardMap(Locale.JAPAN);
+    assertNotNull(map);
+    
+    map = KeyboardMapFactory.createKeyboardMap(Locale.KOREA);
+    assertNotNull(map);
+    
+    try
+    {
+      map = KeyboardMapFactory.createKeyboardMap(Locale.CHINA);
+      fail("expected exception did not occur");
+    }
+    catch (IllegalArgumentException e)
+    {
+      // was expected and is ignored
+    }
+    
+    try
+    {
+      map = KeyboardMapFactory.createKeyboardMap(Locale.PRC);
+      fail("expected exception did not occur");
+    }
+    catch (IllegalArgumentException e)
+    {
+      // was expected and is ignored
+    }
+    
+    try
+    {
+      map = KeyboardMapFactory.createKeyboardMap(Locale.TAIWAN);
+      fail("expected exception did not occur");
+    }
+    catch (IllegalArgumentException e)
+    {
+      // was expected and is ignored
+    }
+    
+    map = KeyboardMapFactory.createKeyboardMap(Locale.UK);
+    assertNotNull(map);
+    
+    map = KeyboardMapFactory.createKeyboardMap(Locale.US);
+    assertNotNull(map);
+    
+    map = KeyboardMapFactory.createKeyboardMap(Locale.CANADA);
+    assertNotNull(map);
+    
+    map = KeyboardMapFactory.createKeyboardMap(Locale.CANADA_FRENCH);
+    assertNotNull(map);
+
+    map = KeyboardMapFactory.createKeyboardMap(Locale.GERMAN);
+    assertNotNull(map);
+    
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Test
+  public void testGermanKeyboardMap()
+  {
+    KeyboardMap map = KeyboardMapFactory.createKeyboardMap(Locale.GERMAN);
+    assertNotNull(map);
+    
+    assertCombinations(map, VirtualKey.DIGIT_1, '1', '!', '¹', '¡', true);
+    assertCombinations(map, VirtualKey.EXCLAMATION_MARK, '1', '!', '¹', '¡', true);
+    assertCombinations(map, VirtualKey.INVERTED_EXCLAMATION_MARK, '1', '!', '¹', '¡', true);
+    
+    assertCombinations(map, VirtualKey.DIGIT_2, '2', '"', '²', '⅛', true);
+    assertCombinations(map, VirtualKey.QUOTEDBL, '2', '"', '²', '⅛', true);
+
+    assertCombinations(map, VirtualKey.DIGIT_3, '3', '§', '³', '£', true);
+
+    assertCombinations(map, VirtualKey.DIGIT_4, '4', '$', '¼', '¤', true);
+    assertCombinations(map, VirtualKey.DOLLAR, '4', '$', '¼', '¤', true);
+
+    assertCombinations(map, VirtualKey.DIGIT_5, '5', '%', '½', '⅜', true);
+
+    assertCombinations(map, VirtualKey.DIGIT_6, '6', '&', '¾', '⅝', true);
+    assertCombinations(map, VirtualKey.AMPERSAND, '6', '&', '¾', '⅝', true);
+
+    assertCombinations(map, VirtualKey.DIGIT_7, '7', '/', '{', '⅞', true);
+    assertCombinations(map, VirtualKey.SLASH, '7', '/', '{', '⅞', true);
+    assertCombinations(map, VirtualKey.BRACELEFT, '7', '/', '{', '⅞', true);
+
+    assertCombinations(map, VirtualKey.DIGIT_8, '8', '(', '[', '™', true);
+    assertCombinations(map, VirtualKey.LEFT_PARENTHESIS, '8', '(', '[', '™', true);
+    assertCombinations(map, VirtualKey.OPEN_BRACKET, '8', '(', '[', '™', true);
+
+    assertCombinations(map, VirtualKey.DIGIT_9, '9', ')', ']', '±', true);
+    assertCombinations(map, VirtualKey.RIGHT_PARENTHESIS, '9', ')', ']', '±', true);
+    assertCombinations(map, VirtualKey.CLOSE_BRACKET, '9', ')', ']', '±', true);
+
+    assertCombinations(map, VirtualKey.DIGIT_0, '0', '=', '}', 0, true);
+    assertCombinations(map, VirtualKey.EQUALS, '0', '=', '}', 0, true);
+    assertCombinations(map, VirtualKey.BRACERIGHT, '0', '=', '}', 0, true);
+
+    assertCombinations(map, VirtualKey.BACK_SLASH, 'ß', '?', '\\', '¿', true);
+
+    assertCombinations(map, VirtualKey.LETTER_Q, 'q', 'Q', '@', 'Ω', true);
+    assertCombinations(map, VirtualKey.AT, 'q', 'Q', '@', 'Ω', true);
+
+    assertCombinations(map, VirtualKey.LETTER_W, 'w', 'W', 0, 0, true);
+
+    assertCombinations(map, VirtualKey.LETTER_E, 'e', 'E', '€', 0, true);
+    assertCombinations(map, VirtualKey.EURO_SIGN, 'e', 'E', '€', 0, true);
+
+    assertCombinations(map, VirtualKey.LETTER_R, 'r', 'R', 0, '®', true);
+
+    assertCombinations(map, VirtualKey.LETTER_T, 't', 'T', 'ŧ', 'Ŧ', true);
+
+    assertCombinations(map, VirtualKey.LETTER_Z, 'z', 'Z', '←', '¥', true);
+
+    assertCombinations(map, VirtualKey.LETTER_U, 'u', 'U', '↓', '↑', true);
+
+    assertCombinations(map, VirtualKey.LETTER_I, 'i', 'I', '→', 'ı', true);
+
+    assertCombinations(map, VirtualKey.LETTER_O, 'o', 'O', 'ø', 'Ø', true);
+
+    assertCombinations(map, VirtualKey.LETTER_P, 'p', 'P', 'þ', 'Þ', true);
+
+    assertCombinations(map, VirtualKey.LETTER_A, 'a', 'A', 'æ', 'Æ', true);
+
+    assertCombinations(map, VirtualKey.LETTER_S, 's', 'S', 0, 0, true);
+
+    assertCombinations(map, VirtualKey.LETTER_D, 'd', 'D', 'ð', 'Ð', true);
+
+    assertCombinations(map, VirtualKey.LETTER_F, 'f', 'F', 'đ', 'ª', true);
+
+    assertCombinations(map, VirtualKey.LETTER_G, 'g', 'G', 'ŋ', 'Ŋ', true);
+
+    assertCombinations(map, VirtualKey.LETTER_H, 'h', 'H', 'ħ', 'Ħ', true);
+
+    assertCombinations(map, VirtualKey.LETTER_J, 'j', 'J', 0, 0, true);
+
+    assertCombinations(map, VirtualKey.LETTER_K, 'k', 'K', 'ĸ', 0, true);
+
+    assertCombinations(map, VirtualKey.LETTER_L, 'l', 'L', 0, 0, true);
+
+    assertCombinations(map, VirtualKey.LETTER_Y, 'y', 'Y', '»', 0, true);
+
+    assertCombinations(map, VirtualKey.LETTER_X, 'x', 'X', '«', 0, true);
+
+    assertCombinations(map, VirtualKey.LETTER_C, 'c', 'C', '¢', '©', true);
+
+    assertCombinations(map, VirtualKey.LETTER_V, 'v', 'V', '„', 0, true);
+
+    assertCombinations(map, VirtualKey.LETTER_B, 'b', 'B', '“', 0, true);
+
+    assertCombinations(map, VirtualKey.LETTER_N, 'n', 'N', 0, 0, true);
+
+    assertCombinations(map, VirtualKey.LETTER_M, 'm', 'M', 'µ', 'º', true);
+
+    assertCombinations(map, VirtualKey.NUMPAD_0, '0', 0, 0, 0, false);
+
+    assertCombinations(map, VirtualKey.NUMPAD_1, '1', 0, 0, 0, false);
+
+    assertCombinations(map, VirtualKey.NUMPAD_2, '2', 0, 0, 0, false);
+
+    assertCombinations(map, VirtualKey.NUMPAD_3, '3', 0, 0, 0, false);
+
+    assertCombinations(map, VirtualKey.NUMPAD_4, '4', 0, 0, 0, false);
+
+    assertCombinations(map, VirtualKey.NUMPAD_5, '5', 0, 0, 0, false);
+
+    assertCombinations(map, VirtualKey.NUMPAD_6, '6', 0, 0, 0, false);
+
+    assertCombinations(map, VirtualKey.NUMPAD_7, '7', 0, 0, 0, false);
+
+    assertCombinations(map, VirtualKey.NUMPAD_8, '8', 0, 0, 0, false);
+
+    assertCombinations(map, VirtualKey.NUMPAD_9, '9', 0, 0, 0, false);
+
+    assertCombinations(map, VirtualKey.SEPARATOR, ',', 0, 0, 0, false);
+    assertCombinations(map, VirtualKey.DECIMAL, ',', 0, 0, 0, false);
+
+    assertCombinations(map, VirtualKey.CIRCUMFLEX, '^', '°', '¬', 0, true);
+
+    assertCombinations(map, VirtualKey.TAB, '\t', 0, '\t', 0, true);
+
+    assertCombinations(map, VirtualKey.SPACE, ' ', ' ', ' ', ' ', true);
+
+    assertCombinations(map, VirtualKey.COMMA, ',', ';', '·', '×', true);
+    assertCombinations(map, VirtualKey.SEMICOLON, ',', ';', '·', '×', true);
+    assertCombinations(map, VirtualKey.MULTIPLY, ',', ';', '·', '×', true);
+
+    assertCombinations(map, VirtualKey.MINUS, '-', '_', 0, 0, true);
+    assertCombinations(map, VirtualKey.UNDERSCORE, '-', '_', 0, 0, true);
+
+    assertCombinations(map, VirtualKey.PERIOD, '.', ':', '…', '÷', true);
+    assertCombinations(map, VirtualKey.COLON, '.', ':', '…', '÷', true);
+    assertCombinations(map, VirtualKey.DIVIDE, '.', ':', '…', '÷', true);
+
+    assertCombinations(map, VirtualKey.PLUS, '+', '*', '~', 0, true);
+    assertCombinations(map, VirtualKey.ASTERISK, '+', '*', '~', 0, true);
+    assertCombinations(map, VirtualKey.DEAD_TILDE, '+', '*', '~', 0, true);
+
+    assertCombinations(map, VirtualKey.LESS, '<', '>', '|', '¦', true);
+    assertCombinations(map, VirtualKey.GREATER, '<', '>', '|', '¦', true);
+
+    assertCombinations(map, VirtualKey.NUMBER_SIGN, '#', '\'', 0, 0, true);
+
+    /*DEAD_GRAVE(KeyEvent.VK_DEAD_GRAVE),
+    DEAD_ACUTE(KeyEvent.VK_DEAD_ACUTE),
+    DEAD_CIRCUMFLEX(KeyEvent.VK_DEAD_CIRCUMFLEX),
+    DEAD_TILDE(KeyEvent.VK_DEAD_TILDE),
+    DEAD_MACRON(KeyEvent.VK_DEAD_MACRON),
+    DEAD_BREVE(KeyEvent.VK_DEAD_BREVE),
+    DEAD_ABOVEDOT(KeyEvent.VK_DEAD_ABOVEDOT),
+    DEAD_DIAERESIS(KeyEvent.VK_DEAD_DIAERESIS),
+    DEAD_ABOVERING(KeyEvent.VK_DEAD_ABOVERING),
+    DEAD_DOUBLEACUTE(KeyEvent.VK_DEAD_DOUBLEACUTE),
+    DEAD_CARON(KeyEvent.VK_DEAD_CARON),
+    DEAD_CEDILLA(KeyEvent.VK_DEAD_CEDILLA),
+    DEAD_OGONEK(KeyEvent.VK_DEAD_OGONEK),
+    DEAD_IOTA(KeyEvent.VK_DEAD_IOTA),
+    DEAD_VOICED_SOUND(KeyEvent.VK_DEAD_VOICED_SOUND),
+    DEAD_SEMIVOICED_SOUND(KeyEvent.VK_DEAD_SEMIVOICED_SOUND),*/
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  private void assertCombinations(KeyboardMap map,
+                                  VirtualKey  key,
+                                  int         normal,
+                                  int         withShift,
+                                  int         withAltGr,
+                                  int         withShiftAndAltGr,
+                                  boolean     numLockIndependent)
+  {
+    if (numLockIndependent)
+    {
+      if (normal != 0)
+      {
+        assertCombination("normal", normal, map, key, false, false, false);
+      }
+    
+      if (withShift != 0)
+      {
+        assertCombination("shift", withShift, map, key, false, true, false);
+      }
+    
+      if (withAltGr != 0)
+      {
+        assertCombination("altgr", withAltGr, map, key, false, false, true);
+      }
+    
+      if (withShiftAndAltGr != 0)
+      {
+        assertCombination("shift and altgr", withShiftAndAltGr, map, key, false, true, true);
+      }
+    }
+    else
+    {
+      assertInvalidCombination("normal", normal, map, key, false, false, false);
+      assertInvalidCombination("shift", withShift, map, key, false, true, false);
+      assertInvalidCombination("altgr", withAltGr, map, key, false, false, true);
+      assertInvalidCombination("shift and altgr", withShiftAndAltGr, map, key, false, true, true);
+    }
+
+    if (normal != 0)
+    {
+      assertCombination("numlock", normal, map, key, true, false, false);
+    }
+      
+    if (withShift != 0)
+    {
+      assertCombination("numlock and shift", withShift, map, key, true, true, false);
+    }
+      
+    if (withAltGr != 0)
+    {
+      assertCombination("numlock and altgr", withAltGr, map, key, true, false, true);
+    }
+      
+    if (withShiftAndAltGr != 0)
+    {
+      assertCombination
+        ("numlock, shift and altgr", withShiftAndAltGr, map, key, true, true, true);
+    }
+  }
+  
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param string
+   * @param normal
+   * @param characterFor
+   */
+  //-----------------------------------------------------------------------------------------------
+  private void assertCombination(String      type,
+                                 int         expectedChar,
+                                 KeyboardMap map,
+                                 VirtualKey  key,
+                                 boolean     numlock,
+                                 boolean     shift,
+                                 boolean     altgr)
+  {
+    String message = "checked for " + type + ": expected '" + ((char) expectedChar) + "'";
+
+    char retrievedChar;
+    try
+    {
+      retrievedChar = map.getCharacterFor(key, numlock, shift, altgr, false);
+    }
+    catch (IllegalArgumentException e)
+    {
+      fail("no character found. " + message);
+      return;
+    }
+    
+    message += " but got '" + retrievedChar + "'";
+    
+    assertEquals(message, expectedChar, retrievedChar);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param string
+   * @param normal
+   * @param characterFor
+   */
+  //-----------------------------------------------------------------------------------------------
+  private void assertInvalidCombination(String      type,
+                                        int         expectedChar,
+                                        KeyboardMap map,
+                                        VirtualKey  key,
+                                        boolean     numlock,
+                                        boolean     shift,
+                                        boolean     altgr)
+  {
+    char retrievedChar;
+    try
+    {
+      retrievedChar = map.getCharacterFor(key, numlock, shift, altgr, false);
+      assertEquals(Character.UNASSIGNED, retrievedChar);
+    }
+    catch (IllegalArgumentException e)
+    {
+      // this is ok and checked for
+    }
+    
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-misc/.classpath
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/.classpath	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/.classpath	(revision 540)
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src/main/java"/>
+	<classpathentry kind="src" path="src/main/resources"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
Index: /tags/quest-pre-eventrefactoring/quest-misc/.project
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/.project	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/.project	(revision 540)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>quest-misc</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
Index: /tags/quest-pre-eventrefactoring/quest-misc/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/.settings/org.eclipse.jdt.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/.settings/org.eclipse.jdt.core.prefs	(revision 540)
@@ -0,0 +1,5 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.6
Index: /tags/quest-pre-eventrefactoring/quest-misc/.settings/org.eclipse.m2e.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/.settings/org.eclipse.m2e.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/.settings/org.eclipse.m2e.core.prefs	(revision 540)
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
Index: /tags/quest-pre-eventrefactoring/quest-misc/pom.xml
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/pom.xml	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/pom.xml	(revision 540)
@@ -0,0 +1,36 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>de.ugoe.cs.quest</groupId>
+  <artifactId>quest-misc</artifactId>
+  <version>0.0.1-SNAPSHOT</version>
+  <name>quest-misc</name>
+  <scm>
+    <url>https://www.trex.informatik.uni-goettingen.de/svn/swephd/pharms/tasktree/trunk/quest-misc</url>
+  </scm>
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.8.1</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+  <distributionManagement>
+    <snapshotRepository>
+      <id>quest-snapshots</id>
+      <url>https://trex.informatik.uni-goettingen.de/nexus/content/repositories/quest-snapshots</url>
+    </snapshotRepository>
+  </distributionManagement>
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>2.5.1</version>
+        <configuration>
+          <source>1.6</source>
+          <target>1.6</target>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
Index: /tags/quest-pre-eventrefactoring/quest-misc/src/main/java/de/ugoe/cs/tasktree/keyboardmaps/KeyStroke.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/src/main/java/de/ugoe/cs/tasktree/keyboardmaps/KeyStroke.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/src/main/java/de/ugoe/cs/tasktree/keyboardmaps/KeyStroke.java	(revision 540)
@@ -0,0 +1,222 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: KeyStroke.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 11.07.2012 $
+// Project   : KeyboardMaps
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.tasktree.keyboardmaps;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 11.07.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public class KeyStroke
+{
+
+  /** */
+  private String mKeyStrokeName;
+
+  /** */
+  private VirtualKey mVirtualKey;
+
+  /** */
+  private boolean mNumlock;
+
+  /** */
+  private boolean mLocalstate;
+
+  /** */
+  private boolean mShift;
+
+  /** */
+  private boolean mAltgr;
+
+  /** */
+  private boolean mInhibit;
+
+  /** */
+  private char mCharacter;
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param keyStrokeName
+   * @param mapKeyIdToVirtualKey
+   * @param numlock
+   * @param localstate
+   * @param b
+   * @param altgr
+   * @param inhibit
+   */
+  //-----------------------------------------------------------------------------------------------
+  public KeyStroke(String     keyStrokeName,
+                   VirtualKey virtualKey,
+                   boolean    numlock,
+                   boolean    localstate,
+                   boolean    shift,
+                   boolean    altgr,
+                   boolean    inhibit,
+                   char       character)
+  {
+    mKeyStrokeName = keyStrokeName;
+    mVirtualKey = virtualKey;
+    mNumlock = numlock;
+    mLocalstate = localstate;
+    mShift = shift;
+    mAltgr = altgr;
+    mInhibit = inhibit;
+    mCharacter = character;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * @return the keyStrokeName
+   */
+  //-----------------------------------------------------------------------------------------------
+  public String getKeyStrokeName()
+  {
+    return mKeyStrokeName;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  public VirtualKey getVirtualKey()
+  {
+    return mVirtualKey;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  public char getCharacter()
+  {
+    return mCharacter;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  public boolean getInhibit()
+  {
+    return mInhibit;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  public boolean getAltgr()
+  {
+    return mAltgr;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  public boolean getShift()
+  {
+    return mShift;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  public boolean getLocalstate()
+  {
+    return mLocalstate;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  public boolean getNumlock()
+  {
+    return mNumlock;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /* (non-Javadoc)
+   * @see java.lang.Object#toString()
+   */
+  //-----------------------------------------------------------------------------------------------
+  @Override
+  public String toString()
+  {
+    StringBuffer toString = new StringBuffer();
+    toString.append("KeyStroke(");
+    toString.append(mKeyStrokeName);
+    toString.append(", ");
+    toString.append(mVirtualKey);
+    
+    if (mCharacter != Character.UNASSIGNED)
+    {
+      toString.append(", \'");
+      toString.append(mCharacter);
+      toString.append("\'");
+    }
+    
+    if (mShift)
+    {
+      toString.append(", shift");
+    }
+    
+    if (mAltgr)
+    {
+      toString.append(", altgr");
+    }
+    
+    if (mNumlock)
+    {
+      toString.append(", numlock");
+    }
+    
+    if (mLocalstate)
+    {
+      toString.append(", localstate");
+    }
+    
+    if (mInhibit)
+    {
+      toString.append(", inhibit");
+    }
+    
+    toString.append(")");
+
+    return toString.toString();
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-misc/src/main/java/de/ugoe/cs/tasktree/keyboardmaps/KeyboardMap.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/src/main/java/de/ugoe/cs/tasktree/keyboardmaps/KeyboardMap.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/src/main/java/de/ugoe/cs/tasktree/keyboardmaps/KeyboardMap.java	(revision 540)
@@ -0,0 +1,2920 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: KeyboardMap.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 11.07.2012 $
+// Project   : KeyboardMaps
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.tasktree.keyboardmaps;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 11.07.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public class KeyboardMap
+{
+  /** */
+  private static Logger LOG = Logger.getLogger(KeyboardMap.class.getName());
+
+  /** */
+  private Locale mLocale;
+
+  /** */
+  private String mFileName;
+
+  /** */
+  private Map<VirtualKey, List<KeyStroke>> mKeyStrokes = new HashMap<VirtualKey, List<KeyStroke>>();
+  
+  /** TODO: remove this stuff */
+  private List<Object[]> mKeyIds = new ArrayList<Object[]>();
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param locale
+   */
+  //-----------------------------------------------------------------------------------------------
+  KeyboardMap(Locale locale)
+  {
+    mLocale = locale;
+    
+    if ((mLocale == Locale.ENGLISH) || (mLocale == Locale.US) || (mLocale == Locale.CANADA))
+    {
+      mFileName = "en-us";
+    }
+    else if (mLocale == Locale.UK)
+    {
+      mFileName = "en-gb";
+    }
+    else
+    {
+      mFileName = locale.getLanguage();
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param digit1
+   * @param b
+   * @param c
+   * @param d
+   * @param e
+   * @param f
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  public char getCharacterFor(VirtualKey key,
+                              boolean    numlock,
+                              boolean    shift,
+                              boolean    altgr,
+                              boolean    inhibit)
+    throws IllegalArgumentException
+  {
+    List<KeyStroke> candidates = mKeyStrokes.get(key);
+    
+    if (candidates == null)
+    {
+      return Character.UNASSIGNED;
+    }
+    
+    // try to find the key stroke 
+    for (KeyStroke keyStroke : candidates)
+    {
+      if ((numlock == keyStroke.getNumlock()) &&
+          (!keyStroke.getLocalstate()) &&
+          (shift == keyStroke.getShift()) &&
+          (altgr == keyStroke.getAltgr()) &&
+          (inhibit == keyStroke.getInhibit()))
+      {
+        return keyStroke.getCharacter();
+      }
+    }
+    
+    // try to find the key stroke with a local state ignoring the other keys
+    for (KeyStroke keyStroke : candidates)
+    {
+      if ((numlock == keyStroke.getNumlock()) &&
+          (keyStroke.getLocalstate()) &&
+          (inhibit == keyStroke.getInhibit()))
+      {
+        return keyStroke.getCharacter();
+      }
+    }
+    
+    return Character.UNASSIGNED;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  void init() throws IllegalArgumentException
+  {
+    LOG.info("initializing keymap for locale " + mLocale);
+
+    List<String[]> deadKeySequences = new ArrayList<String[]>();
+    List<String[]> keyStrokes = new ArrayList<String[]>();
+    readStream(getStream(mFileName), deadKeySequences, keyStrokes);
+    
+    LOG.info("read " + keyStrokes.size() + " key strokes and " + deadKeySequences.size() +
+             " dead key sequences");
+
+    VirtualKeySynonyms virtualKeySynonyms = determineVirtualKeySynonyms(keyStrokes);
+    processKeyStrokes(keyStrokes, virtualKeySynonyms);
+    processDeadKeySequences(deadKeySequences);
+    
+    for (Object[] keyId : mKeyIds)
+    {
+      System.out.println(Integer.toHexString((Integer) keyId[0]) + "  " + keyId[1]);
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param fileName
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  private InputStream getStream(String name)
+  {
+    LOG.info("reading keymap for locale " + mLocale + " from resource keymaps/" + name);
+
+    InputStream stream =
+      this.getClass().getClassLoader().getResourceAsStream("keymaps/" + name);
+      
+    if (stream == null)
+    {
+      throw new IllegalArgumentException("no keyboard map available for locale " + mLocale);
+    }
+    
+    return stream;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param stream
+   * @param virtualKeySynonyms 
+   * @param deadKeySequences 
+   */
+  //-----------------------------------------------------------------------------------------------
+  private void readStream(InputStream    stream,
+                          List<String[]> deadKeySequences,
+                          List<String[]> keyStrokes)
+    throws IllegalArgumentException
+  {
+    BufferedReader in = new BufferedReader(new InputStreamReader(stream));
+    
+    try
+    {
+      String line;
+      while ((line = in.readLine()) != null)
+      {
+        if (!"".equals(line))
+        {
+          processLine(line, deadKeySequences, keyStrokes);
+        }
+      }
+    }
+    catch (IOException e)
+    {
+      LOG.log(Level.WARNING, "no keyboard map available for locale " + mLocale, e);
+      throw new IllegalArgumentException("no keyboard map available for locale " + mLocale, e);
+    }
+    finally
+    {
+      try
+      {
+        in.close();
+      }
+      catch (IOException e)
+      {
+        LOG.warning("could not close input stream for reading keyboard map");
+      }
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param line
+   * @param deadKeySequences 
+   */
+  //-----------------------------------------------------------------------------------------------
+  private void processLine(String         line,
+                           List<String[]> deadKeySequences,
+                           List<String[]> keyStrokes)
+  {
+    String[] values = line.split(" ");
+    
+    if (values.length <= 0)
+    {
+      return;
+    }
+    
+    // ignore comments
+    if (values[0].startsWith("#"))
+    {
+      return;
+    }
+    
+    if ("map".equals(values[0]))
+    {
+      // this is the map id. Ignore it.
+    }
+    else if ("include".equals(values[0]))
+    {
+      // process all includes
+      for (int i = 1; i < values.length; i++)
+      {
+        if (!values[i].startsWith("#"))
+        {
+          readStream(getStream(values[i]), deadKeySequences, keyStrokes);
+        }
+        else
+        {
+          break;
+        }
+      }
+    }
+    else if ("sequence".equals(values[0]))
+    {
+      deadKeySequences.add(values);
+    }
+    else
+    {
+      boolean alreadyAdded = false;
+      
+      // check, if there is a replacement
+      for (int i = 0; i < keyStrokes.size(); i++)
+      {
+        if (keyStrokes.get(i)[0].equals(values[0]))
+        {
+          LOG.finest("replacing key stroke " + values[0] + " with former keyid " +
+                     keyStrokes.get(i)[1] + " with new key id " + values[1]);
+          keyStrokes.set(i, values);
+          alreadyAdded = true;
+          break;
+        }
+      }
+      
+      if (!alreadyAdded)
+      {
+        keyStrokes.add(values);
+      }
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param keyStrokes
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  private VirtualKeySynonyms determineVirtualKeySynonyms(List<String[]> keyStrokes)
+  {
+    LOG.info("determining virtual keys and synonyms for the keymap");
+
+    VirtualKeySynonyms virtualKeySynonyms = new VirtualKeySynonyms();
+    
+    // for debugging purposes, determine which key strokes are not matched to virtual keys.
+    List<String[]> unmatchedKeyStrokes = new ArrayList<String[]>();
+    
+    for (String[] keyStroke : keyStrokes)
+    {
+      String keyStrokeName = keyStroke[0];
+      int keyId = getKeyId(keyStroke[1]);
+      //System.err.println(keyStrokeName + "  0x" + Integer.toHexString(keyId));
+
+      VirtualKey virtualKey = determineVirtualKey(keyStrokeName);
+      
+      if (virtualKey != null)
+      {
+        virtualKeySynonyms.add(keyId, virtualKey);
+      }
+      else
+      {
+        unmatchedKeyStrokes.add(keyStroke);
+      }
+    }
+    
+    for (String[] unmatchedKeyStroke : unmatchedKeyStrokes)
+    {
+      if (!virtualKeySynonyms.containsKey(getKeyId(unmatchedKeyStroke[1])))
+      {
+        LOG.finest("no virtual key mapped to key stroke " + unmatchedKeyStroke[0] + "(" +
+                   unmatchedKeyStroke[1] + ") of keyboard map for locale " + mLocale);
+      }
+    }
+    
+    return virtualKeySynonyms;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param string
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  private int getKeyId(String keyIdString)
+  {
+    if (keyIdString.startsWith("0x"))
+    {
+      keyIdString = keyIdString.substring(2);
+    }
+  
+    return Integer.parseInt(keyIdString, 16);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param keyStrokes
+   * @param virtualKeySynonyms
+   */
+  //-----------------------------------------------------------------------------------------------
+  private void processKeyStrokes(List<String[]> keyStrokes, VirtualKeySynonyms virtualKeySynonyms)
+  {
+    for (String[] keyStroke : keyStrokes)
+    {
+      handleKeyStroke(keyStroke, virtualKeySynonyms);
+    }
+    
+    addKeyStrokesIndependentOfNumLock();
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param values
+   */
+  //-----------------------------------------------------------------------------------------------
+  private void handleKeyStroke(String[]           values,
+                               VirtualKeySynonyms virtualKeySynonyms)
+  {
+    String keyStrokeName = values[0];
+    String keyIdString = values[1];
+    if (keyIdString.startsWith("0x"))
+    {
+      keyIdString = keyIdString.substring(2);
+    }
+    
+    int keyId = Integer.parseInt(keyIdString, 16);
+    
+    // parse the conditions
+    boolean numlock = false;
+    boolean localstate = false;
+    boolean shift = false;
+    boolean altgr = false;
+    boolean addupper = false;
+    boolean inhibit = false;
+    
+    for (int i = 2; i < values.length; i++)
+    {
+      if (!values[i].startsWith("#"))
+      {
+        if ("numlock".equals(values[i]))
+        {
+          numlock = true;
+        }
+        else if ("localstate".equals(values[i]))
+        {
+          localstate = true;
+        }
+        else if ("shift".equals(values[i]))
+        {
+          shift = true;
+        }
+        else if ("altgr".equals(values[i]))
+        {
+          altgr = true;
+        }
+        else if ("addupper".equals(values[i]))
+        {
+          addupper = true;
+        }
+        else if ("inhibit".equals(values[i]))
+        {
+          inhibit = true;
+        }
+        else
+        {
+          LOG.severe("unknown condition " + values[i] + " specified for key stroke " +
+                     keyStrokeName + " through keyboard map for locale " + mLocale);
+          throw new IllegalArgumentException("no keyboard map available for locale " + mLocale);
+        }
+      }
+      else
+      {
+        break;
+      }
+    }
+    
+    addAllRepresentedKeyStrokes(keyStrokeName, keyId, numlock, localstate, shift, altgr, addupper,
+                                inhibit, virtualKeySynonyms);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param keyStrokeName
+   * @param keyId
+   * @param numlock
+   * @param localstate
+   * @param shift
+   * @param altgr
+   * @param addupper
+   * @param inhibit
+   */
+  //-----------------------------------------------------------------------------------------------
+  private void addAllRepresentedKeyStrokes(String             keyStrokeName,
+                                           int                keyId,
+                                           boolean            numlock,
+                                           boolean            localstate,
+                                           boolean            shift,
+                                           boolean            altgr,
+                                           boolean            addupper,
+                                           boolean            inhibit,
+                                           VirtualKeySynonyms virtualKeySynonyms)
+  {
+    VirtualKey[] virtualKeys = virtualKeySynonyms.getVirtualKeySynonyms(keyId);
+    
+    if (virtualKeys == null)
+    {
+      LOG.severe("no virtual key mapped to key stroke " + keyStrokeName +
+                 " of keyboard map for locale " + mLocale);
+      //throw new IllegalArgumentException("no keyboard map available for locale " + mLocale);
+      return;
+    }
+    
+    for (VirtualKey virtualKey : virtualKeys)
+    {
+      if (addupper)
+      {
+        char c = determineCharacter(keyStrokeName, true);
+        addKeyStroke(keyStrokeName, virtualKey, numlock, localstate, true, altgr, inhibit, c);
+      
+        c = determineCharacter(keyStrokeName, false);
+        addKeyStroke(keyStrokeName, virtualKey, numlock, localstate, false, altgr, inhibit, c);
+      }
+      else
+      {
+        char c = determineCharacter(keyStrokeName, false);
+        addKeyStroke(keyStrokeName, virtualKey, numlock, localstate, shift, altgr, inhibit, c);
+      }
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param keyStroke
+   */
+  //-----------------------------------------------------------------------------------------------
+  private void addKeyStroke(String     keyStrokeName,
+                            VirtualKey virtualKey,
+                            boolean    numlock,
+                            boolean    localstate,
+                            boolean    shift,
+                            boolean    altgr,
+                            boolean    inhibit,
+                            char       character)
+  {
+    KeyStroke keyStroke = new KeyStroke
+      (keyStrokeName, virtualKey, numlock, localstate, shift, altgr, inhibit, character);
+    
+    List<KeyStroke> keyStrokes = mKeyStrokes.get(keyStroke.getVirtualKey());
+    
+    if (keyStrokes == null)
+    {
+      keyStrokes = new ArrayList<KeyStroke>();
+      mKeyStrokes.put(keyStroke.getVirtualKey(), keyStrokes);
+    }
+    
+    keyStrokes.add(keyStroke);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  private void addKeyStrokesIndependentOfNumLock()
+  {
+    for (Map.Entry<VirtualKey, List<KeyStroke>> entry : mKeyStrokes.entrySet())
+    {
+      List<KeyStroke> keyStrokesToAdd = new ArrayList<KeyStroke>();
+      for (KeyStroke keyStroke : entry.getValue())
+      {
+        if (!keyStroke.getNumlock())
+        {
+          boolean foundPositiveNumlockVariant = false;
+          for (KeyStroke candidate : entry.getValue())
+          {
+            if ((candidate.getShift() == keyStroke.getShift()) &&
+                (candidate.getAltgr() == keyStroke.getAltgr()) &&
+                (candidate.getLocalstate() == keyStroke.getLocalstate()) &&
+                (candidate.getInhibit() == keyStroke.getInhibit()) &&
+                (candidate.getNumlock()))
+            {
+              foundPositiveNumlockVariant = true;
+              break;
+            }
+          }
+          
+          if (!foundPositiveNumlockVariant)
+          {
+            keyStrokesToAdd.add(keyStroke);
+          }
+        }
+      }
+      
+      for (KeyStroke keyStroke : keyStrokesToAdd)
+      {
+        addKeyStroke(keyStroke.getKeyStrokeName(), keyStroke.getVirtualKey(), true,
+                     keyStroke.getLocalstate(), keyStroke.getShift(), keyStroke.getAltgr(),
+                     keyStroke.getInhibit(), keyStroke.getCharacter());
+      }
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param deadKeySequences
+   */
+  //-----------------------------------------------------------------------------------------------
+  private void processDeadKeySequences(List<String[]> deadKeySequences)
+  {
+    // TODO Auto-generated method stub
+    //System.out.println("PATRICK: KeyboardMap.processDeadKeySequences ");
+    
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param keyStrokeName
+   * @param shift
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  private VirtualKey determineVirtualKey(String keyStrokeName)
+  {
+    if ("Shift_R".equals(keyStrokeName))
+    {
+      return VirtualKey.SHIFT;
+    }
+    else if ("Shift_L".equals(keyStrokeName))
+    {
+      return VirtualKey.SHIFT;
+    }
+    else if ("Alt_R".equals(keyStrokeName))
+    {
+      return VirtualKey.ALT_GRAPH;
+    }
+    else if ("Mode_switch".equals(keyStrokeName))
+    {
+      return VirtualKey.MODECHANGE;
+    }
+    else if ("ISO_Level3_Shift".equals(keyStrokeName))
+    {
+      return VirtualKey.SHIFT;
+    }
+    else if ("Alt_L".equals(keyStrokeName))
+    {
+      return VirtualKey.ALT;
+    }
+    else if ("Control_R".equals(keyStrokeName))
+    {
+      return VirtualKey.CONTROL;
+    }
+    else if ("Control_L".equals(keyStrokeName))
+    {
+      return VirtualKey.CONTROL;
+    }
+    else if ("Menu".equals(keyStrokeName))
+    {
+      return VirtualKey.WINDOWS;
+    }
+    else if ("1".equals(keyStrokeName))
+    {
+      return VirtualKey.DIGIT_1;
+    }
+    else if ("2".equals(keyStrokeName))
+    {
+      return VirtualKey.DIGIT_2;
+    }
+    else if ("3".equals(keyStrokeName))
+    {
+      return VirtualKey.DIGIT_3;
+    }
+    else if ("4".equals(keyStrokeName))
+    {
+      return VirtualKey.DIGIT_4;
+    }
+    else if ("5".equals(keyStrokeName))
+    {
+      return VirtualKey.DIGIT_5;
+    }
+    else if ("6".equals(keyStrokeName))
+    {
+      return VirtualKey.DIGIT_6;
+    }
+    else if ("7".equals(keyStrokeName))
+    {
+      return VirtualKey.DIGIT_7;
+    }
+    else if ("8".equals(keyStrokeName))
+    {
+      return VirtualKey.DIGIT_8;
+    }
+    else if ("9".equals(keyStrokeName))
+    {
+      return VirtualKey.DIGIT_9;
+    }
+    else if ("0".equals(keyStrokeName))
+    {
+      return VirtualKey.DIGIT_0;
+    }
+    else if ("BackSpace".equals(keyStrokeName))
+    {
+      return VirtualKey.BACK_SPACE;
+    }
+    else if ("Tab".equals(keyStrokeName))
+    {
+      return VirtualKey.TAB;
+    }
+    else if ("q".equals(keyStrokeName))
+    {
+      return VirtualKey.LETTER_Q;
+    }
+    else if ("w".equals(keyStrokeName))
+    {
+      return VirtualKey.LETTER_W;
+    }
+    else if ("e".equals(keyStrokeName))
+    {
+      return VirtualKey.LETTER_E;
+    }
+    else if ("r".equals(keyStrokeName))
+    {
+      return VirtualKey.LETTER_R;
+    }
+    else if ("t".equals(keyStrokeName))
+    {
+      return VirtualKey.LETTER_T;
+    }
+    else if ("y".equals(keyStrokeName))
+    {
+      return VirtualKey.LETTER_Y;
+    }
+    else if ("u".equals(keyStrokeName))
+    {
+      return VirtualKey.LETTER_U;
+    }
+    else if ("i".equals(keyStrokeName))
+    {
+      return VirtualKey.LETTER_I;
+    }
+    else if ("o".equals(keyStrokeName))
+    {
+      return VirtualKey.LETTER_O;
+    }
+    else if ("p".equals(keyStrokeName))
+    {
+      return VirtualKey.LETTER_P;
+    }
+    else if ("a".equals(keyStrokeName))
+    {
+      return VirtualKey.LETTER_A;
+    }
+    else if ("s".equals(keyStrokeName))
+    {
+      return VirtualKey.LETTER_S;
+    }
+    else if ("d".equals(keyStrokeName))
+    {
+      return VirtualKey.LETTER_D;
+    }
+    else if ("f".equals(keyStrokeName))
+    {
+      return VirtualKey.LETTER_F;
+    }
+    else if ("g".equals(keyStrokeName))
+    {
+      return VirtualKey.LETTER_G;
+    }
+    else if ("h".equals(keyStrokeName))
+    {
+      return VirtualKey.LETTER_H;
+    }
+    else if ("j".equals(keyStrokeName))
+    {
+      return VirtualKey.LETTER_J;
+    }
+    else if ("k".equals(keyStrokeName))
+    {
+      return VirtualKey.LETTER_K;
+    }
+    else if ("l".equals(keyStrokeName))
+    {
+      return VirtualKey.LETTER_L;
+    }
+    else if ("Return".equals(keyStrokeName))
+    {
+      return VirtualKey.ENTER;
+    }
+    else if ("z".equals(keyStrokeName))
+    {
+      return VirtualKey.LETTER_Z;
+    }
+    else if ("x".equals(keyStrokeName))
+    {
+      return VirtualKey.LETTER_X;
+    }
+    else if ("c".equals(keyStrokeName))
+    {
+      return VirtualKey.LETTER_C;
+    }
+    else if ("v".equals(keyStrokeName))
+    {
+      return VirtualKey.LETTER_V;
+    }
+    else if ("b".equals(keyStrokeName))
+    {
+      return VirtualKey.LETTER_B;
+    }
+    else if ("n".equals(keyStrokeName))
+    {
+      return VirtualKey.LETTER_N;
+    }
+    else if ("m".equals(keyStrokeName))
+    {
+      return VirtualKey.LETTER_M;
+    }
+    else if ("space".equals(keyStrokeName))
+    {
+      return VirtualKey.SPACE;
+    }
+    else if ("less".equals(keyStrokeName))
+    {
+      return VirtualKey.LESS;
+    }
+    else if ("greater".equals(keyStrokeName))
+    {
+      return VirtualKey.GREATER;
+    }
+    else if ("Escape".equals(keyStrokeName))
+    {
+      return VirtualKey.ESCAPE;
+    }
+    else if ("F1".equals(keyStrokeName))
+    {
+      return VirtualKey.F1;
+    }
+    else if ("F2".equals(keyStrokeName))
+    {
+      return VirtualKey.F2;
+    }
+    else if ("F3".equals(keyStrokeName))
+    {
+      return VirtualKey.F3;
+    }
+    else if ("F4".equals(keyStrokeName))
+    {
+      return VirtualKey.F4;
+    }
+    else if ("F5".equals(keyStrokeName))
+    {
+      return VirtualKey.F5;
+    }
+    else if ("F6".equals(keyStrokeName))
+    {
+      return VirtualKey.F6;
+    }
+    else if ("F7".equals(keyStrokeName))
+    {
+      return VirtualKey.F7;
+    }
+    else if ("F8".equals(keyStrokeName))
+    {
+      return VirtualKey.F8;
+    }
+    else if ("F9".equals(keyStrokeName))
+    {
+      return VirtualKey.F9;
+    }
+    else if ("F10".equals(keyStrokeName))
+    {
+      return VirtualKey.F10;
+    }
+    else if ("F11".equals(keyStrokeName))
+    {
+      return VirtualKey.F11;
+    }
+    else if ("F12".equals(keyStrokeName))
+    {
+      return VirtualKey.F12;
+    }
+    else if ("F13".equals(keyStrokeName))
+    {
+      return VirtualKey.F13;
+    }
+    else if ("F14".equals(keyStrokeName))
+    {
+      return VirtualKey.F14;
+    }
+    else if ("F15".equals(keyStrokeName))
+    {
+      return VirtualKey.F15;
+    }
+    else if ("F16".equals(keyStrokeName))
+    {
+      return VirtualKey.F16;
+    }
+    else if ("F17".equals(keyStrokeName))
+    {
+      return VirtualKey.F17;
+    }
+    else if ("F18".equals(keyStrokeName))
+    {
+      return VirtualKey.F18;
+    }
+    else if ("F19".equals(keyStrokeName))
+    {
+      return VirtualKey.F19;
+    }
+    else if ("F20".equals(keyStrokeName))
+    {
+      return VirtualKey.F20;
+    }
+    else if ("F21".equals(keyStrokeName))
+    {
+      return VirtualKey.F21;
+    }
+    else if ("F22".equals(keyStrokeName))
+    {
+      return VirtualKey.F22;
+    }
+    else if ("F23".equals(keyStrokeName))
+    {
+      return VirtualKey.F23;
+    }
+    else if ("F24".equals(keyStrokeName))
+    {
+      return VirtualKey.F24;
+    }
+    else if ("Print".equals(keyStrokeName))
+    {
+      return VirtualKey.PRINTSCREEN;
+    }
+    else if ("Scroll_Lock".equals(keyStrokeName))
+    {
+      return VirtualKey.SCROLL_LOCK;
+    }
+    else if ("Insert".equals(keyStrokeName))
+    {
+      return VirtualKey.INSERT;
+    }
+    else if ("Delete".equals(keyStrokeName))
+    {
+      return VirtualKey.DELETE;
+    }
+    else if ("Home".equals(keyStrokeName))
+    {
+      return VirtualKey.HOME;
+    }
+    else if ("End".equals(keyStrokeName))
+    {
+      return VirtualKey.END;
+    }
+    else if ("Page_Up".equals(keyStrokeName))
+    {
+      return VirtualKey.PAGE_UP;
+    }
+    else if ("Page_Down".equals(keyStrokeName))
+    {
+      return VirtualKey.PAGE_DOWN;
+    }
+    else if ("Left".equals(keyStrokeName))
+    {
+      return VirtualKey.LEFT;
+    }
+    else if ("Up".equals(keyStrokeName))
+    {
+      return VirtualKey.UP;
+    }
+    else if ("Down".equals(keyStrokeName))
+    {
+      return VirtualKey.DOWN;
+    }
+    else if ("Right".equals(keyStrokeName))
+    {
+      return VirtualKey.RIGHT;
+    }
+    else if ("Num_Lock".equals(keyStrokeName))
+    {
+      return VirtualKey.NUM_LOCK;
+    }
+    else if ("KP_Divide".equals(keyStrokeName))
+    {
+      return VirtualKey.SLASH;
+    }
+    else if ("KP_Multiply".equals(keyStrokeName))
+    {
+      return VirtualKey.ASTERISK;
+    }
+    else if ("KP_Subtract".equals(keyStrokeName))
+    {
+      return VirtualKey.MINUS;
+    }
+    else if ("KP_Add".equals(keyStrokeName))
+    {
+      return VirtualKey.PLUS;
+    }
+    else if ("KP_Enter".equals(keyStrokeName))
+    {
+      return VirtualKey.ENTER;
+    }
+    else if ("KP_Decimal".equals(keyStrokeName))
+    {
+      return VirtualKey.DECIMAL;
+    }
+    else if ("KP_Separator".equals(keyStrokeName))
+    {
+      return VirtualKey.SEPARATOR;
+    }
+    else if ("KP_Delete".equals(keyStrokeName))
+    {
+      return VirtualKey.DELETE;
+    }
+    else if ("KP_0".equals(keyStrokeName))
+    {
+      return VirtualKey.NUMPAD_0;
+    }
+    else if ("KP_Insert".equals(keyStrokeName))
+    {
+      return VirtualKey.INSERT;
+    }
+    else if ("KP_1".equals(keyStrokeName))
+    {
+      return VirtualKey.NUMPAD_1;
+    }
+    else if ("KP_End".equals(keyStrokeName))
+    {
+      return VirtualKey.END;
+    }
+    else if ("KP_2".equals(keyStrokeName))
+    {
+      return VirtualKey.NUMPAD_2;
+    }
+    else if ("KP_Down".equals(keyStrokeName))
+    {
+      return VirtualKey.KP_DOWN;
+    }
+    else if ("KP_3".equals(keyStrokeName))
+    {
+      return VirtualKey.NUMPAD_3;
+    }
+    else if ("KP_Next".equals(keyStrokeName))
+    {
+      return VirtualKey.PAGE_DOWN;
+    }
+    else if ("KP_4".equals(keyStrokeName))
+    {
+      return VirtualKey.NUMPAD_4;
+    }
+    else if ("KP_Left".equals(keyStrokeName))
+    {
+      return VirtualKey.KP_LEFT;
+    }
+    else if ("KP_5".equals(keyStrokeName))
+    {
+      return VirtualKey.NUMPAD_5;
+    }
+    else if ("KP_Begin".equals(keyStrokeName))
+    {
+      return VirtualKey.BEGIN;
+    }
+    else if ("KP_6".equals(keyStrokeName))
+    {
+      return VirtualKey.NUMPAD_6;
+    }
+    else if ("KP_Right".equals(keyStrokeName))
+    {
+      return VirtualKey.KP_RIGHT;
+    }
+    else if ("KP_7".equals(keyStrokeName))
+    {
+      return VirtualKey.NUMPAD_7;
+    }
+    else if ("KP_Home".equals(keyStrokeName))
+    {
+      return VirtualKey.HOME;
+    }
+    else if ("KP_8".equals(keyStrokeName))
+    {
+      return VirtualKey.NUMPAD_8;
+    }
+    else if ("KP_Up".equals(keyStrokeName))
+    {
+      return VirtualKey.KP_UP;
+    }
+    else if ("KP_9".equals(keyStrokeName))
+    {
+      return VirtualKey.NUMPAD_9;
+    }
+    else if ("KP_Prior".equals(keyStrokeName))
+    {
+      return VirtualKey.PAGE_UP;
+    }
+    else if ("Caps_Lock".equals(keyStrokeName))
+    {
+      return VirtualKey.CAPS_LOCK;
+    }
+    else if ("exclam".equals(keyStrokeName))
+    {
+      return VirtualKey.EXCLAMATION_MARK;
+    }
+    else if ("exclamdown".equals(keyStrokeName))
+    {
+      return VirtualKey.INVERTED_EXCLAMATION_MARK;
+    }
+    else if ("quotedbl".equals(keyStrokeName))
+    {
+      return VirtualKey.QUOTEDBL;
+    }
+    else if ("slash".equals(keyStrokeName))
+    {
+      return VirtualKey.SLASH;
+    }
+    else if ("backslash".equals(keyStrokeName))
+    {
+      return VirtualKey.BACK_SLASH;
+    }
+    else if ("dead_acute".equals(keyStrokeName))
+    {
+      return VirtualKey.DEAD_ACUTE;
+    }
+    else if ("dead_diaresis".equals(keyStrokeName))
+    {
+      return VirtualKey.DEAD_DIAERESIS;
+    }
+    else if ("dead_abovering".equals(keyStrokeName))
+    {
+      return VirtualKey.DEAD_ABOVERING;
+    }
+    else if ("plus".equals(keyStrokeName))
+    {
+      return VirtualKey.PLUS;
+    }
+    else if ("asterisk".equals(keyStrokeName))
+    {
+      return VirtualKey.ASTERISK;
+    }
+    else if ("dead_tilde".equals(keyStrokeName))
+    {
+      return VirtualKey.DEAD_TILDE;
+    }
+    else if ("dead_doubleacute".equals(keyStrokeName))
+    {
+      return VirtualKey.DEAD_DOUBLEACUTE;
+    }
+    else if ("dead_caron".equals(keyStrokeName))
+    {
+      return VirtualKey.DEAD_CARON;
+    }
+    else if ("dead_circumflex".equals(keyStrokeName))
+    {
+      return VirtualKey.DEAD_CIRCUMFLEX;
+    }
+    else if ("comma".equals(keyStrokeName))
+    {
+      return VirtualKey.COMMA;
+    }
+    else if ("semicolon".equals(keyStrokeName))
+    {
+      return VirtualKey.SEMICOLON;
+    }
+    else if ("multiply".equals(keyStrokeName))
+    {
+      return VirtualKey.MULTIPLY;
+    }
+    else if ("period".equals(keyStrokeName))
+    {
+      return VirtualKey.PERIOD;
+    }
+    else if ("colon".equals(keyStrokeName))
+    {
+      return VirtualKey.COLON;
+    }
+    else if ("dead_breve".equals(keyStrokeName))
+    {
+      return VirtualKey.DEAD_BREVE;
+    }
+    else if ("division".equals(keyStrokeName))
+    {
+      return VirtualKey.DIVIDE;
+    }
+    else if ("minus".equals(keyStrokeName))
+    {
+      return VirtualKey.MINUS;
+    }
+    else if ("underscore".equals(keyStrokeName))
+    {
+      return VirtualKey.UNDERSCORE;
+    }
+    else if ("dead_abovedot".equals(keyStrokeName))
+    {
+      return VirtualKey.DEAD_ABOVEDOT;
+    }
+    else if ("bracketleft".equals(keyStrokeName))
+    {
+      return VirtualKey.OPEN_BRACKET;
+    }
+    else if ("bracketright".equals(keyStrokeName))
+    {
+      return VirtualKey.CLOSE_BRACKET;
+    }
+    else if ("grave".equals(keyStrokeName))
+    {
+      return VirtualKey.DEAD_GRAVE;
+    }
+    else if ("equal".equals(keyStrokeName))
+    {
+      return VirtualKey.EQUALS;
+    }
+    else if ("dead_macron".equals(keyStrokeName))
+    {
+      return VirtualKey.DEAD_MACRON;
+    }
+    else if ("dead_ogonek".equals(keyStrokeName))
+    {
+      return VirtualKey.DEAD_OGONEK;
+    }
+    else if ("dead_cedilla".equals(keyStrokeName))
+    {
+      return VirtualKey.DEAD_CEDILLA;
+    }
+    else if ("ampersand".equals(keyStrokeName))
+    {
+      return VirtualKey.AMPERSAND;
+    }
+    else if ("parenleft".equals(keyStrokeName))
+    {
+      return VirtualKey.LEFT_PARENTHESIS;
+    }
+    else if ("parenright".equals(keyStrokeName))
+    {
+      return VirtualKey.RIGHT_PARENTHESIS;
+    }
+    else if ("braceleft".equals(keyStrokeName))
+    {
+      return VirtualKey.BRACELEFT;
+    }
+    else if ("braceright".equals(keyStrokeName))
+    {
+      return VirtualKey.BRACERIGHT;
+    }
+    else if ("at".equals(keyStrokeName))
+    {
+      return VirtualKey.AT;
+    }
+    else if ("dollar".equals(keyStrokeName))
+    {
+      return VirtualKey.DOLLAR;
+    }
+    else if ("EuroSign".equals(keyStrokeName))
+    {
+      return VirtualKey.EURO_SIGN;
+    }
+    else if ("Begin".equals(keyStrokeName))
+    {
+      return VirtualKey.BEGIN;
+    }
+    else if ("numbersign".equals(keyStrokeName))
+    {
+      return VirtualKey.NUMBER_SIGN;
+    }
+    else if ("asciicircum".equals(keyStrokeName))
+    {
+      return VirtualKey.CIRCUMFLEX;
+    }
+    else if ("Kanji".equals(keyStrokeName))
+    {
+      return VirtualKey.KANJI;
+    }
+    else if ("Katakana".equals(keyStrokeName))
+    {
+      return VirtualKey.KATAKANA;
+    }
+    else if ("Hiragana_Katakana".equals(keyStrokeName))
+    {
+      return VirtualKey.HIRAGANA;
+    }
+    else if ("Muhenkan".equals(keyStrokeName))
+    {
+      // I found this in the KeyEvent description
+      return VirtualKey.NONCONVERT;
+    }
+    else if ("kan".equals(keyStrokeName))
+    {
+      // I found this in the KeyEvent description
+      return VirtualKey.NONCONVERT;
+    }
+    else if ("Henkan_Mode".equals(keyStrokeName))
+    {
+      // I found this in the key event description
+      return VirtualKey.CONVERT;
+    }
+    else if ("voicedsound".equals(keyStrokeName))
+    {
+      return VirtualKey.DEAD_VOICED_SOUND;
+    }
+    else if ("semivoicedsound".equals(keyStrokeName))
+    {
+      return VirtualKey.DEAD_SEMIVOICED_SOUND;
+    }
+    else if ("Menu".equals(keyStrokeName))
+    {
+      return VirtualKey.CONTEXT_MENU;
+    }
+    else
+    {
+      LOG.finest("unknown virtual key for key stroke " + keyStrokeName + " specified through " +
+                 "keyboard map for locale " + mLocale);
+      
+      return null;
+    }
+    
+    // for the following virtual keys no key stroke names are provided in the key maps
+    /*CANCEL(KeyEvent.VK_CANCEL),
+    CLEAR(KeyEvent.VK_CLEAR),
+    PAUSE(KeyEvent.VK_PAUSE),
+    HELP(KeyEvent.VK_HELP),
+    META(KeyEvent.VK_META),
+
+    BACK_QUOTE(KeyEvent.VK_BACK_QUOTE),
+    QUOTE(KeyEvent.VK_QUOTE),
+
+    DEAD_IOTA(KeyEvent.VK_DEAD_IOTA),
+
+    FINAL(KeyEvent.VK_FINAL),
+    CONVERT(KeyEvent.VK_CONVERT),
+    NONCONVERT(KeyEvent.VK_NONCONVERT),
+    ACCEPT(KeyEvent.VK_ACCEPT),
+    KANA(KeyEvent.VK_KANA),
+    ALPHANUMERIC(KeyEvent.VK_ALPHANUMERIC),
+    FULL_WIDTH(KeyEvent.VK_FULL_WIDTH),
+    HALF_WIDTH(KeyEvent.VK_HALF_WIDTH),
+    ROMAN_CHARACTERS(KeyEvent.VK_ROMAN_CHARACTERS),
+    ALL_CANDIDATES(KeyEvent.VK_ALL_CANDIDATES),
+    PREVIOUS_CANDIDATE(KeyEvent.VK_PREVIOUS_CANDIDATE),
+    CODE_INPUT(KeyEvent.VK_CODE_INPUT),
+    JAPANESE_KATAKANA(KeyEvent.VK_JAPANESE_KATAKANA),
+    JAPANESE_HIRAGANA(KeyEvent.VK_JAPANESE_HIRAGANA),
+    JAPANESE_ROMAN(KeyEvent.VK_JAPANESE_ROMAN),
+    KANA_LOCK(KeyEvent.VK_KANA_LOCK),
+    INPUT_METHOD_ON_OFF(KeyEvent.VK_INPUT_METHOD_ON_OFF),
+
+    CUT(KeyEvent.VK_CUT),
+    COPY(KeyEvent.VK_COPY),
+    PASTE(KeyEvent.VK_PASTE),
+    UNDO(KeyEvent.VK_UNDO),
+    AGAIN(KeyEvent.VK_AGAIN),
+    FIND(KeyEvent.VK_FIND),
+    PROPS(KeyEvent.VK_PROPS),
+    STOP(KeyEvent.VK_STOP),
+    COMPOSE(KeyEvent.VK_COMPOSE),*/
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param keyStrokeName
+   * @param shift
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  private char determineCharacter(String keyStrokeName, boolean getUpper)
+  {
+    if ("Shift_R".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("Shift_L".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("Alt_R".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("Mode_switch".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("ISO_Level3_Shift".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("Alt_L".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("Control_R".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("Control_L".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("Menu".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("1".equals(keyStrokeName))
+    {
+      return '1';
+    }
+    else if ("2".equals(keyStrokeName))
+    {
+      return '2';
+    }
+    else if ("3".equals(keyStrokeName))
+    {
+      return '3';
+    }
+    else if ("4".equals(keyStrokeName))
+    {
+      return '4';
+    }
+    else if ("5".equals(keyStrokeName))
+    {
+      return '5';
+    }
+    else if ("6".equals(keyStrokeName))
+    {
+      return '6';
+    }
+    else if ("7".equals(keyStrokeName))
+    {
+      return '7';
+    }
+    else if ("8".equals(keyStrokeName))
+    {
+      return '8';
+    }
+    else if ("9".equals(keyStrokeName))
+    {
+      return '9';
+    }
+    else if ("0".equals(keyStrokeName))
+    {
+      return '0';
+    }
+    else if ("BackSpace".equals(keyStrokeName))
+    {
+      return '\b';
+    }
+    else if ("Tab".equals(keyStrokeName))
+    {
+      return '\t';
+    }
+    else if ("ISO_Left_Tab".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("q".equals(keyStrokeName))
+    {
+      return getUpper ? 'Q' : 'q';
+    }
+    else if ("w".equals(keyStrokeName))
+    {
+      return getUpper ? 'W' : 'w';
+    }
+    else if ("e".equals(keyStrokeName))
+    {
+      return getUpper ? 'E' : 'e';
+    }
+    else if ("r".equals(keyStrokeName))
+    {
+      return getUpper ? 'R' : 'r';
+    }
+    else if ("t".equals(keyStrokeName))
+    {
+      return getUpper ? 'T' : 't';
+    }
+    else if ("y".equals(keyStrokeName))
+    {
+      return getUpper ? 'Y' : 'y';
+    }
+    else if ("u".equals(keyStrokeName))
+    {
+      return getUpper ? 'U' : 'u';
+    }
+    else if ("i".equals(keyStrokeName))
+    {
+      return getUpper ? 'I' : 'i';
+    }
+    else if ("o".equals(keyStrokeName))
+    {
+      return getUpper ? 'O' : 'o';
+    }
+    else if ("p".equals(keyStrokeName))
+    {
+      return getUpper ? 'P' : 'p';
+    }
+    else if ("a".equals(keyStrokeName))
+    {
+      return getUpper ? 'A' : 'a';
+    }
+    else if ("s".equals(keyStrokeName))
+    {
+      return getUpper ? 'S' : 's';
+    }
+    else if ("d".equals(keyStrokeName))
+    {
+      return getUpper ? 'D' : 'd';
+    }
+    else if ("f".equals(keyStrokeName))
+    {
+      return getUpper ? 'F' : 'f';
+    }
+    else if ("g".equals(keyStrokeName))
+    {
+      return getUpper ? 'G' : 'g';
+    }
+    else if ("h".equals(keyStrokeName))
+    {
+      return getUpper ? 'H' : 'h';
+    }
+    else if ("j".equals(keyStrokeName))
+    {
+      return getUpper ? 'J' : 'j';
+    }
+    else if ("k".equals(keyStrokeName))
+    {
+      return getUpper ? 'K' : 'k';
+    }
+    else if ("l".equals(keyStrokeName))
+    {
+      return getUpper ? 'L' : 'l';
+    }
+    else if ("Return".equals(keyStrokeName))
+    {
+      return '\n';
+    }
+    else if ("z".equals(keyStrokeName))
+    {
+      return getUpper ? 'Z' : 'z';
+    }
+    else if ("x".equals(keyStrokeName))
+    {
+      return getUpper ? 'X' : 'x';
+    }
+    else if ("c".equals(keyStrokeName))
+    {
+      return getUpper ? 'C' : 'c';
+    }
+    else if ("v".equals(keyStrokeName))
+    {
+      return getUpper ? 'V' : 'v';
+    }
+    else if ("b".equals(keyStrokeName))
+    {
+      return getUpper ? 'B' : 'b';
+    }
+    else if ("n".equals(keyStrokeName))
+    {
+      return getUpper ? 'N' : 'n';
+    }
+    else if ("m".equals(keyStrokeName))
+    {
+      return getUpper ? 'M' : 'm';
+    }
+    else if ("space".equals(keyStrokeName))
+    {
+      return ' ';
+    }
+    else if ("less".equals(keyStrokeName))
+    {
+      return '<';
+    }
+    else if ("greater".equals(keyStrokeName))
+    {
+      return '>';
+    }
+    else if ("bar".equals(keyStrokeName))
+    {
+      return '|';
+    }
+    else if ("brokenbar".equals(keyStrokeName))
+    {
+      return '¦';
+    }
+    else if ("Escape".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("F1".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("F2".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("F3".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("F4".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("F5".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("F6".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("F7".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("F8".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("F9".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("F10".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("F11".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("SunF36".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("F12".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("SunF37".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("Print".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("Sys_Req".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("Execute".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("F22".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("Scroll_Lock".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("F23".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("Insert".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("Delete".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("Home".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("End".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("Page_Up".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("Page_Down".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("Left".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("Up".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("Down".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("Right".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("Num_Lock".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("KP_Divide".equals(keyStrokeName))
+    {
+      return '/';
+    }
+    else if ("KP_Multiply".equals(keyStrokeName))
+    {
+      return '*';
+    }
+    else if ("KP_Subtract".equals(keyStrokeName))
+    {
+      return '-';
+    }
+    else if ("KP_Add".equals(keyStrokeName))
+    {
+      return '+';
+    }
+    else if ("KP_Enter".equals(keyStrokeName))
+    {
+      return '\n';
+    }
+    else if ("KP_Decimal".equals(keyStrokeName))
+    {
+      return ',';
+    }
+    else if ("KP_Separator".equals(keyStrokeName))
+    {
+      return ',';
+    }
+    else if ("KP_Delete".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("KP_0".equals(keyStrokeName))
+    {
+      return '0';
+    }
+    else if ("KP_Insert".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("KP_1".equals(keyStrokeName))
+    {
+      return '1';
+    }
+    else if ("KP_End".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("KP_2".equals(keyStrokeName))
+    {
+      return '2';
+    }
+    else if ("KP_Down".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("KP_3".equals(keyStrokeName))
+    {
+      return '3';
+    }
+    else if ("KP_Next".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("KP_4".equals(keyStrokeName))
+    {
+      return '4';
+    }
+    else if ("KP_Left".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("KP_5".equals(keyStrokeName))
+    {
+      return '5';
+    }
+    else if ("KP_Begin".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("KP_6".equals(keyStrokeName))
+    {
+      return '6';
+    }
+    else if ("KP_Right".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("KP_7".equals(keyStrokeName))
+    {
+      return '7';
+    }
+    else if ("KP_Home".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("KP_8".equals(keyStrokeName))
+    {
+      return '8';
+    }
+    else if ("KP_Up".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("KP_9".equals(keyStrokeName))
+    {
+      return '9';
+    }
+    else if ("KP_Prior".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("Caps_Lock".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("Multi_key".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("exclam".equals(keyStrokeName))
+    {
+      return '!';
+    }
+    else if ("onesuperior".equals(keyStrokeName))
+    {
+      return '¹';
+    }
+    else if ("exclamdown".equals(keyStrokeName))
+    {
+      return '¡';
+    }
+    else if ("quotedbl".equals(keyStrokeName))
+    {
+      return '"';
+    }
+    else if ("twosuperior".equals(keyStrokeName))
+    {
+      return '²';
+    }
+    else if ("oneeighth".equals(keyStrokeName))
+    {
+      return '⅛';
+    }
+    else if ("section".equals(keyStrokeName))
+    {
+      return '§';
+    }
+    else if ("threesuperior".equals(keyStrokeName))
+    {
+      return '³';
+    }
+    else if ("sterling".equals(keyStrokeName))
+    {
+      return '£';
+    }
+    else if ("dollar".equals(keyStrokeName))
+    {
+      return '$';
+    }
+    else if ("onequarter".equals(keyStrokeName))
+    {
+      return '¼';
+    }
+    else if ("currency".equals(keyStrokeName))
+    {
+      return '¤';
+    }
+    else if ("percent".equals(keyStrokeName))
+    {
+      return '%';
+    }
+    else if ("onehalf".equals(keyStrokeName))
+    {
+      return '½';
+    }
+    else if ("threeeighths".equals(keyStrokeName))
+    {
+      return '⅜';
+    }
+    else if ("ampersand".equals(keyStrokeName))
+    {
+      return '&';
+    }
+    else if ("threequarters".equals(keyStrokeName))
+    {
+      return '¾';
+    }
+    else if ("fiveeighths".equals(keyStrokeName))
+    {
+      return '⅝';
+    }
+    else if ("slash".equals(keyStrokeName))
+    {
+      return '/';
+    }
+    else if ("braceleft".equals(keyStrokeName))
+    {
+      return '{';
+    }
+    else if ("seveneighths".equals(keyStrokeName))
+    {
+      return '⅞';
+    }
+    else if ("parenleft".equals(keyStrokeName))
+    {
+      return '(';
+    }
+    else if ("bracketleft".equals(keyStrokeName))
+    {
+      return '[';
+    }
+    else if ("trademark".equals(keyStrokeName))
+    {
+      return '™';
+    }
+    else if ("parenright".equals(keyStrokeName))
+    {
+      return ')';
+    }
+    else if ("bracketright".equals(keyStrokeName))
+    {
+      return ']';
+    }
+    else if ("plusminus".equals(keyStrokeName))
+    {
+      return '±';
+    }
+    else if ("equal".equals(keyStrokeName))
+    {
+      return '=';
+    }
+    else if ("braceright".equals(keyStrokeName))
+    {
+      return '}';
+    }
+    else if ("ssharp".equals(keyStrokeName))
+    {
+      return 'ß';
+    }
+    else if ("question".equals(keyStrokeName))
+    {
+      return '?';
+    }
+    else if ("backslash".equals(keyStrokeName))
+    {
+      return '\\';
+    }
+    else if ("questiondown".equals(keyStrokeName))
+    {
+      return '¿';
+    }
+    else if ("acute".equals(keyStrokeName))
+    {
+      return '´';
+    }
+    else if ("dead_acute".equals(keyStrokeName))
+    {
+      return 0x0301;
+    }
+    else if ("grave".equals(keyStrokeName))
+    {
+      return '`';
+    }
+    else if ("dead_grave".equals(keyStrokeName))
+    {
+      return 0x0300;
+    }
+    else if ("dead_cedilla".equals(keyStrokeName))
+    {
+      return 0x0327;
+    }
+    else if ("dead_ogonek".equals(keyStrokeName))
+    {
+      return 0x0328;
+    }
+    else if ("at".equals(keyStrokeName))
+    {
+      return '@';
+    }
+    else if ("Greek_OMEGA".equals(keyStrokeName))
+    {
+      return 'Ω';
+    }
+    else if ("EuroSign".equals(keyStrokeName))
+    {
+      return '€';
+    }
+    else if ("paragraph".equals(keyStrokeName))
+    {
+      return 0x2029;
+    }
+    else if ("registered".equals(keyStrokeName))
+    {
+      return '®';
+    }
+    else if ("tslash".equals(keyStrokeName))
+    {
+      return 'ŧ';
+    }
+    else if ("Tslash".equals(keyStrokeName))
+    {
+      return 'Ŧ';
+    }
+    else if ("z".equals(keyStrokeName))
+    {
+      return getUpper ? 'Z' : 'z';
+    }
+    else if ("leftarrow".equals(keyStrokeName))
+    {
+      return '←';
+    }
+    else if ("yen".equals(keyStrokeName))
+    {
+      return '¥';
+    }
+    else if ("downarrow".equals(keyStrokeName))
+    {
+      return '↓';
+    }
+    else if ("uparrow".equals(keyStrokeName))
+    {
+      return '↑';
+    }
+    else if ("rightarrow".equals(keyStrokeName))
+    {
+      return '→';
+    }
+    else if ("idotless".equals(keyStrokeName))
+    {
+      return 'ı';
+    }
+    else if ("oslash".equals(keyStrokeName))
+    {
+      return 'ø';
+    }
+    else if ("Ooblique".equals(keyStrokeName))
+    {
+      return 'Ø';
+    }
+    else if ("thorn".equals(keyStrokeName))
+    {
+      return 'þ';
+    }
+    else if ("THORN".equals(keyStrokeName))
+    {
+      return 'Þ';
+    }
+    else if ("udiaeresis".equals(keyStrokeName))
+    {
+      return getUpper ? 'Ü' : 'ü';
+    }
+    else if ("Udiaeresis".equals(keyStrokeName))
+    {
+      return getUpper ? 'Ü' : 'ü';
+    }
+    else if ("dead_diaeresis".equals(keyStrokeName))
+    {
+      return 0x0308;
+    }
+    else if ("dead_abovering".equals(keyStrokeName))
+    {
+      return 0x030A;
+    }
+    else if ("plus".equals(keyStrokeName))
+    {
+      return '+';
+    }
+    else if ("asterisk".equals(keyStrokeName))
+    {
+      return '*';
+    }
+    else if ("asciitilde".equals(keyStrokeName))
+    {
+      return '~';
+    }
+    else if ("dead_tilde".equals(keyStrokeName))
+    {
+      return 0x0303;
+    }
+    else if ("dead_macron".equals(keyStrokeName))
+    {
+      return 0x0304;
+    }
+    else if ("ae".equals(keyStrokeName))
+    {
+      return 'æ';
+    }
+    else if ("AE".equals(keyStrokeName))
+    {
+      return 'Æ';
+    }
+    else if ("eth".equals(keyStrokeName))
+    {
+      return 'ð';
+    }
+    else if ("ETH".equals(keyStrokeName))
+    {
+      return 'Ð';
+    }
+    else if ("dstroke".equals(keyStrokeName))
+    {
+      return getUpper ? 'Đ' : 'đ';
+    }
+    else if ("ordfeminine".equals(keyStrokeName))
+    {
+      return 'ª';
+    }
+    else if ("eng".equals(keyStrokeName))
+    {
+      return 'ŋ';
+    }
+    else if ("ENG".equals(keyStrokeName))
+    {
+      return 'Ŋ';
+    }
+    else if ("hstroke".equals(keyStrokeName))
+    {
+      return 'ħ';
+    }
+    else if ("Hstroke".equals(keyStrokeName))
+    {
+      return 'Ħ';
+    }
+    else if ("kra".equals(keyStrokeName))
+    {
+      return 'ĸ';
+    }
+    else if ("odiaeresis".equals(keyStrokeName))
+    {
+      return 'ö';
+    }
+    else if ("Odiaeresis".equals(keyStrokeName))
+    {
+      return 'Ö';
+    }
+    else if ("dead_doubleacute".equals(keyStrokeName))
+    {
+      return 0x030B;
+    }
+    else if ("adiaeresis".equals(keyStrokeName))
+    {
+      return 'ä';
+    }
+    else if ("Adiaeresis".equals(keyStrokeName))
+    {
+      return 'Ä';
+    }
+    else if ("dead_caron".equals(keyStrokeName))
+    {
+      return 0x030C;
+    }
+    else if ("asciicircum".equals(keyStrokeName))
+    {
+      return '^';
+    }
+    else if ("dead_circumflex".equals(keyStrokeName))
+    {
+      return 0x0302;
+    }
+    else if ("degree".equals(keyStrokeName))
+    {
+      return '°';
+    }
+    else if ("notsign".equals(keyStrokeName))
+    {
+      return '¬';
+    }
+    else if ("numbersign".equals(keyStrokeName))
+    {
+      return '#';
+    }
+    else if ("apostrophe".equals(keyStrokeName))
+    {
+      return '\'';
+    }
+    else if ("dead_breve".equals(keyStrokeName))
+    {
+      return 0x0306;
+    }
+    else if ("y".equals(keyStrokeName))
+    {
+      return getUpper ? 'Y' : 'y';
+    }
+    else if ("guillemotleft".equals(keyStrokeName))
+    {
+      return '»';
+    }
+    else if ("guillemotright".equals(keyStrokeName))
+    {
+      return '«';
+    }
+    else if ("cent".equals(keyStrokeName))
+    {
+      return '¢';
+    }
+    else if ("copyright".equals(keyStrokeName))
+    {
+      return '©';
+    }
+    else if ("leftdoublequotemark".equals(keyStrokeName))
+    {
+      return '„';
+    }
+    else if ("rightdoublequotemark".equals(keyStrokeName))
+    {
+      return '“';
+    }
+    else if ("mu".equals(keyStrokeName))
+    {
+      return 'µ';
+    }
+    else if ("masculine".equals(keyStrokeName))
+    {
+      return 'º';
+    }
+    else if ("comma".equals(keyStrokeName))
+    {
+      return ',';
+    }
+    else if ("semicolon".equals(keyStrokeName))
+    {
+      return ';';
+    }
+    else if ("horizconnector".equals(keyStrokeName))
+    {
+      return '·';
+    }
+    else if ("multiply".equals(keyStrokeName))
+    {
+      return '×';
+    }
+    else if ("period".equals(keyStrokeName))
+    {
+      return '.';
+    }
+    else if ("colon".equals(keyStrokeName))
+    {
+      return ':';
+    }
+    else if ("periodcentered".equals(keyStrokeName))
+    {
+      return '…';
+    }
+    else if ("division".equals(keyStrokeName))
+    {
+      return '÷';
+    }
+    else if ("minus".equals(keyStrokeName))
+    {
+      return '-';
+    }
+    else if ("underscore".equals(keyStrokeName))
+    {
+      return '_';
+    }
+    else if ("dead_belowdot".equals(keyStrokeName))
+    {
+      return 0x0323;
+    }
+    else if ("dead_abovedot".equals(keyStrokeName))
+    {
+      return 0x0307;
+    }
+    else if ("eacute".equals(keyStrokeName))
+    {
+      return getUpper ? 'É' : 'é';
+    }
+    else if ("Eacute".equals(keyStrokeName))
+    {
+      return getUpper ? 'É' : 'é';
+    }
+    else if ("egrave".equals(keyStrokeName))
+    {
+      return getUpper ? 'È' : 'è';
+    }
+    else if ("Egrave".equals(keyStrokeName))
+    {
+      return getUpper ? 'È' : 'è';
+    }
+    else if ("ccedilla".equals(keyStrokeName))
+    {
+      return getUpper ? 'Ç' : 'ç';
+    }
+    else if ("Ccedilla".equals(keyStrokeName))
+    {
+      return getUpper ? 'Ç' : 'ç';
+    }
+    else if ("agrave".equals(keyStrokeName))
+    {
+      return getUpper ? 'À' : 'à';
+    }
+    else if ("Agrave".equals(keyStrokeName))
+    {
+      return getUpper ? 'À' : 'à';
+    }
+    else if ("lstroke".equals(keyStrokeName))
+    {
+      return getUpper ? 'Ł' : 'ł';
+    }
+    else if ("Lstroke".equals(keyStrokeName))
+    {
+      return getUpper ? 'Ł' : 'ł';
+    }
+    else if ("ugrave".equals(keyStrokeName))
+    {
+      return getUpper ? 'Ù' : 'ù';
+    }
+    else if ("Ugrave".equals(keyStrokeName))
+    {
+      return getUpper ? 'Ù' : 'ù';
+    }
+    else if ("igrave".equals(keyStrokeName))
+    {
+      return getUpper ? 'Ì' : 'ì';
+    }
+    else if ("Igrave".equals(keyStrokeName))
+    {
+      return getUpper ? 'Ì' : 'ì';
+    }
+    else if ("ograve".equals(keyStrokeName))
+    {
+      return getUpper ? 'Ò' : 'ò';
+    }
+    else if ("ograve".equals(keyStrokeName))
+    {
+      return getUpper ? 'Ò' : 'ò';
+    }
+    else if ("keyboard_type".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("keyboard_subtype".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("keyboard_functionkeys".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("kana_NU".equals(keyStrokeName))
+    {
+      return 'ヌ';
+    }
+    else if ("kana_FU".equals(keyStrokeName))
+    {
+      return 'フ';
+    }
+    else if ("kana_A".equals(keyStrokeName))
+    {
+      return 'ア';
+    }
+    else if ("kana_a".equals(keyStrokeName))
+    {
+      return 'ァ';
+    }
+    else if ("kana_U".equals(keyStrokeName))
+    {
+      return 'ウ';
+    }
+    else if ("kana_u".equals(keyStrokeName))
+    {
+      return 'ゥ';
+    }
+    else if ("kana_E".equals(keyStrokeName))
+    {
+      return 'エ';
+    }
+    else if ("kana_e".equals(keyStrokeName))
+    {
+      return 'ェ';
+    }
+    else if ("kana_O".equals(keyStrokeName))
+    {
+      return 'オ';
+    }
+    else if ("kana_o".equals(keyStrokeName))
+    {
+      return 'ォ';
+    }
+    else if ("kana_YA".equals(keyStrokeName))
+    {
+      return 'ヤ';
+    }
+    else if ("kana_ya".equals(keyStrokeName))
+    {
+      return 'ャ';
+    }
+    else if ("kana_YU".equals(keyStrokeName))
+    {
+      return 'ユ';
+    }
+    else if ("kana_yu".equals(keyStrokeName))
+    {
+      return 'ュ';
+    }
+    else if ("kana_YO".equals(keyStrokeName))
+    {
+      return 'ヨ';
+    }
+    else if ("kana_yo".equals(keyStrokeName))
+    {
+      return 'ョ';
+    }
+    else if ("kana_WA".equals(keyStrokeName))
+    {
+      return 'ワ';
+    }
+    else if ("kana_WO".equals(keyStrokeName))
+    {
+      return 'ヲ';
+    }
+    else if ("kana_HO".equals(keyStrokeName))
+    {
+      return 'ホ';
+    }
+    else if ("kana_HE".equals(keyStrokeName))
+    {
+      return 'ヘ';
+    }
+    else if ("kana_TA".equals(keyStrokeName))
+    {
+      return 'タ';
+    }
+    else if ("kana_TE".equals(keyStrokeName))
+    {
+      return 'テ';
+    }
+    else if ("kana_I".equals(keyStrokeName))
+    {
+      return 'イ';
+    }
+    else if ("kana_i".equals(keyStrokeName))
+    {
+      return 'ィ';
+    }
+    else if ("kana_SU".equals(keyStrokeName))
+    {
+      return 'ス';
+    }
+    else if ("kana_KA".equals(keyStrokeName))
+    {
+      return 'カ';
+    }
+    else if ("kana_N".equals(keyStrokeName))
+    {
+      return 'ン';
+    }
+    else if ("kana_NA".equals(keyStrokeName))
+    {
+      return 'ナ';
+    }
+    else if ("kana_NI".equals(keyStrokeName))
+    {
+      return 'ニ';
+    }
+    else if ("kana_RA".equals(keyStrokeName))
+    {
+      return 'ラ';
+    }
+    else if ("kana_SE".equals(keyStrokeName))
+    {
+      return 'セ';
+    }
+    else if ("voicedsound".equals(keyStrokeName))
+    {
+      return 0x3099;
+    }
+    else if ("semivoicedsound".equals(keyStrokeName))
+    {
+      return 0x309A;
+    }
+    else if ("kana_openingbracket".equals(keyStrokeName))
+    {
+      return 0x04A2;
+    }
+    else if ("kana_closingbracket".equals(keyStrokeName))
+    {
+      return 0x04A3;
+    }
+    else if ("kana_CHI".equals(keyStrokeName))
+    {
+      return 'チ';
+    }
+    else if ("kana_TO".equals(keyStrokeName))
+    {
+      return 'ト';
+    }
+    else if ("kana_SHI".equals(keyStrokeName))
+    {
+      return 'シ';
+    }
+    else if ("kana_HA".equals(keyStrokeName))
+    {
+      return 'ハ';
+    }
+    else if ("kana_KI".equals(keyStrokeName))
+    {
+      return 'キ';
+    }
+    else if ("kana_KU".equals(keyStrokeName))
+    {
+      return 'ク';
+    }
+    else if ("kana_MA".equals(keyStrokeName))
+    {
+      return 'マ';
+    }
+    else if ("kana_NO".equals(keyStrokeName))
+    {
+      return 'ノ';
+    }
+    else if ("kana_RI".equals(keyStrokeName))
+    {
+      return 'リ';
+    }
+    else if ("kana_RE".equals(keyStrokeName))
+    {
+      return 'レ';
+    }
+    else if ("kana_KE".equals(keyStrokeName))
+    {
+      return 'ケ';
+    }
+    else if ("Zenkaku_Hankaku".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("Kanji".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("kana_MU".equals(keyStrokeName))
+    {
+      return 'ム';
+    }
+    else if ("kana_TSU".equals(keyStrokeName))
+    {
+      return 'ツ';
+    }
+    else if ("kana_tsu".equals(keyStrokeName))
+    {
+      return 'ッ';
+    }
+    else if ("kana_SA".equals(keyStrokeName))
+    {
+      return 'サ';
+    }
+    else if ("kana_SO".equals(keyStrokeName))
+    {
+      return 'ソ';
+    }
+    else if ("kana_HI".equals(keyStrokeName))
+    {
+      return 'ヒ';
+    }
+    else if ("kana_KO".equals(keyStrokeName))
+    {
+      return 'コ';
+    }
+    else if ("kana_MI".equals(keyStrokeName))
+    {
+      return 'ミ';
+    }
+    else if ("kana_MO".equals(keyStrokeName))
+    {
+      return 'モ';
+    }
+    else if ("kana_NE".equals(keyStrokeName))
+    {
+      return 'ネ';
+    }
+    else if ("kana_comma".equals(keyStrokeName))
+    {
+      return '､';
+    }
+    else if ("kana_RU".equals(keyStrokeName))
+    {
+      return 'ル';
+    }
+    else if ("kana_fullstop".equals(keyStrokeName))
+    {
+      return '｡';
+    }
+    else if ("kana_ME".equals(keyStrokeName))
+    {
+      return 'メ';
+    }
+    else if ("kana_conjunctive".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("Henkan_Mode".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("Hiragana_Katakana".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("Katakana".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("Romaji".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("Muhenkan".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("Eisu_toggle".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("Eisu_toggle".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("F13".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("Hangul".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else if ("Hangul_Hanja".equals(keyStrokeName))
+    {
+      return Character.UNASSIGNED;
+    }
+    else
+    {
+      LOG.severe("unknown key stroke name " + keyStrokeName + " specified through keyboard map " +
+                 "for locale " + mLocale);
+      
+//      if (shift)
+//      {
+//        System.err.println("    else if (\"" + keyStrokeName + "\".equals(keyStrokeName))");
+//        System.err.println("    {");
+//        System.err.println("      return shift ? '" + Character.toUpperCase(keyStrokeName.charAt(0)) +
+//                           "' : '" + Character.toLowerCase(keyStrokeName.charAt(0)) + "';");
+//        System.err.println("    }");
+//      }
+//      else
+//      {
+//        System.err.println("    else if (\"" + keyStrokeName + "\".equals(keyStrokeName))");
+//        System.err.println("    {");
+//        System.err.println("      return '" + keyStrokeName + "';");
+//        System.err.println("    }");
+//      }
+//      
+//      return 0x0;
+      throw new IllegalArgumentException("no keyboard map available for locale " + mLocale);
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * this is a former implementation
+   *
+   * @param keyId
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  /*private VirtualKey[] mapKeyIdToVirtualKeys(int     keyId,
+                                             String  keyStrokeName)
+  {
+    
+    Set<String> names = null;
+    
+    for (int i = 0; i < mKeyIds.size(); i++)
+    {
+      if (((Integer) mKeyIds.get(i)[0]) == keyId)
+      {
+        names = (Set<String>) mKeyIds.get(i)[1];
+        break;
+      }
+    }
+    
+    if (names == null)
+    {
+      names = new HashSet<String>();
+      boolean added = false;
+      
+      for (int i = 0; i < mKeyIds.size(); i++)
+      {
+        if (((Integer) mKeyIds.get(i)[0]) > keyId)
+        {
+          mKeyIds.add(i, new Object[] { keyId, names });
+          added = true;
+          break;
+        }
+      }
+      
+      if (!added)
+      {
+        mKeyIds.add(new Object[] { keyId, names });
+      }
+    }
+    
+    names.add(keyStrokeName);
+    
+    
+    switch(keyId)
+    {
+      case 0x36:
+      case 0x2a:
+        return new VirtualKey[] { VirtualKey.SHIFT };
+      case 0xb8:
+        return new VirtualKey[] { VirtualKey.ALT_GRAPH };
+      case 0x38:
+        return new VirtualKey[] { VirtualKey.ALT };
+      case 0x9d:
+      case 0x1d:
+        return new VirtualKey[] { VirtualKey.CONTROL };
+      case 0xdd:
+        return new VirtualKey[] { VirtualKey.WINDOWS };
+      case 0x2:
+        return new VirtualKey[] { VirtualKey.DIGIT_1 };
+      case 0x3:
+        return new VirtualKey[] { VirtualKey.DIGIT_2 };
+      case 0x4:
+        return new VirtualKey[] { VirtualKey.DIGIT_3 };
+      case 0x5:
+        return new VirtualKey[] { VirtualKey.DIGIT_4 };
+      case 0x6:
+        return new VirtualKey[] { VirtualKey.DIGIT_5 };
+      case 0x7:
+        return new VirtualKey[] { VirtualKey.DIGIT_6 };
+      case 0x8:
+        return new VirtualKey[] { VirtualKey.DIGIT_7 };
+      case 0x9:
+        return new VirtualKey[] { VirtualKey.DIGIT_8 };
+      case 0xa:
+        return new VirtualKey[] { VirtualKey.DIGIT_9 };
+      case 0xb:
+        return new VirtualKey[] { VirtualKey.DIGIT_0 };
+      case 0xe:
+        return new VirtualKey[] { VirtualKey.BACK_SPACE };
+      case 0xf:
+        return new VirtualKey[] { VirtualKey.TAB };
+      case 0x10:
+        return new VirtualKey[] { VirtualKey.LETTER_Q };
+      case 0x11:
+        return new VirtualKey[] { VirtualKey.LETTER_W };
+      case 0x12:
+        return new VirtualKey[] { VirtualKey.LETTER_E };
+      case 0x13:
+        return new VirtualKey[] { VirtualKey.LETTER_R };
+      case 0x14:
+        return new VirtualKey[] { VirtualKey.LETTER_T };
+      case 0x15:
+        return new VirtualKey[] { VirtualKey.LETTER_Y };
+      case 0x16:
+        return new VirtualKey[] { VirtualKey.LETTER_U };
+      case 0x17:
+        return new VirtualKey[] { VirtualKey.LETTER_I };
+      case 0x18:
+        return new VirtualKey[] { VirtualKey.LETTER_O };
+      case 0x19:
+        return new VirtualKey[] { VirtualKey.LETTER_P };
+      case 0x1e:
+        return new VirtualKey[] { VirtualKey.LETTER_A };
+      case 0x1f:
+        return new VirtualKey[] { VirtualKey.LETTER_S };
+      case 0x20:
+        return new VirtualKey[] { VirtualKey.LETTER_D };
+      case 0x21:
+        return new VirtualKey[] { VirtualKey.LETTER_F };
+      case 0x22:
+        return new VirtualKey[] { VirtualKey.LETTER_G };
+      case 0x23:
+        return new VirtualKey[] { VirtualKey.LETTER_H };
+      case 0x24:
+        return new VirtualKey[] { VirtualKey.LETTER_J };
+      case 0x25:
+        return new VirtualKey[] { VirtualKey.LETTER_K };
+      case 0x26:
+        return new VirtualKey[] { VirtualKey.LETTER_L };
+      case 0x1c:
+        return new VirtualKey[] { VirtualKey.ENTER };
+      case 0x2c:
+        return new VirtualKey[] { VirtualKey.LETTER_Z };
+      case 0x2d:
+        return new VirtualKey[] { VirtualKey.LETTER_X };
+      case 0x2e:
+        return new VirtualKey[] { VirtualKey.LETTER_C };
+      case 0x2f:
+        return new VirtualKey[] { VirtualKey.LETTER_V };
+      case 0x30:
+        return new VirtualKey[] { VirtualKey.LETTER_B };
+      case 0x31:
+        return new VirtualKey[] { VirtualKey.LETTER_N };
+      case 0x32:
+        return new VirtualKey[] { VirtualKey.LETTER_M };
+      case 0x39:
+        return new VirtualKey[] { VirtualKey.SPACE };
+      case 0x56:
+        return new VirtualKey[] { VirtualKey.LESS };
+      case 0x1:
+        return new VirtualKey[] { VirtualKey.ESCAPE };
+      case 0x3b:
+        return new VirtualKey[] { VirtualKey.F1 };
+      case 0x3c:
+        return new VirtualKey[] { VirtualKey.F2 };
+      case 0x3d:
+        return new VirtualKey[] { VirtualKey.F3 };
+      case 0x3e:
+        return new VirtualKey[] { VirtualKey.F4 };
+      case 0x3f:
+        return new VirtualKey[] { VirtualKey.F5 };
+      case 0x40:
+        return new VirtualKey[] { VirtualKey.F6 };
+      case 0x41:
+        return new VirtualKey[] { VirtualKey.F7 };
+      case 0x42:
+        return new VirtualKey[] { VirtualKey.F8 };
+      case 0x43:
+        return new VirtualKey[] { VirtualKey.F9 };
+      case 0x44:
+        return new VirtualKey[] { VirtualKey.F10 };
+      case 0x57:
+        return new VirtualKey[] { VirtualKey.F11 };
+      case 0x58:
+        return new VirtualKey[] { VirtualKey.F12 };
+      case 0xb7:
+        return new VirtualKey[] { VirtualKey.PRINTSCREEN };
+      case 0x46:
+        return new VirtualKey[] { VirtualKey.SCROLL_LOCK };
+      case 0xd2:
+        return new VirtualKey[] { VirtualKey.INSERT };
+      case 0xd3:
+        return new VirtualKey[] { VirtualKey.DELETE };
+      case 0xc7:
+        return new VirtualKey[] { VirtualKey.HOME };
+      case 0xcf:
+        return new VirtualKey[] { VirtualKey.END };
+      case 0xc9:
+        return new VirtualKey[] { VirtualKey.PAGE_UP };
+      case 0xd1:
+        return new VirtualKey[] { VirtualKey.PAGE_DOWN };
+      case 0xcb:
+        return new VirtualKey[] { VirtualKey.LEFT };
+      case 0xc8:
+        return new VirtualKey[] { VirtualKey.UP };
+      case 0xd0:
+        return new VirtualKey[] { VirtualKey.DOWN };
+      case 0xcd:
+        return new VirtualKey[] { VirtualKey.RIGHT };
+      case 0x45:
+        return new VirtualKey[] { VirtualKey.NUM_LOCK };
+      case 0xb5:
+        return new VirtualKey[] { VirtualKey.DIVIDE };
+      case 0x37:
+        return new VirtualKey[] { VirtualKey.MULTIPLY };
+      case 0x4a:
+        return new VirtualKey[] { VirtualKey.SUBTRACT };
+      case 0x4e:
+        return new VirtualKey[] { VirtualKey.ADD };
+      case 0x9c:
+        return new VirtualKey[] { VirtualKey.ENTER };
+      case 0x53:
+        return new VirtualKey[] { VirtualKey.DECIMAL, VirtualKey.DELETE };
+      case 0x52:
+        return new VirtualKey[] { VirtualKey.NUMPAD_0, VirtualKey.INSERT };
+      case 0x4f:
+        return new VirtualKey[] { VirtualKey.NUMPAD_1, VirtualKey.END };
+      case 0x50:
+        return new VirtualKey[] { VirtualKey.NUMPAD_2, VirtualKey.KP_DOWN };
+      case 0x51:
+        return new VirtualKey[] { VirtualKey.NUMPAD_3, VirtualKey.PAGE_UP };
+      case 0x4b:
+        return new VirtualKey[] { VirtualKey.NUMPAD_4, VirtualKey.KP_LEFT };
+      case 0x4c:
+        return new VirtualKey[] { VirtualKey.NUMPAD_5, VirtualKey.BEGIN };
+      case 0x4d:
+        return new VirtualKey[] { VirtualKey.NUMPAD_6, VirtualKey.KP_RIGHT };
+      case 0x47:
+        return new VirtualKey[] { VirtualKey.NUMPAD_7, VirtualKey.HOME };
+      case 0x48:
+        return new VirtualKey[] { VirtualKey.NUMPAD_8, VirtualKey.KP_UP };
+      case 0x49:
+        return new VirtualKey[] { VirtualKey.NUMPAD_9, VirtualKey.PAGE_DOWN };
+      case 0x0:
+        return new VirtualKey[] { VirtualKey.CAPS_LOCK };
+      case 0xc:
+        return new VirtualKey[] { VirtualKey.MINUS, VirtualKey.UNDERSCORE };
+      case 0xd:
+        return new VirtualKey[] { VirtualKey.EQUALS, VirtualKey.PLUS };
+      case 0x1a:
+        return new VirtualKey[] { VirtualKey.OPEN_BRACKET, VirtualKey.BRACELEFT };
+      case 0x1b:
+        return new VirtualKey[] { VirtualKey.CLOSE_BRACKET, VirtualKey.BRACERIGHT };
+      case 0x27:
+        return new VirtualKey[] { VirtualKey.SEMICOLON, VirtualKey.COLON };
+/*      case 0x28:
+        return new VirtualKey[] { VirtualKey.APOSTROPHE, VirtualKey.QUOTEDBL };
+      case 0x29:
+        return new VirtualKey[] { VirtualKey.DEAD_GRAVE, VirtualKey.DEAD_TILDE };
+      case 0x2b:
+        return new VirtualKey[] { VirtualKey.BACK_SLASH, VirtualKey.BAR };
+      case 0x33:
+        return new VirtualKey[] { VirtualKey.COMMA, VirtualKey.LESS };
+      case 0x34:
+        return new VirtualKey[] { VirtualKey.PERIOD, VirtualKey.GREATER };
+      case 0x35:
+        return new VirtualKey[] { VirtualKey.SLASH, VirtualKey.QUESTIONMARK };
+      case 0x73:
+        return new VirtualKey[] { VirtualKey.BACK_SLASH, VirtualKey.DEGREE,
+                                  VirtualKey.QUESTIONMARK, VirtualKey.UNDERSCORE };
+      case 0x7d:
+        return new VirtualKey[] { VirtualKey.BAR };
+      case 0x79:
+        return new VirtualKey[] { VirtualKey.HENKAN_MODE };
+      case 0x70:
+        return new VirtualKey[] { VirtualKey.KATAKANA };
+      case 0x7b:
+        return new VirtualKey[] { VirtualKey.MUHENKAN };
+      case 0x3a:
+        return new VirtualKey[] { VirtualKey.EISU_TOGGLE, VirtualKey.CAPS_LOCK };
+      case 0xdc:
+        return new VirtualKey[] { VirtualKey.F13 };
+      case 0xf2:
+        return new VirtualKey[] { VirtualKey.HANGUL };
+      case 0xf1:
+        return new VirtualKey[] { VirtualKey.HANGUL_HANJA };
+      case 0x54:
+        return new VirtualKey[] { VirtualKey.EXECUTE };
+      default:
+        LOG.severe("unknown key id 0x" + Integer.toHexString(keyId) + " specified for key stroke " +
+                   keyStrokeName + " through keyboard map for locale " + mLocale);
+        throw new IllegalArgumentException("no keyboard map available for locale " + mLocale);
+    }
+  }*/
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-misc/src/main/java/de/ugoe/cs/tasktree/keyboardmaps/KeyboardMapFactory.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/src/main/java/de/ugoe/cs/tasktree/keyboardmaps/KeyboardMapFactory.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/src/main/java/de/ugoe/cs/tasktree/keyboardmaps/KeyboardMapFactory.java	(revision 540)
@@ -0,0 +1,46 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: KeyboardMapFactory.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 11.07.2012 $
+// Project   : KeyboardMaps
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.tasktree.keyboardmaps;
+
+import java.util.Locale;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 11.07.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public class KeyboardMapFactory
+{
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  private KeyboardMapFactory()
+  {
+    // TODO Auto-generated constructor stub
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  public static KeyboardMap createKeyboardMap(Locale locale)
+  {
+    KeyboardMap keyboardMap = new KeyboardMap(locale);
+    keyboardMap.init();
+    return keyboardMap;
+  }
+}
Index: /tags/quest-pre-eventrefactoring/quest-misc/src/main/java/de/ugoe/cs/tasktree/keyboardmaps/VirtualKey.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/src/main/java/de/ugoe/cs/tasktree/keyboardmaps/VirtualKey.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/src/main/java/de/ugoe/cs/tasktree/keyboardmaps/VirtualKey.java	(revision 540)
@@ -0,0 +1,470 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: Key.java,v $
+// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 01.04.2012 $
+// Project   : TaskTreeCreator
+// Creation  : 2012 by patrick
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.tasktree.keyboardmaps;
+
+import java.awt.event.KeyEvent;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ *
+ * @version $Revision: $ $Date: 01.04.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+//-------------------------------------------------------------------------------------------------
+public enum VirtualKey
+{
+    ENTER(KeyEvent.VK_ENTER),
+    BACK_SPACE(KeyEvent.VK_BACK_SPACE),
+    TAB(KeyEvent.VK_TAB),
+    CANCEL(KeyEvent.VK_CANCEL),
+    CLEAR(KeyEvent.VK_CLEAR),
+    SHIFT(KeyEvent.VK_SHIFT),
+    CONTROL(KeyEvent.VK_CONTROL),
+    ALT(KeyEvent.VK_ALT),
+    PAUSE(KeyEvent.VK_PAUSE),
+    CAPS_LOCK(KeyEvent.VK_CAPS_LOCK),
+    ESCAPE(KeyEvent.VK_ESCAPE),
+    SPACE(KeyEvent.VK_SPACE),
+    PAGE_UP(KeyEvent.VK_PAGE_UP),
+    PAGE_DOWN(KeyEvent.VK_PAGE_DOWN),
+    END(KeyEvent.VK_END),
+    HOME(KeyEvent.VK_HOME),
+
+    LEFT(KeyEvent.VK_LEFT),
+    UP(KeyEvent.VK_UP),
+    RIGHT(KeyEvent.VK_RIGHT),
+    DOWN(KeyEvent.VK_DOWN),
+
+    COMMA(KeyEvent.VK_COMMA),
+    MINUS(KeyEvent.VK_MINUS),
+    PERIOD(KeyEvent.VK_PERIOD),
+    SLASH(KeyEvent.VK_SLASH),
+
+    DIGIT_0(KeyEvent.VK_0),
+    DIGIT_1(KeyEvent.VK_1),
+    DIGIT_2(KeyEvent.VK_2),
+    DIGIT_3(KeyEvent.VK_3),
+    DIGIT_4(KeyEvent.VK_4),
+    DIGIT_5(KeyEvent.VK_5),
+    DIGIT_6(KeyEvent.VK_6),
+    DIGIT_7(KeyEvent.VK_7),
+    DIGIT_8(KeyEvent.VK_8),
+    DIGIT_9(KeyEvent.VK_9),
+
+    SEMICOLON(KeyEvent.VK_SEMICOLON),
+    EQUALS(KeyEvent.VK_EQUALS),
+
+    LETTER_A(KeyEvent.VK_A),
+    LETTER_B(KeyEvent.VK_B),
+    LETTER_C(KeyEvent.VK_C),
+    LETTER_D(KeyEvent.VK_D),
+    LETTER_E(KeyEvent.VK_E),
+    LETTER_F(KeyEvent.VK_F),
+    LETTER_G(KeyEvent.VK_G),
+    LETTER_H(KeyEvent.VK_H),
+    LETTER_I(KeyEvent.VK_I),
+    LETTER_J(KeyEvent.VK_J),
+    LETTER_K(KeyEvent.VK_K),
+    LETTER_L(KeyEvent.VK_L),
+    LETTER_M(KeyEvent.VK_M),
+    LETTER_N(KeyEvent.VK_N),
+    LETTER_O(KeyEvent.VK_O),
+    LETTER_P(KeyEvent.VK_P),
+    LETTER_Q(KeyEvent.VK_Q),
+    LETTER_R(KeyEvent.VK_R),
+    LETTER_S(KeyEvent.VK_S),
+    LETTER_T(KeyEvent.VK_T),
+    LETTER_U(KeyEvent.VK_U),
+    LETTER_V(KeyEvent.VK_V),
+    LETTER_W(KeyEvent.VK_W),
+    LETTER_X(KeyEvent.VK_X),
+    LETTER_Y(KeyEvent.VK_Y),
+    LETTER_Z(KeyEvent.VK_Z),
+
+    OPEN_BRACKET(KeyEvent.VK_OPEN_BRACKET),
+    BACK_SLASH(KeyEvent.VK_BACK_SLASH),
+    CLOSE_BRACKET(KeyEvent.VK_CLOSE_BRACKET),
+
+    NUMPAD_0(KeyEvent.VK_NUMPAD0),
+    NUMPAD_1(KeyEvent.VK_NUMPAD1),
+    NUMPAD_2(KeyEvent.VK_NUMPAD2),
+    NUMPAD_3(KeyEvent.VK_NUMPAD3),
+    NUMPAD_4(KeyEvent.VK_NUMPAD4),
+    NUMPAD_5(KeyEvent.VK_NUMPAD5),
+    NUMPAD_6(KeyEvent.VK_NUMPAD6),
+    NUMPAD_7(KeyEvent.VK_NUMPAD7),
+    NUMPAD_8(KeyEvent.VK_NUMPAD8),
+    NUMPAD_9(KeyEvent.VK_NUMPAD9),
+    MULTIPLY(KeyEvent.VK_MULTIPLY),
+    ADD(KeyEvent.VK_ADD),
+
+    SEPARATOR(KeyEvent.VK_SEPARATOR),
+
+    SUBTRACT(KeyEvent.VK_SUBTRACT),
+    DECIMAL(KeyEvent.VK_DECIMAL),
+    DIVIDE(KeyEvent.VK_DIVIDE),
+    DELETE(KeyEvent.VK_DELETE),
+    NUM_LOCK(KeyEvent.VK_NUM_LOCK),
+    SCROLL_LOCK(KeyEvent.VK_SCROLL_LOCK),
+
+    F1(KeyEvent.VK_F1),
+    F2(KeyEvent.VK_F2),
+    F3(KeyEvent.VK_F3),
+    F4(KeyEvent.VK_F4),
+    F5(KeyEvent.VK_F5),
+    F6(KeyEvent.VK_F6),
+    F7(KeyEvent.VK_F7),
+    F8(KeyEvent.VK_F8),
+    F9(KeyEvent.VK_F9),
+    F10(KeyEvent.VK_F10),
+    F11(KeyEvent.VK_F11),
+    F12(KeyEvent.VK_F12),
+    F13(KeyEvent.VK_F13),
+    F14(KeyEvent.VK_F14),
+    F15(KeyEvent.VK_F15),
+    F16(KeyEvent.VK_F16),
+    F17(KeyEvent.VK_F17),
+    F18(KeyEvent.VK_F18),
+    F19(KeyEvent.VK_F19),
+    F20(KeyEvent.VK_F20),
+    F21(KeyEvent.VK_F21),
+    F22(KeyEvent.VK_F22),
+    F23(KeyEvent.VK_F23),
+    F24(KeyEvent.VK_F24),
+
+    PRINTSCREEN(KeyEvent.VK_PRINTSCREEN),
+    INSERT(KeyEvent.VK_INSERT),
+    HELP(KeyEvent.VK_HELP),
+    META(KeyEvent.VK_META),
+
+    BACK_QUOTE(KeyEvent.VK_BACK_QUOTE),
+    QUOTE(KeyEvent.VK_QUOTE),
+
+    KP_UP(KeyEvent.VK_KP_UP),
+    KP_DOWN(KeyEvent.VK_KP_DOWN),
+    KP_LEFT(KeyEvent.VK_KP_LEFT),
+    KP_RIGHT(KeyEvent.VK_KP_RIGHT),
+
+    DEAD_GRAVE(KeyEvent.VK_DEAD_GRAVE),
+    DEAD_ACUTE(KeyEvent.VK_DEAD_ACUTE),
+    DEAD_CIRCUMFLEX(KeyEvent.VK_DEAD_CIRCUMFLEX),
+    DEAD_TILDE(KeyEvent.VK_DEAD_TILDE),
+    DEAD_MACRON(KeyEvent.VK_DEAD_MACRON),
+    DEAD_BREVE(KeyEvent.VK_DEAD_BREVE),
+    DEAD_ABOVEDOT(KeyEvent.VK_DEAD_ABOVEDOT),
+    DEAD_DIAERESIS(KeyEvent.VK_DEAD_DIAERESIS),
+    DEAD_ABOVERING(KeyEvent.VK_DEAD_ABOVERING),
+    DEAD_DOUBLEACUTE(KeyEvent.VK_DEAD_DOUBLEACUTE),
+    DEAD_CARON(KeyEvent.VK_DEAD_CARON),
+    DEAD_CEDILLA(KeyEvent.VK_DEAD_CEDILLA),
+    DEAD_OGONEK(KeyEvent.VK_DEAD_OGONEK),
+    DEAD_IOTA(KeyEvent.VK_DEAD_IOTA),
+    DEAD_VOICED_SOUND(KeyEvent.VK_DEAD_VOICED_SOUND),
+    DEAD_SEMIVOICED_SOUND(KeyEvent.VK_DEAD_SEMIVOICED_SOUND),
+
+    AMPERSAND(KeyEvent.VK_AMPERSAND),
+    ASTERISK(KeyEvent.VK_ASTERISK),
+    QUOTEDBL(KeyEvent.VK_QUOTEDBL),
+    LESS(KeyEvent.VK_LESS),
+    GREATER(KeyEvent.VK_GREATER),
+    BRACELEFT(KeyEvent.VK_BRACELEFT),
+    BRACERIGHT(KeyEvent.VK_BRACERIGHT),
+
+    AT(KeyEvent.VK_AT),
+    COLON(KeyEvent.VK_COLON),
+    CIRCUMFLEX(KeyEvent.VK_CIRCUMFLEX),
+    DOLLAR(KeyEvent.VK_DOLLAR),
+    EURO_SIGN(KeyEvent.VK_EURO_SIGN),
+    EXCLAMATION_MARK(KeyEvent.VK_EXCLAMATION_MARK),
+    INVERTED_EXCLAMATION_MARK(KeyEvent.VK_INVERTED_EXCLAMATION_MARK),
+    LEFT_PARENTHESIS(KeyEvent.VK_LEFT_PARENTHESIS),
+    NUMBER_SIGN(KeyEvent.VK_NUMBER_SIGN),
+    PLUS(KeyEvent.VK_PLUS),
+    RIGHT_PARENTHESIS(KeyEvent.VK_RIGHT_PARENTHESIS),
+    UNDERSCORE(KeyEvent.VK_UNDERSCORE),
+
+    WINDOWS(KeyEvent.VK_WINDOWS),
+    CONTEXT_MENU(KeyEvent.VK_CONTEXT_MENU),
+
+    FINAL(KeyEvent.VK_FINAL),
+    CONVERT(KeyEvent.VK_CONVERT),
+    NONCONVERT(KeyEvent.VK_NONCONVERT),
+    ACCEPT(KeyEvent.VK_ACCEPT),
+    MODECHANGE(KeyEvent.VK_MODECHANGE),
+    KANA(KeyEvent.VK_KANA),
+    KANJI(KeyEvent.VK_KANJI),
+    ALPHANUMERIC(KeyEvent.VK_ALPHANUMERIC),
+    KATAKANA(KeyEvent.VK_KATAKANA),
+    HIRAGANA(KeyEvent.VK_HIRAGANA),
+    FULL_WIDTH(KeyEvent.VK_FULL_WIDTH),
+    HALF_WIDTH(KeyEvent.VK_HALF_WIDTH),
+    ROMAN_CHARACTERS(KeyEvent.VK_ROMAN_CHARACTERS),
+    ALL_CANDIDATES(KeyEvent.VK_ALL_CANDIDATES),
+    PREVIOUS_CANDIDATE(KeyEvent.VK_PREVIOUS_CANDIDATE),
+    CODE_INPUT(KeyEvent.VK_CODE_INPUT),
+    JAPANESE_KATAKANA(KeyEvent.VK_JAPANESE_KATAKANA),
+    JAPANESE_HIRAGANA(KeyEvent.VK_JAPANESE_HIRAGANA),
+    JAPANESE_ROMAN(KeyEvent.VK_JAPANESE_ROMAN),
+    KANA_LOCK(KeyEvent.VK_KANA_LOCK),
+    INPUT_METHOD_ON_OFF(KeyEvent.VK_INPUT_METHOD_ON_OFF),
+
+    CUT(KeyEvent.VK_CUT),
+    COPY(KeyEvent.VK_COPY),
+    PASTE(KeyEvent.VK_PASTE),
+    UNDO(KeyEvent.VK_UNDO),
+    AGAIN(KeyEvent.VK_AGAIN),
+    FIND(KeyEvent.VK_FIND),
+    PROPS(KeyEvent.VK_PROPS),
+    STOP(KeyEvent.VK_STOP),
+    COMPOSE(KeyEvent.VK_COMPOSE),
+    ALT_GRAPH(KeyEvent.VK_ALT_GRAPH),
+    BEGIN(KeyEvent.VK_BEGIN),
+
+    UNDEFINED(KeyEvent.VK_UNDEFINED);
+    
+    /*BAR(KeyEvent.VK_UNDEFINED),
+    APOSTROPHE(KeyEvent.VK_UNDEFINED),
+    QUESTIONMARK(KeyEvent.VK_UNDEFINED),
+    DEGREE(KeyEvent.VK_UNDEFINED),
+    HENKAN_MODE(KeyEvent.VK_UNDEFINED),
+    MUHENKAN(KeyEvent.VK_UNDEFINED),
+    EISU_TOGGLE(KeyEvent.VK_UNDEFINED),
+    HANGUL(KeyEvent.VK_UNDEFINED),
+    HANGUL_HANJA(KeyEvent.VK_UNDEFINED),
+    EXECUTE(KeyEvent.VK_UNDEFINED);*/
+
+  /** the virtual key code of the virtual key. */
+  private int mVirtualKeyCode = -1;
+
+  /** the description of the virtual key */
+  private String mDescription;
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  private VirtualKey(int virtualKeyCode)
+  {
+    mVirtualKeyCode = virtualKeyCode;
+    mDescription = KeyEvent.getKeyText(mVirtualKeyCode);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * @return Returns the description.
+   */
+  //-----------------------------------------------------------------------------------------------
+  String getDescription()
+  {
+    return mDescription;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  public boolean isCombinationKey()
+  {
+    switch (this)
+    {
+      case SHIFT:
+      case CONTROL:
+      case ALT:
+      case ALT_GRAPH:
+      case WINDOWS:
+        return true;
+
+    default:
+      return false;
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  public boolean isLockKey()
+  {
+    switch (this)
+    {
+      case CAPS_LOCK :
+      case NUM_LOCK:
+      case SCROLL_LOCK:
+
+      return true;
+
+    default:
+      return false;
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  public boolean isShiftKey()
+  {
+    switch (this)
+    {
+      case SHIFT:
+        return true;
+
+      default:
+        return false;
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  public boolean isAltKey()
+  {
+    switch (this)
+    {
+      case ALT:
+      case ALT_GRAPH:
+        return true;
+
+      default:
+        return false;
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  public boolean isControlKey()
+  {
+    switch (this)
+    {
+      case CONTROL:
+        return true;
+
+      default:
+        return false;
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  public boolean isWindowsKey()
+  {
+    switch (this)
+    {
+      case WINDOWS:
+        return true;
+
+      default:
+        return false;
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  public boolean isMetaKey()
+  {
+    switch (this)
+    {
+      case META:
+        return true;
+
+      default:
+        return false;
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  public boolean isLetter()
+  {
+    if (mVirtualKeyCode > -1)
+    {
+      return Character.isLetter((char) mVirtualKeyCode);
+    }
+    else
+    {
+      return false;
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  public boolean isDigit()
+  {
+    if (mVirtualKeyCode > -1)
+    {
+      return Character.isDigit(mVirtualKeyCode);
+    }
+    else
+    {
+      return false;
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param parameter
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  public static VirtualKey parseVirtualKey(String string)
+  {
+    int virtualKeyCode = Integer.parseInt(string);
+    for (VirtualKey key1 : VirtualKey.values())
+    {
+      if (key1.mVirtualKeyCode == virtualKeyCode)
+      {
+        return key1;
+      }
+    }
+      
+    throw new IllegalArgumentException("there is no virtual key with id " + string);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  public static VirtualKey valueOf(int number)
+  {
+    for (VirtualKey virtualKey : VirtualKey.values())
+    {
+      if (virtualKey.mVirtualKeyCode == number)
+      {
+        return virtualKey;
+      }
+    }
+    
+    throw new IllegalArgumentException("there is no virtual key with number " + number);
+  }
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-misc/src/main/java/de/ugoe/cs/tasktree/keyboardmaps/VirtualKeySynonyms.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/src/main/java/de/ugoe/cs/tasktree/keyboardmaps/VirtualKeySynonyms.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/src/main/java/de/ugoe/cs/tasktree/keyboardmaps/VirtualKeySynonyms.java	(revision 540)
@@ -0,0 +1,103 @@
+//-------------------------------------------------------------------------------------------------
+// Module    : $RCSfile: VirtualKeySynonyms.java,v $
+// Version   : $Revision: 0.0 $  $Author: pharms $  $Date: 12.07.2012 $
+// Project   : KeyboardMaps
+// Creation  : 2012 by pharms
+// Copyright : Patrick Harms, 2012
+//-------------------------------------------------------------------------------------------------
+package de.ugoe.cs.tasktree.keyboardmaps;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Logger;
+
+//-------------------------------------------------------------------------------------------------
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 12.07.2012$
+ * @author 2012, last modified by $Author: pharms$
+ */
+//-------------------------------------------------------------------------------------------------
+class VirtualKeySynonyms
+{
+  /** */
+  private static Logger LOG = Logger.getLogger(KeyboardMap.class.getName());
+
+  /** */
+  private Map<Integer, List<VirtualKey>> mSynonyms = new HashMap<Integer, List<VirtualKey>>();
+  
+  /** */
+  private Map<VirtualKey, Integer> mKeyIds = new HashMap<VirtualKey, Integer>();
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param keyId
+   * @param virtualKey
+   */
+  //-----------------------------------------------------------------------------------------------
+  public void add(int keyId, VirtualKey virtualKey)
+  {
+    List<VirtualKey> synonyms = mSynonyms.get(keyId);
+    
+    if (synonyms == null)
+    {
+      synonyms = new ArrayList<VirtualKey>();
+      mSynonyms.put(keyId, synonyms);
+    }
+    
+    if (!synonyms.contains(virtualKey))
+    {
+      // ensure that the latest determined virtual keys are considered first
+      synonyms.add(0, virtualKey);
+    }
+    
+    Integer existingKeyId = mKeyIds.get(virtualKey);
+    
+    if ((existingKeyId != null) && (existingKeyId != keyId))
+    {
+      LOG.finest("virtual key " + virtualKey + " is mapped to more than one key id (current is " +
+                 existingKeyId + ", new is " + keyId + "). New key id will be used (" + keyId +
+                 ").");
+    }
+    
+    mKeyIds.put(virtualKey, keyId);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   *
+   */
+  //-----------------------------------------------------------------------------------------------
+  public boolean containsKey(int keyId)
+  {
+    return mSynonyms.containsKey(keyId);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /**
+   * TODO: comment
+   *
+   * @param keyId
+   * @return
+   */
+  //-----------------------------------------------------------------------------------------------
+  public VirtualKey[] getVirtualKeySynonyms(int keyId)
+  {
+    List<VirtualKey> virtualKeys = mSynonyms.get(keyId);
+    if (virtualKeys != null)
+    {
+      return virtualKeys.toArray(new VirtualKey[virtualKeys.size()]);
+    }
+    else
+    {
+      LOG.warning("no virtual key define for key id " + keyId);
+      return null;
+    }
+  }
+  
+}
Index: /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/ar
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/ar	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/ar	(revision 540)
@@ -0,0 +1,98 @@
+# generated from XKB map ar
+include common
+map 0x401
+exclam 0x02 shift
+at 0x03 shift
+numbersign 0x04 shift
+dollar 0x05 shift
+percent 0x06 shift
+asciicircum 0x07 shift
+ampersand 0x08 shift
+asterisk 0x09 shift
+parenleft 0x0a shift
+parenright 0x0b shift
+minus 0x0c
+underscore 0x0c shift
+equal 0x0d
+plus 0x0d shift
+Arabic_dad 0x10 altgr
+Arabic_fatha 0x10 shift altgr
+Arabic_sad 0x11 altgr
+Arabic_fathatan 0x11 shift altgr
+Arabic_theh 0x12 altgr
+Arabic_damma 0x12 shift altgr
+Arabic_qaf 0x13 altgr
+Arabic_dammatan 0x13 shift altgr
+Arabic_feh 0x14 altgr
+UFEF9 0x14 shift altgr
+Arabic_ghain 0x15 altgr
+Arabic_hamzaunderalef 0x15 shift altgr
+Arabic_ain 0x16 altgr
+grave 0x16 shift altgr
+Arabic_ha 0x17 altgr
+division 0x17 shift altgr
+Arabic_khah 0x18 altgr
+multiply 0x18 shift altgr
+Arabic_hah 0x19 altgr
+Arabic_semicolon 0x19 shift altgr
+bracketleft 0x1a
+braceleft 0x1a shift
+Arabic_jeem 0x1a altgr
+bracketright 0x1b
+braceright 0x1b shift
+Arabic_dal 0x1b altgr
+Arabic_sheen 0x1e altgr
+backslash 0x1e shift altgr
+Arabic_seen 0x1f altgr
+Arabic_yeh 0x20 altgr
+bracketleft 0x20 shift altgr
+Arabic_beh 0x21 altgr
+bracketright 0x21 shift altgr
+Arabic_lam 0x22 altgr
+UFEF7 0x22 shift altgr
+Arabic_alef 0x23 altgr
+Arabic_hamzaonalef 0x23 shift altgr
+Arabic_teh 0x24 altgr
+Arabic_tatweel 0x24 shift altgr
+Arabic_noon 0x25 altgr
+Arabic_comma 0x25 shift altgr
+Arabic_meem 0x26 altgr
+slash 0x26 shift altgr
+semicolon 0x27
+colon 0x27 shift
+Arabic_kaf 0x27 altgr
+apostrophe 0x28
+quotedbl 0x28 shift
+Arabic_tah 0x28 altgr
+grave 0x29
+asciitilde 0x29 shift
+Arabic_thal 0x29 altgr
+Arabic_shadda 0x29 shift altgr
+backslash 0x2b
+bar 0x2b shift
+less 0x2b altgr
+greater 0x2b shift altgr
+Arabic_hamzaonyeh 0x2c altgr
+asciitilde 0x2c shift altgr
+Arabic_hamza 0x2d altgr
+Arabic_sukun 0x2d shift altgr
+Arabic_hamzaonwaw 0x2e altgr
+Arabic_kasra 0x2e shift altgr
+Arabic_ra 0x2f altgr
+Arabic_kasratan 0x2f shift altgr
+UFEFB 0x30 altgr
+UFEF5 0x30 shift altgr
+Arabic_alefmaksura 0x31 altgr
+Arabic_maddaonalef 0x31 shift altgr
+Arabic_tehmarbuta 0x32 altgr
+apostrophe 0x32 shift altgr
+comma 0x33
+less 0x33 shift
+Arabic_waw 0x33 altgr
+period 0x34
+greater 0x34 shift
+Arabic_zain 0x34 altgr
+slash 0x35
+question 0x35 shift
+Arabic_zah 0x35 altgr
+Arabic_question_mark 0x35 shift altgr
Index: /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/common
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/common	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/common	(revision 540)
@@ -0,0 +1,229 @@
+include modifiers
+
+#
+# Top row
+#
+1 0x2
+2 0x3
+3 0x4
+4 0x5
+5 0x6
+6 0x7
+7 0x8
+8 0x9
+9 0xa
+0 0xb
+BackSpace 0xe
+
+#
+# QWERTY first row
+#
+Tab 0xf localstate
+ISO_Left_Tab 0xf shift
+q 0x10 addupper
+w 0x11 addupper
+e 0x12 addupper
+sequence egrave dead_grave e
+sequence Egrave dead_grave E
+sequence eacute dead_acute e
+sequence Eacute dead_acute E
+sequence ecircumflex dead_circumflex e 
+sequence Ecircumflex dead_circumflex E 
+sequence ediaeresis dead_diaeresis e
+sequence Ediaeresis dead_diaeresis E
+r 0x13 addupper
+t 0x14 addupper
+y 0x15 addupper
+sequence ygrave dead_grave y
+sequence Ygrave dead_grave Y
+sequence yacute dead_acute y
+sequence Yacute dead_acute Y
+sequence ycircumflex dead_circumflex y
+sequence Ycircumflex dead_circumflex Y 
+sequence ydiaeresis dead_diaeresis y
+sequence Ydiaeresis dead_diaeresis Y
+u 0x16 addupper
+sequence ugrave dead_grave u
+sequence Ugrave dead_grave U
+sequence uacute dead_acute u
+sequence Uacute dead_acute U
+sequence ucircumflex dead_circumflex u 
+sequence Ucircumflex dead_circumflex U 
+sequence udiaeresis dead_diaeresis u
+sequence Udiaeresis dead_diaeresis U
+i 0x17 addupper
+sequence igrave dead_grave i
+sequence Igrave dead_grave I
+sequence iacute dead_acute i
+sequence Iacute dead_acute I
+sequence icircumflex dead_circumflex i 
+sequence Icircumflex dead_circumflex I 
+sequence idiaeresis dead_diaeresis i
+sequence Idiaeresis dead_diaeresis I
+o 0x18 addupper
+sequence ograve dead_grave o
+sequence Ograve dead_grave O
+sequence oacute dead_acute o
+sequence Oacute dead_acute O
+sequence ocircumflex dead_circumflex o 
+sequence Ocircumflex dead_circumflex O 
+sequence odiaeresis dead_diaeresis o
+sequence Odiaeresis dead_diaeresis O
+sequence otilde dead_tilde o
+sequence Otilde dead_tilde O
+p 0x19 addupper
+
+#
+# QWERTY second row
+#
+a 0x1e addupper
+sequence agrave dead_grave a
+sequence Agrave dead_grave A
+sequence aacute dead_acute a
+sequence Aacute dead_acute A
+sequence acircumflex dead_circumflex a 
+sequence Acircumflex dead_circumflex A 
+sequence adiaeresis dead_diaeresis a
+sequence Adiaeresis dead_diaeresis A
+sequence aring dead_abovering a
+sequence Aring dead_abovering A
+sequence atilde dead_tilde a
+sequence Atilde dead_tilde A
+s 0x1f addupper
+d 0x20 addupper
+f 0x21 addupper
+g 0x22 addupper
+h 0x23 addupper
+j 0x24 addupper
+k 0x25 addupper
+l 0x26 addupper
+Return 0x1c localstate
+
+#
+# QWERTY third row
+#
+z 0x2c addupper
+x 0x2d addupper
+c 0x2e addupper
+sequence ccedilla dead_cedilla c
+sequence Ccedilla dead_cedilla C
+v 0x2f addupper
+b 0x30 addupper
+n 0x31 addupper
+sequence ntilde dead_tilde n
+sequence Ntilde dead_tilde N
+m 0x32 addupper
+
+space 0x39 localstate
+
+less 0x56
+greater 0x56 shift
+bar 0x56 altgr
+brokenbar 0x56 shift altgr
+
+#
+# Translations for some other dead keys
+#
+sequence asciitilde dead_tilde space
+sequence diaeresis dead_diaeresis space
+sequence asciicircum dead_circumflex space
+sequence apostrophe dead_acute space
+sequence grave dead_grave space
+sequence acute dead_acute space
+
+#
+# Esc and Function keys
+#
+Escape 0x1 localstate
+F1 0x3b localstate
+F2 0x3c localstate
+F3 0x3d localstate
+F4 0x3e localstate
+F5 0x3f localstate
+F6 0x40 localstate
+F7 0x41 localstate
+F8 0x42 localstate
+F9 0x43 localstate
+F10 0x44 localstate
+F11 0x57 localstate
+SunF36 0x57 localstate
+F12 0x58 localstate
+SunF37 0x58 localstate
+
+# Printscreen, Scrollock and Pause
+# Printscreen really requires four scancodes (0xe0, 0x2a, 0xe0, 0x37),
+# but (0xe0, 0x37) seems to work. 
+Print 0xb7 localstate
+Sys_Req 0xb7 localstate
+Execute 0xb7 localstate
+F22 0xb7 localstate
+Scroll_Lock 0x46
+F23 0x46
+
+#
+# Insert - PgDown
+#
+Insert 0xd2 localstate
+Delete 0xd3 localstate
+Home 0xc7 localstate
+End 0xcf localstate
+Page_Up 0xc9 localstate
+Page_Down 0xd1 localstate
+
+#
+# Arrow keys
+#
+Left 0xcb localstate
+Up 0xc8 localstate
+Down 0xd0 localstate
+Right 0xcd localstate
+
+#
+# Numpad
+#
+Num_Lock 0x45
+KP_Divide 0xb5 localstate
+KP_Multiply 0x37 localstate
+KP_Subtract 0x4a localstate
+KP_Add 0x4e localstate
+KP_Enter 0x9c localstate
+
+KP_Decimal 0x53 numlock
+KP_Separator 0x53 numlock
+KP_Delete 0x53
+
+KP_0 0x52 numlock
+KP_Insert 0x52 localstate
+
+KP_1 0x4f numlock
+KP_End 0x4f localstate
+
+KP_2 0x50 numlock
+KP_Down 0x50 localstate
+
+KP_3 0x51 numlock
+KP_Next 0x51 localstate
+
+KP_4 0x4b numlock
+KP_Left 0x4b localstate
+
+KP_5 0x4c numlock
+KP_Begin 0x4c localstate
+
+KP_6 0x4d numlock
+KP_Right 0x4d localstate
+
+KP_7 0x47 numlock
+KP_Home 0x47 localstate
+
+KP_8 0x48 numlock
+KP_Up 0x48 localstate
+
+KP_9 0x49 numlock
+KP_Prior 0x49 localstate
+
+#
+# Inhibited keys
+#
+Caps_Lock 0x0 inhibit
+Multi_key 0x0 inhibit
Index: /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/cs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/cs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/cs	(revision 540)
@@ -0,0 +1,87 @@
+# Czech keymap
+include common
+map 0x405
+
+# AltGr
+ISO_Level3_Shift 0xb8
+
+#
+# Top row
+#
+
+# `
+grave 0x29
+asciitilde 0x29 shift
+# 1
+exclam 0x2 shift
+# 2
+at 0x3 shift
+ecaron 0x3 altgr
+# 3
+numbersign 0x4 shift
+# 4
+dollar 0x5 shift
+# 5
+percent 0x6 shift
+# 6
+asciicircum 0x7 shift
+# 7
+ampersand 0x8 shift
+# 8
+asterisk 0x9 shift
+# 9
+parenleft 0xa shift
+# 0
+parenright 0xb shift
+# -
+minus 0xc
+underscore 0xc shift
+# =
+equal 0xd
+plus 0xd shift
+
+
+#
+# QWERTZ first row
+#
+
+# q
+q 0x10 altgr
+# e
+e 0x12 altgr
+# [
+bracketleft 0x1a
+braceleft 0x1a shift
+# ]
+bracketright 0x1b
+braceright 0x1b shift
+
+#
+# QWERTZ second row
+#
+
+# ;
+semicolon 0x27
+# ;
+colon 0x27 shift
+# '
+apostrophe 0x28
+# '
+quotedbl 0x28 shift
+
+#
+# QWERTZ third row
+#
+
+# v
+v 0x2f altgr
+# ,
+comma 0x33
+less 0x33 shift
+# .
+period 0x34
+greater 0x34 shift
+# /
+slash 0x35
+question 0x35 shift
+
Index: /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/da
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/da	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/da	(revision 540)
@@ -0,0 +1,120 @@
+# generated from XKB map dk
+include common
+map 0x406
+exclam 0x02 shift
+exclamdown 0x02 altgr
+onesuperior 0x02 shift altgr
+quotedbl 0x03 shift
+at 0x03 altgr
+twosuperior 0x03 shift altgr
+numbersign 0x04 shift
+sterling 0x04 altgr
+threesuperior 0x04 shift altgr
+currency 0x05 shift
+dollar 0x05 altgr
+onequarter 0x05 shift altgr
+percent 0x06 shift
+onehalf 0x06 altgr
+cent 0x06 shift altgr
+ampersand 0x07 shift
+yen 0x07 altgr
+fiveeighths 0x07 shift altgr
+slash 0x08 shift
+braceleft 0x08 altgr
+division 0x08 shift altgr
+parenleft 0x09 shift
+bracketleft 0x09 altgr
+guillemotleft 0x09 shift altgr
+parenright 0x0a shift
+bracketright 0x0a altgr
+guillemotright 0x0a shift altgr
+equal 0x0b shift
+braceright 0x0b altgr
+degree 0x0b shift altgr
+plus 0x0c
+question 0x0c shift
+plusminus 0x0c altgr
+questiondown 0x0c shift altgr
+dead_acute 0x0d
+dead_grave 0x0d shift
+bar 0x0d altgr
+brokenbar 0x0d shift altgr
+Greek_OMEGA 0x10 shift altgr
+lstroke 0x11 altgr
+Lstroke 0x11 shift altgr
+EuroSign 0x12 altgr
+cent 0x12 shift altgr
+registered 0x13 altgr
+thorn 0x14 altgr
+THORN 0x14 shift altgr
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+downarrow 0x16 altgr
+uparrow 0x16 shift altgr
+rightarrow 0x17 altgr
+idotless 0x17 shift altgr
+oe 0x18 altgr
+OE 0x18 shift altgr
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+aring 0x1a
+Aring 0x1a shift
+dead_diaeresis 0x1a altgr
+dead_abovering 0x1a shift altgr
+dead_diaeresis 0x1b
+dead_circumflex 0x1b shift
+dead_tilde 0x1b altgr
+dead_caron 0x1b shift altgr
+ordfeminine 0x1e altgr
+masculine 0x1e shift altgr
+ssharp 0x1f altgr
+section 0x1f shift altgr
+eth 0x20 altgr
+ETH 0x20 shift altgr
+dstroke 0x21 altgr
+ordfeminine 0x21 shift altgr
+eng 0x22 altgr
+ENG 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+kra 0x25 altgr
+lstroke 0x26 altgr
+Lstroke 0x26 shift altgr
+ae 0x27
+AE 0x27 shift
+oslash 0x28
+Ooblique 0x28 shift
+dead_caron 0x28 shift altgr
+onehalf 0x29
+section 0x29 shift
+threequarters 0x29 altgr
+paragraph 0x29 shift altgr
+apostrophe 0x2b
+asterisk 0x2b shift
+dead_doubleacute 0x2b altgr
+multiply 0x2b shift altgr
+guillemotleft 0x2c altgr
+guillemotright 0x2d altgr
+copyright 0x2e altgr
+leftdoublequotemark 0x2f altgr
+grave 0x2f shift altgr
+rightdoublequotemark 0x30 altgr
+mu 0x32 altgr
+masculine 0x32 shift altgr
+comma 0x33
+semicolon 0x33 shift
+dead_cedilla 0x33 altgr
+dead_ogonek 0x33 shift altgr
+period 0x34
+colon 0x34 shift
+periodcentered 0x34 altgr
+dead_abovedot 0x34 shift altgr
+minus 0x35
+underscore 0x35 shift
+hyphen 0x35 altgr
+macron 0x35 shift altgr
+nobreakspace 0x39 altgr
+less 0x56
+greater 0x56 shift
+backslash 0x56 altgr
+notsign 0x56 shift altgr
Index: /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/de
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/de	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/de	(revision 540)
@@ -0,0 +1,114 @@
+# generated from XKB map de
+include common
+map 0x407
+exclam 0x02 shift
+onesuperior 0x02 altgr
+exclamdown 0x02 shift altgr
+quotedbl 0x03 shift
+twosuperior 0x03 altgr
+oneeighth 0x03 shift altgr
+section 0x04 shift
+threesuperior 0x04 altgr
+sterling 0x04 shift altgr
+dollar 0x05 shift
+onequarter 0x05 altgr
+currency 0x05 shift altgr
+percent 0x06 shift
+onehalf 0x06 altgr
+threeeighths 0x06 shift altgr
+ampersand 0x07 shift
+threequarters 0x07 altgr
+fiveeighths 0x07 shift altgr
+slash 0x08 shift
+braceleft 0x08 altgr
+seveneighths 0x08 shift altgr
+parenleft 0x09 shift
+bracketleft 0x09 altgr
+trademark 0x09 shift altgr
+parenright 0x0a shift
+bracketright 0x0a altgr
+plusminus 0x0a shift altgr
+equal 0x0b shift
+braceright 0x0b altgr
+ssharp 0x0c
+question 0x0c shift
+backslash 0x0c altgr
+questiondown 0x0c shift altgr
+acute 0x0d
+dead_acute 0x0d
+grave 0x0d shift
+dead_grave 0x0d shift
+dead_cedilla 0x0d altgr
+dead_ogonek 0x0d shift altgr
+at 0x10 altgr
+Greek_OMEGA 0x10 shift altgr
+EuroSign 0x12 altgr
+paragraph 0x13 altgr
+registered 0x13 shift altgr
+tslash 0x14 altgr
+Tslash 0x14 shift altgr
+z 0x15 addupper
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+downarrow 0x16 altgr
+uparrow 0x16 shift altgr
+rightarrow 0x17 altgr
+idotless 0x17 shift altgr
+oslash 0x18 altgr
+Ooblique 0x18 shift altgr
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+udiaeresis 0x1a
+Udiaeresis 0x1a shift
+dead_diaeresis 0x1a altgr
+dead_abovering 0x1a shift altgr
+plus 0x1b
+asterisk 0x1b shift
+asciitilde 0x1b altgr
+dead_tilde 0x1b altgr
+dead_macron 0x1b shift altgr
+ae 0x1e altgr
+AE 0x1e shift altgr
+eth 0x20 altgr
+ETH 0x20 shift altgr
+dstroke 0x21 altgr
+ordfeminine 0x21 shift altgr
+eng 0x22 altgr
+ENG 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+kra 0x25 altgr
+odiaeresis 0x27
+Odiaeresis 0x27 shift
+dead_doubleacute 0x27 altgr
+adiaeresis 0x28
+Adiaeresis 0x28 shift
+dead_caron 0x28 shift altgr
+asciicircum 0x29
+dead_circumflex 0x29
+degree 0x29 shift
+notsign 0x29 altgr
+numbersign 0x2b
+apostrophe 0x2b shift
+dead_breve 0x2b shift altgr
+y 0x2c addupper
+guillemotleft 0x2c altgr
+guillemotright 0x2d altgr
+cent 0x2e altgr
+copyright 0x2e shift altgr
+leftdoublequotemark 0x2f altgr
+rightdoublequotemark 0x30 altgr
+mu 0x32 altgr
+masculine 0x32 shift altgr
+comma 0x33
+semicolon 0x33 shift
+horizconnector 0x33 altgr
+multiply 0x33 shift altgr
+period 0x34
+colon 0x34 shift
+periodcentered 0x34 altgr
+division 0x34 shift altgr
+minus 0x35
+underscore 0x35 shift
+dead_belowdot 0x35 altgr
+dead_abovedot 0x35 shift altgr
Index: /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/de-ch
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/de-ch	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/de-ch	(revision 540)
@@ -0,0 +1,169 @@
+# rdesktop Swiss-German (de-ch) keymap file 
+# 2003-06-03 by noldi@tristar.ch 
+#
+include common
+map 0x00000807
+#
+# Scan Code 1
+section 0x29
+degree 0x29 shift
+notsign 0x29 altgr inhibit
+#
+# Scan Code 2
+plus 0x2 shift
+brokenbar 0x02 altgr
+#
+# Scan Code 3
+quotedbl 0x03 shift
+at 0x03 altgr
+#
+# Scan Code 4
+asterisk 0x04 shift
+numbersign 0x04 altgr
+#
+# Scan Code 5
+ccedilla 0x05 shift
+onequarter 0x05 altgr inhibit
+#
+# Scan Code 6
+percent 0x06 shift
+onehalf 0x06 altgr inhibit
+#
+# Scan Code 7
+ampersand 0x07 shift
+notsign 0x07 altgr
+#
+# Scan Code 8
+slash 0x08 shift
+bar 0x08 altgr
+#
+# Scan Code 9
+parenleft 0x09 shift
+cent 0x09 altgr
+# 
+# Scan Code 10
+parenright 0x0a shift
+#
+# Scan Code 11
+equal 0x0b shift
+braceright 0x0b altgr inhibit
+#
+# Scan Code 12
+apostrophe 0x0c 
+question 0x0c shift
+dead_acute 0x0c altgr
+#
+# Scan Code 13
+dead_circumflex 0x0d
+dead_grave 0x0d shift
+dead_tilde 0x0d altgr
+#
+# Scan Code 19
+EuroSign 0x12 altgr
+#
+# Scan Code 22
+z 0x15 addupper
+#
+# Scan Code 27
+udiaeresis 0x1a
+egrave 0x1a shift
+bracketleft 0x1a altgr
+# 
+# Scan Code 28
+dead_diaeresis 0x1b
+exclam 0x1b shift 
+bracketright 0x1b altgr
+#
+# Scan Code 40
+odiaeresis 0x27
+eacute 0x27 shift
+#
+# Scan Code 41
+adiaeresis 0x28
+agrave 0x28 shift
+braceleft 0x28 altgr
+#
+# Scan Code 42 (only on international keyboards)
+dollar 0x2b
+sterling 0x2b shift
+braceright 0x2b altgr
+#
+# Scan Code 45 (only on international keyboards)
+backslash 0x56 altgr
+#
+# Scan Code 46
+y 0x2c addupper
+# 
+# Scan Code 53
+comma 0x33
+semicolon 0x33 shift
+# 
+# Scan Code 54
+period 0x34
+colon 0x34 shift
+#
+# Scan Code 55
+minus 0x35 
+underscore 0x35 shift
+#
+# Suppress Windows unsupported AltGr keys
+#
+# Scan Code 17
+paragraph 0x10 altgr inhibit
+#
+# Scan Code 21
+tslash 0x14 altgr inhibit
+#
+# Scan Code 22
+leftarrow 0x15 altgr inhibit
+#
+# Scan Code 23
+downarrow 0x16 altgr inhibit
+#
+# Scan Code 24
+rightarrow 0x17 altgr inhibit
+#
+# Scan Code 25
+oslash 0x18 altgr inhibit
+#
+# Scan Code 26
+thorn 0x19 altgr inhibit
+#
+# Scan Code 31
+ae 0x1e altgr inhibit
+#
+# Scan Code 32
+ssharp 0x1f altgr inhibit
+#
+# Scan Code 33
+eth 0x20 altgr inhibit
+#
+# Scan Code 34
+dstroke 0x21 altgr inhibit
+#
+# Scan Code 35
+eng 0x22 altgr inhibit
+#
+# Scan Code 36
+hstroke 0x23 altgr inhibit
+#
+# Scan Code 38
+kra 0x25 altgr inhibit
+#
+# Scan Code 39
+lstroke 0x26 altgr inhibit
+#
+# Scan Code 46
+guillemotleft 0x2c altgr inhibit
+#
+# Scan Code 47
+guillemotright 0x2d altgr inhibit
+#
+# Scan Code 49
+leftdoublequotemark 0x2f altgr inhibit
+#
+# Scan Code 50
+rightdoublequotemark 0x30 altgr inhibit
+#
+# Scan Code 52
+mu 0x32 altgr inhibit
Index: /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/en-dv
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/en-dv	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/en-dv	(revision 540)
@@ -0,0 +1,216 @@
+# American Dvorak
+map 0x10409
+
+# Note: we are not including the common section
+include modifiers
+
+#
+# Top row
+#
+1 0x2
+2 0x3
+3 0x4
+4 0x5
+5 0x6
+6 0x7
+7 0x8
+8 0x9
+9 0xa
+0 0xb
+BackSpace 0xe
+
+#
+# QWERTY first row
+
+# QWERTY:
+# q w e r t y u i o p
+
+# Dvorak:
+# ' , . p y f g c r l
+
+Tab 0xf localstate
+ISO_Left_Tab 0xf shift
+q 0x2d addupper
+w 0x33 addupper
+e 0x20 addupper
+r 0x18 addupper
+t 0x25 addupper
+y 0x14 addupper
+u 0x21 addupper
+i 0x22 addupper
+o 0x1f addupper
+p 0x13 addupper
+
+#
+# QWERTY second row
+
+# QUERTY:
+# a s d f g h j k l
+
+# Dvorak:
+# a o e u i d h t n
+ 
+a 0x1e addupper
+s 0x27 addupper
+d 0x23 addupper
+f 0x15 addupper
+g 0x16 addupper
+h 0x24 addupper
+j 0x2e addupper
+k 0x2f addupper
+l 0x19 addupper
+Return 0x1c localstate
+
+#
+# QWERTY third row
+
+# QUERTY:
+# z x c v b n m
+
+# Dvorak:
+# ; q j k x b m
+
+z 0x35 addupper
+x 0x30 addupper
+c 0x17 addupper
+v 0x34 addupper
+b 0x31 addupper
+n 0x26 addupper
+m 0x32 addupper
+
+space 0x39 localstate
+
+less 0x56
+greater 0x56 shift
+bar 0x56 altgr
+brokenbar 0x56 shift altgr
+
+#
+# Esc and Function keys
+#
+Escape 0x1 localstate
+F1 0x3b localstate
+F2 0x3c localstate
+F3 0x3d localstate
+F4 0x3e localstate
+F5 0x3f localstate
+F6 0x40 localstate
+F7 0x41 localstate
+F8 0x42 localstate
+F9 0x43 localstate
+F10 0x44 localstate
+F11 0x57 localstate
+SunF36 0x57 localstate
+F12 0x58 localstate
+SunF37 0x58 localstate
+
+# Printscreen, Scrollock and Pause
+# Printscreen really requires four scancodes (0xe0, 0x2a, 0xe0, 0x37),
+# but (0xe0, 0x37) seems to work. 
+Print 0xb7 localstate
+Sys_Req 0xb7 localstate
+Execute 0xb7 localstate
+F22 0xb7 localstate
+Scroll_Lock 0x46
+F23 0x46
+
+#
+# Insert - PgDown
+#
+Insert 0xd2 localstate
+Delete 0xd3 localstate
+Home 0xc7 localstate
+End 0xcf localstate
+Page_Up 0xc9 localstate
+Page_Down 0xd1 localstate
+
+#
+# Arrow keys
+#
+Left 0xcb localstate
+Up 0xc8 localstate
+Down 0xd0 localstate
+Right 0xcd localstate
+
+#
+# Numpad
+#
+Num_Lock 0x45
+KP_Divide 0xb5
+KP_Multiply 0x37
+KP_Subtract 0x4a
+KP_Add 0x4e
+KP_Enter 0x9c
+
+KP_Decimal 0x53 numlock
+KP_Separator 0x53 numlock
+KP_Delete 0x53
+
+KP_0 0x52 numlock
+KP_Insert 0x52
+
+KP_1 0x4f numlock
+KP_End 0x4f
+
+KP_2 0x50 numlock
+KP_Down 0x50
+
+KP_3 0x51 numlock
+KP_Next 0x51
+
+KP_4 0x4b numlock
+KP_Left 0x4b
+
+KP_5 0x4c numlock
+KP_Begin 0x4c
+
+KP_6 0x4d numlock
+KP_Right 0x4d
+
+KP_7 0x47 numlock
+KP_Home 0x47
+
+KP_8 0x48 numlock
+KP_Up 0x48
+
+KP_9 0x49 numlock
+KP_Prior 0x49
+
+#
+# Inhibited keys
+#
+Caps_Lock 0x0 inhibit
+Multi_key 0x0 inhibit
+
+exclam 0x02 shift
+at 0x03 shift
+numbersign 0x04 shift
+dollar 0x05 shift
+percent 0x06 shift
+asciicircum 0x07 shift
+ampersand 0x08 shift
+asterisk 0x09 shift
+parenleft 0x0a shift
+parenright 0x0b shift
+minus 0x28
+underscore 0x28 shift
+equal 0x1b
+plus 0x1b shift
+bracketleft 0x0c
+braceleft 0x0c shift
+bracketright 0x0d
+braceright 0x0d shift
+semicolon 0x2c
+colon 0x2c shift
+apostrophe 0x10
+quotedbl 0x10 shift
+grave 0x29
+asciitilde 0x29 shift
+backslash 0x2b
+bar 0x2b shift
+comma 0x11
+less 0x11 shift
+period 0x12
+greater 0x12 shift
+slash 0x1a
+question 0x1a shift
Index: /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/en-gb
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/en-gb	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/en-gb	(revision 540)
@@ -0,0 +1,119 @@
+# generated from XKB map gb
+include common
+map 0x809
+exclam 0x02 shift
+onesuperior 0x02 altgr
+exclamdown 0x02 shift altgr
+quotedbl 0x03 shift
+twosuperior 0x03 altgr
+oneeighth 0x03 shift altgr
+sterling 0x04 shift
+threesuperior 0x04 altgr
+dollar 0x05 shift
+EuroSign 0x05 altgr
+percent 0x06 shift
+onehalf 0x06 altgr
+threeeighths 0x06 shift altgr
+asciicircum 0x07 shift
+threequarters 0x07 altgr
+fiveeighths 0x07 shift altgr
+ampersand 0x08 shift
+braceleft 0x08 altgr
+seveneighths 0x08 shift altgr
+asterisk 0x09 shift
+bracketleft 0x09 altgr
+trademark 0x09 shift altgr
+parenleft 0x0a shift
+bracketright 0x0a altgr
+plusminus 0x0a shift altgr
+parenright 0x0b shift
+braceright 0x0b altgr
+degree 0x0b shift altgr
+minus 0x0c
+underscore 0x0c shift
+backslash 0x0c altgr
+questiondown 0x0c shift altgr
+equal 0x0d
+plus 0x0d shift
+dead_cedilla 0x0d altgr
+dead_ogonek 0x0d shift altgr
+at 0x10 altgr
+Greek_OMEGA 0x10 shift altgr
+lstroke 0x11 altgr
+Lstroke 0x11 shift altgr
+paragraph 0x13 altgr
+registered 0x13 shift altgr
+tslash 0x14 altgr
+Tslash 0x14 shift altgr
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+downarrow 0x16 altgr
+uparrow 0x16 shift altgr
+rightarrow 0x17 altgr
+idotless 0x17 shift altgr
+oslash 0x18 altgr
+Ooblique 0x18 shift altgr
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+bracketleft 0x1a
+braceleft 0x1a shift
+dead_diaeresis 0x1a altgr
+dead_abovering 0x1a shift altgr
+bracketright 0x1b
+braceright 0x1b shift
+dead_tilde 0x1b altgr
+dead_macron 0x1b shift altgr
+ae 0x1e altgr
+AE 0x1e shift altgr
+ssharp 0x1f altgr
+section 0x1f shift altgr
+eth 0x20 altgr
+ETH 0x20 shift altgr
+dstroke 0x21 altgr
+ordfeminine 0x21 shift altgr
+eng 0x22 altgr
+ENG 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+kra 0x25 altgr
+lstroke 0x26 altgr
+Lstroke 0x26 shift altgr
+semicolon 0x27
+colon 0x27 shift
+dead_acute 0x27 altgr
+dead_doubleacute 0x27 shift altgr
+apostrophe 0x28
+at 0x28 shift
+dead_circumflex 0x28 altgr
+dead_caron 0x28 shift altgr
+grave 0x29
+notsign 0x29 shift
+bar 0x29 altgr
+numbersign 0x2b
+asciitilde 0x2b shift
+dead_grave 0x2b altgr
+dead_breve 0x2b shift altgr
+guillemotleft 0x2c altgr
+less 0x2c shift altgr
+guillemotright 0x2d altgr
+greater 0x2d shift altgr
+cent 0x2e altgr
+copyright 0x2e shift altgr
+leftdoublequotemark 0x2f altgr
+rightdoublequotemark 0x30 altgr
+mu 0x32 altgr
+masculine 0x32 shift altgr
+comma 0x33
+less 0x33 shift
+horizconnector 0x33 altgr
+multiply 0x33 shift altgr
+period 0x34
+greater 0x34 shift
+periodcentered 0x34 altgr
+division 0x34 shift altgr
+slash 0x35
+question 0x35 shift
+dead_belowdot 0x35 altgr
+dead_abovedot 0x35 shift altgr
+backslash 0x56
+bar 0x56 shift
Index: /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/en-us
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/en-us	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/en-us	(revision 540)
@@ -0,0 +1,35 @@
+# generated from XKB map us
+include common
+map 0x409
+exclam 0x02 shift
+at 0x03 shift
+numbersign 0x04 shift
+dollar 0x05 shift
+percent 0x06 shift
+asciicircum 0x07 shift
+ampersand 0x08 shift
+asterisk 0x09 shift
+parenleft 0x0a shift
+parenright 0x0b shift
+minus 0x0c
+underscore 0x0c shift
+equal 0x0d
+plus 0x0d shift
+bracketleft 0x1a
+braceleft 0x1a shift
+bracketright 0x1b
+braceright 0x1b shift
+semicolon 0x27
+colon 0x27 shift
+apostrophe 0x28
+quotedbl 0x28 shift
+grave 0x29
+asciitilde 0x29 shift
+backslash 0x2b
+bar 0x2b shift
+comma 0x33
+less 0x33 shift
+period 0x34
+greater 0x34 shift
+slash 0x35
+question 0x35 shift
Index: /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/es
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/es	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/es	(revision 540)
@@ -0,0 +1,105 @@
+# generated from XKB map es
+include common
+map 0x40a
+exclam 0x02 shift
+bar 0x02 altgr
+quotedbl 0x03 shift
+at 0x03 altgr
+oneeighth 0x03 shift altgr
+periodcentered 0x04 shift
+numbersign 0x04 altgr
+sterling 0x04 shift altgr
+dollar 0x05 shift
+asciitilde 0x05 altgr
+percent 0x06 shift
+onehalf 0x06 altgr
+threeeighths 0x06 shift altgr
+ampersand 0x07 shift
+notsign 0x07 altgr
+fiveeighths 0x07 shift altgr
+slash 0x08 shift
+seveneighths 0x08 shift altgr
+parenleft 0x09 shift
+trademark 0x09 shift altgr
+parenright 0x0a shift
+plusminus 0x0a shift altgr
+equal 0x0b shift
+degree 0x0b shift altgr
+apostrophe 0x0c
+question 0x0c shift
+exclamdown 0x0d
+questiondown 0x0d shift
+Greek_OMEGA 0x10 shift altgr
+lstroke 0x11 altgr
+Lstroke 0x11 shift altgr
+EuroSign 0x12 altgr
+paragraph 0x13 altgr
+registered 0x13 shift altgr
+tslash 0x14 altgr
+Tslash 0x14 shift altgr
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+downarrow 0x16 altgr
+uparrow 0x16 shift altgr
+rightarrow 0x17 altgr
+idotless 0x17 shift altgr
+oslash 0x18 altgr
+Ooblique 0x18 shift altgr
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+dead_grave 0x1a
+dead_circumflex 0x1a shift
+bracketleft 0x1a altgr
+dead_abovering 0x1a shift altgr
+plus 0x1b
+asterisk 0x1b shift
+bracketright 0x1b altgr
+dead_macron 0x1b shift altgr
+ae 0x1e altgr
+AE 0x1e shift altgr
+ssharp 0x1f altgr
+section 0x1f shift altgr
+eth 0x20 altgr
+ETH 0x20 shift altgr
+dstroke 0x21 altgr
+eng 0x22 altgr
+ENG 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+kra 0x25 altgr
+lstroke 0x26 altgr
+Lstroke 0x26 shift altgr
+ntilde 0x27
+Ntilde 0x27 shift
+dead_doubleacute 0x27 shift altgr
+dead_acute 0x28
+dead_diaeresis 0x28 shift
+braceleft 0x28 altgr
+masculine 0x29
+ordfeminine 0x29 shift
+backslash 0x29 altgr
+ccedilla 0x2b
+Ccedilla 0x2b shift
+braceright 0x2b altgr
+dead_breve 0x2b shift altgr
+guillemotleft 0x2c altgr
+less 0x56
+greater 0x56 shift
+guillemotright 0x2d altgr
+cent 0x2e altgr
+copyright 0x2e shift altgr
+leftdoublequotemark 0x2f altgr
+grave 0x2f shift altgr
+rightdoublequotemark 0x30 altgr
+mu 0x32 altgr
+comma 0x33
+semicolon 0x33 shift
+horizconnector 0x33 altgr
+multiply 0x33 shift altgr
+period 0x34
+colon 0x34 shift
+division 0x34 shift altgr
+minus 0x35
+underscore 0x35 shift
+dead_belowdot 0x35 altgr
+dead_abovedot 0x35 shift altgr
Index: /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/et
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/et	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/et	(revision 540)
@@ -0,0 +1,86 @@
+map 0x00000425
+include common
+
+#
+# Top row
+#
+dead_caron 0x29
+dead_tilde 0x29 shift
+
+# 1
+exclam 0x2 shift
+
+# 2
+quotedbl 0x3 shift
+at 0x3 altgr
+
+# 3
+numbersign 0x4 shift
+sterling 0x4 altgr
+# 4
+currency 0x5 shift
+dollar 0x5 altgr
+# 5
+percent 0x6 shift
+# 6
+ampersand 0x7 shift
+# 7
+slash 0x8 shift
+braceleft 0x8 altgr
+# 8
+parenleft 0x9 shift
+bracketleft 0x9 altgr
+# 9
+parenright 0xa shift
+bracketright 0xa altgr
+# 0
+equal 0xb shift
+braceright 0xb altgr
+
+plus 0xc
+question 0xc shift
+backslash 0xc altgr
+
+acute 0xd
+dead_acute 0xd
+grave 0xd shift
+dead_grave 0xd shift
+
+#
+# QWERTY first row
+#
+EuroSign 0x12 altgr
+udiaeresis 0x1a 
+Udiaeresis 0x1a shift
+otilde 0x1b 
+Otilde 0x1b shift
+section 0x1b altgr
+
+#
+# QWERTY second row
+#
+scaron 0x1f altgr
+Scaron 0x1f altgr shift
+odiaeresis 0x27 
+Odiaeresis 0x27 shift
+adiaeresis 0x28 
+Adiaeresis 0x28 shift
+asciicircum 0x28 altgr
+apostrophe 0x2b
+asterisk 0x2b shift
+onehalf 0x2b altgr
+#
+# QWERTY third row
+#
+less 0x56 
+greater 0x56 shift
+bar 0x56 altgr
+zcaron 0x2c altgr
+Zcaron 0x2c altgr shift
+comma 0x33
+semicolon 0x33 shift
+period 0x34
+colon 0x34 shift
+minus 0x35
+underscore 0x35 shift
+
Index: /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/fi
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/fi	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/fi	(revision 540)
@@ -0,0 +1,122 @@
+# Finnish keyboard layout
+# Originally generated from XKB map se_FI (wrong!), modified afterwards.
+
+include common
+map 0x40b
+
+exclam 0x02 shift
+exclamdown 0x02 altgr
+onesuperior 0x02 shift altgr
+quotedbl 0x03 shift
+at 0x03 altgr
+twosuperior 0x03 shift altgr
+numbersign 0x04 shift
+sterling 0x04 altgr
+threesuperior 0x04 shift altgr
+currency 0x05 shift
+dollar 0x05 altgr
+onequarter 0x05 shift altgr
+percent 0x06 shift
+onehalf 0x06 altgr
+cent 0x06 shift altgr
+ampersand 0x07 shift
+yen 0x07 altgr
+fiveeighths 0x07 shift altgr
+slash 0x08 shift
+braceleft 0x08 altgr
+division 0x08 shift altgr
+parenleft 0x09 shift
+bracketleft 0x09 altgr
+guillemotleft 0x09 shift altgr
+parenright 0x0a shift
+bracketright 0x0a altgr
+guillemotright 0x0a shift altgr
+equal 0x0b shift
+braceright 0x0b altgr
+degree 0x0b shift altgr
+plus 0x0c
+question 0x0c shift
+backslash 0x0c altgr
+questiondown 0x0c shift altgr
+dead_acute 0x0d
+dead_grave 0x0d shift
+plusminus 0x0d altgr
+notsign 0x0d shift altgr
+Greek_OMEGA 0x10 shift altgr
+lstroke 0x11 altgr
+Lstroke 0x11 shift altgr
+EuroSign 0x12 altgr
+cent 0x12 shift altgr
+registered 0x13 altgr
+thorn 0x14 altgr
+THORN 0x14 shift altgr
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+downarrow 0x16 altgr
+uparrow 0x16 shift altgr
+rightarrow 0x17 altgr
+idotless 0x17 shift altgr
+oe 0x18 altgr
+OE 0x18 shift altgr
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+aring 0x1a
+Aring 0x1a shift
+dead_diaeresis 0x1a altgr
+dead_abovering 0x1a shift altgr
+dead_diaeresis 0x1b
+dead_circumflex 0x1b shift
+dead_tilde 0x1b altgr
+dead_caron 0x1b shift altgr
+ordfeminine 0x1e altgr
+masculine 0x1e shift altgr
+ssharp 0x1f altgr
+section 0x1f shift altgr
+eth 0x20 altgr
+ETH 0x20 shift altgr
+dstroke 0x21 altgr
+ordfeminine 0x21 shift altgr
+eng 0x22 altgr
+ENG 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+kra 0x25 altgr
+lstroke 0x26 altgr
+Lstroke 0x26 shift altgr
+odiaeresis 0x27
+Odiaeresis 0x27 shift
+oslash 0x27 altgr
+Ooblique 0x27 shift altgr
+adiaeresis 0x28
+Adiaeresis 0x28 shift
+ae 0x28 altgr
+AE 0x28 shift altgr
+section 0x29
+onehalf 0x29 shift
+paragraph 0x29 altgr
+threequarters 0x29 shift altgr
+apostrophe 0x2b
+asterisk 0x2b shift
+acute 0x2b altgr
+multiply 0x2b shift altgr
+guillemotleft 0x2c altgr
+guillemotright 0x2d altgr
+copyright 0x2e altgr
+leftdoublequotemark 0x2f altgr
+grave 0x2f shift altgr
+rightdoublequotemark 0x30 altgr
+mu 0x32 altgr
+masculine 0x32 shift altgr
+comma 0x33
+semicolon 0x33 shift
+dead_cedilla 0x33 altgr
+dead_ogonek 0x33 shift altgr
+period 0x34
+colon 0x34 shift
+periodcentered 0x34 altgr
+dead_abovedot 0x34 shift altgr
+minus 0x35
+underscore 0x35 shift
+hyphen 0x35 altgr
+macron 0x35 shift altgr
+nobreakspace 0x39 altgr
Index: /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/fo
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/fo	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/fo	(revision 540)
@@ -0,0 +1,77 @@
+map 0x438
+include common
+
+#
+# Top row
+#
+onehalf 0x29
+section 0x29 shift
+
+# 1
+exclam 0x2 shift
+
+# 2
+quotedbl 0x3 shift
+at 0x3 altgr
+
+# 3
+numbersign 0x4 shift
+sterling 0x4 altgr
+# 4
+currency 0x5 shift
+dollar 0x5 altgr
+# 5
+percent 0x6 shift
+# 6
+ampersand 0x7 shift
+# 7
+slash 0x8 shift
+braceleft 0x8 altgr
+# 8
+parenleft 0x9 shift
+bracketleft 0x9 altgr
+# 9
+parenright 0xa shift
+bracketright 0xa altgr
+# 0
+equal 0xb shift
+braceright 0xb altgr
+
+plus 0xc
+question 0xc shift
+plusminus 0xc altgr
+
+bar 0xd altgr
+dead_acute 0xd
+
+#
+# QWERTY first row
+#
+EuroSign 0x12 altgr
+aring 0x1a
+Aring 0x1a shift
+eth 0x1b addupper
+asciitilde 0x1b altgr
+
+#
+# QWERTY second row
+#
+ae 0x27 addupper
+oslash 0x28
+Ooblique 0x28 shift
+apostrophe 0x2b
+asterisk 0x2b shift
+
+#
+# QWERTY third row
+#
+less 0x56
+greater 0x56 shift
+backslash 0x56 altgr
+comma 0x33
+semicolon 0x33 shift
+period 0x34
+colon 0x34 shift
+minus 0x35
+underscore 0x35 shift
+
Index: /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/fr
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/fr	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/fr	(revision 540)
@@ -0,0 +1,181 @@
+include common
+map 0x40c
+#
+# Top row
+#
+twosuperior 0x29
+notsign 0x29 altgr
+
+ampersand 0x02
+1 0x02 shift
+onesuperior 0x02 altgr
+exclamdown 0x02 shift altgr
+
+eacute 0x03
+2 0x03 shift
+asciitilde 0x03 altgr
+oneeighth 0x03 shift altgr
+
+quotedbl 0x04
+3 0x04 shift
+numbersign 0x04 altgr
+
+apostrophe 0x05
+4 0x05 shift
+braceleft 0x05 altgr
+
+parenleft 0x06
+5 0x06 shift
+bracketleft 0x06 altgr
+threeeighths 0x06 shift altgr
+
+minus 0x07
+6 0x07 shift
+bar 0x07 altgr
+fiveeighths 0x07 shift altgr
+
+egrave 0x08
+7 0x08 shift
+grave 0x08 altgr
+seveneighths 0x08 shift altgr
+
+underscore 0x09
+8 0x09 shift
+backslash 0x09 altgr
+trademark 0x09 shift altgr
+
+ccedilla 0x0a
+9 0x0a shift
+asciicircum 0x0a altgr
+plusminus 0x0a shift altgr
+
+agrave 0x0b
+0 0x0b shift
+at 0x0b altgr
+
+parenright 0x0c
+degree 0x0c shift
+bracketright 0x0c altgr
+questiondown 0x0c shift altgr
+
+equal 0x0d
+plus 0x0d shift
+braceright 0x0d altgr
+dead_ogonek 0x0d shift altgr
+
+#
+# AZERTY first row
+#
+
+a 0x10 addupper
+ae 0x10 altgr
+AE 0x10 shift altgr
+
+z 0x11 addupper
+guillemotleft 0x11 altgr
+
+EuroSign 0x12 altgr
+
+paragraph 0x13 altgr
+registered 0x13 shift altgr
+
+tslash 0x14 altgr
+Tslash 0x14 shift altgr
+
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+
+downarrow 0x16 altgr
+uparrow 0x16 shift altgr
+
+rightarrow 0x17 altgr
+idotless 0x17 shift altgr
+
+oslash 0x18 altgr
+Ooblique 0x18 shift altgr
+
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+
+dead_circumflex 0x1a 
+dead_diaeresis 0x1a shift
+dead_abovering 0x1a shift altgr
+
+dollar 0x1b
+sterling 0x1b shift
+currency 0x1b altgr
+dead_macron 0x1b shift altgr
+
+#
+# AZERTY second row
+#
+q 0x1e addupper
+Greek_OMEGA 0x1e shift altgr
+
+ssharp 0x1f altgr
+
+eth 0x20 altgr
+ETH 0x20 shift altgr
+
+dstroke 0x21 altgr
+ordfeminine 0x21 shift altgr
+
+eng 0x22 altgr
+ENG 0x22 shift altgr
+
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+
+kra 0x25 altgr
+
+lstroke 0x26 altgr
+Lstroke 0x26 shift altgr
+
+m 0x27 addupper
+masculine 0x27 shift altgr
+
+ugrave 0x28
+percent 0x28 shift
+dead_caron 0x28 shift altgr
+
+asterisk 0x2b
+mu 0x2b shift
+dead_grave 0x2b altgr
+dead_breve 0x2b shift altgr
+
+#
+# AZERTY third row
+#
+less 0x56
+greater 0x56 shift
+
+w 0x2c addupper
+
+guillemotright 0x2d altgr
+
+cent 0x2e altgr
+copyright 0x2e shift altgr
+
+leftdoublequotemark 0x2f altgr
+
+rightdoublequotemark 0x30 altgr
+
+comma 0x32
+question 0x32 shift
+dead_acute 0x32 altgr
+dead_doubleacute 0x32 shift altgr
+
+semicolon 0x33
+period 0x33 shift
+horizconnector 0x33 altgr
+multiply 0x33 shift altgr
+
+colon 0x34
+slash 0x34 shift
+periodcentered 0x34 altgr
+division 0x34 shift altgr
+
+exclam 0x35
+section 0x35 shift
+dead_belowdot 0x35 altgr
+dead_abovedot 0x35 shift altgr
Index: /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/fr-be
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/fr-be	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/fr-be	(revision 540)
@@ -0,0 +1,135 @@
+# generated from XKB map be
+include common
+map 0x80c
+ampersand 0x02
+1 0x02 shift
+bar 0x02 altgr
+exclamdown 0x02 shift altgr
+eacute 0x03
+2 0x03 shift
+at 0x03 altgr
+oneeighth 0x03 shift altgr
+quotedbl 0x04
+3 0x04 shift
+numbersign 0x04 altgr
+sterling 0x04 shift altgr
+apostrophe 0x05
+4 0x05 shift
+onequarter 0x05 altgr
+dollar 0x05 shift altgr
+parenleft 0x06
+5 0x06 shift
+onehalf 0x06 altgr
+threeeighths 0x06 shift altgr
+section 0x07
+6 0x07 shift
+asciicircum 0x07 altgr
+fiveeighths 0x07 shift altgr
+egrave 0x08
+7 0x08 shift
+braceleft 0x08 altgr
+seveneighths 0x08 shift altgr
+exclam 0x09
+8 0x09 shift
+bracketleft 0x09 altgr
+trademark 0x09 shift altgr
+ccedilla 0x0a
+9 0x0a shift
+braceleft 0x0a altgr
+plusminus 0x0a shift altgr
+agrave 0x0b
+0 0x0b shift
+braceright 0x0b altgr
+degree 0x0b shift altgr
+parenright 0x0c
+degree 0x0c shift
+backslash 0x0c altgr
+questiondown 0x0c shift altgr
+minus 0x0d
+underscore 0x0d shift
+dead_cedilla 0x0d altgr
+dead_ogonek 0x0d shift altgr
+a 0x10 addupper
+Greek_OMEGA 0x10 shift altgr
+z 0x11 addupper
+lstroke 0x11 altgr
+Lstroke 0x11 shift altgr
+EuroSign 0x12 altgr
+cent 0x12 shift altgr
+paragraph 0x13 altgr
+registered 0x13 shift altgr
+tslash 0x14 altgr
+Tslash 0x14 shift altgr
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+downarrow 0x16 altgr
+uparrow 0x16 shift altgr
+rightarrow 0x17 altgr
+idotless 0x17 shift altgr
+oslash 0x18 altgr
+Ooblique 0x18 shift altgr
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+dead_circumflex 0x1a
+dead_diaeresis 0x1a shift
+bracketleft 0x1a altgr
+dead_abovering 0x1a shift altgr
+dollar 0x1b
+asterisk 0x1b shift
+bracketright 0x1b altgr
+dead_macron 0x1b shift altgr
+q 0x1e addupper
+ae 0x1e altgr
+AE 0x1e shift altgr
+ssharp 0x1f altgr
+eth 0x20 altgr
+ETH 0x20 shift altgr
+dstroke 0x21 altgr
+ordfeminine 0x21 shift altgr
+eng 0x22 altgr
+ENG 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+kra 0x25 altgr
+lstroke 0x26 altgr
+Lstroke 0x26 shift altgr
+m 0x27 addupper
+dead_acute 0x27 altgr
+dead_doubleacute 0x27 shift altgr
+ugrave 0x28
+percent 0x28 shift
+dead_acute 0x28 altgr
+dead_caron 0x28 shift altgr
+twosuperior 0x29
+threesuperior 0x29 shift
+notsign 0x29 altgr
+mu 0x2b
+sterling 0x2b shift
+dead_grave 0x2b altgr
+dead_breve 0x2b shift altgr
+w 0x2c addupper
+guillemotleft 0x2c altgr
+guillemotright 0x2d altgr
+cent 0x2e altgr
+copyright 0x2e shift altgr
+leftdoublequotemark 0x2f altgr
+grave 0x2f shift altgr
+rightdoublequotemark 0x30 altgr
+comma 0x32
+question 0x32 shift
+dead_cedilla 0x32 altgr
+masculine 0x32 shift altgr
+semicolon 0x33
+period 0x33 shift
+horizconnector 0x33 altgr
+multiply 0x33 shift altgr
+colon 0x34
+slash 0x34 shift
+periodcentered 0x34 altgr
+division 0x34 shift altgr
+equal 0x35
+plus 0x35 shift
+dead_tilde 0x35 altgr
+dead_abovedot 0x35 shift altgr
+backslash 0x56 altgr
+
Index: /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/fr-ca
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/fr-ca	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/fr-ca	(revision 540)
@@ -0,0 +1,53 @@
+# Canadian French
+# By Simon Germain
+include common
+map 0xc0c
+
+backslash 0x29 altgr
+plusminus 0x2 altgr
+at 0x3 altgr
+sterling 0x4 altgr
+cent 0x5 altgr
+currency 0x6 altgr
+notsign 0x7 altgr
+bar 0x29 shift
+twosuperior 0x9 altgr
+threesuperior 0xa altgr
+onequarter 0xb altgr
+onehalf 0xc altgr
+threequarters 0xd altgr
+section 0x18 altgr
+paragraph 0x19 altgr
+bracketleft 0x1a altgr
+bracketright 0x1b altgr
+asciitilde 0x27 altgr
+braceleft 0x28 altgr
+braceright 0x2b altgr
+less 0x2b
+greater 0x2b shift
+guillemotleft 0x56
+guillemotright 0x56 shift
+degree 0x56 altgr
+mu 0x32 altgr
+eacute 0x35
+dead_acute 0x35 altgr
+dead_grave 0x28
+dead_circumflex 0x1a
+dead_circumflex 0x1a shift
+dead_cedilla 0x1b
+dead_diaeresis 0x1b shift
+exclam 0x2 shift
+quotedbl 0x3 shift
+comma 0x33
+apostrophe 0x33 shift
+period 0x34 shift
+slash 0x4 shift
+dollar 0x5 shift
+percent 0x6 shift
+question 0x7 shift
+ampersand 0x8 shift
+asterisk 0x9 shift
+parenleft 0xa shift
+parenright 0xb shift
+underscore 0xc shift
+plus 0xd shift
Index: /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/fr-ch
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/fr-ch	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/fr-ch	(revision 540)
@@ -0,0 +1,169 @@
+# rdesktop suisse-french keymap file 
+#
+#map 0x00000807
+map 0x0000100C
+include common
+#
+# Scan Code 1
+section 0x29
+degree 0x29 shift
+notsign 0x29 altgr inhibit
+#
+# Scan Code 2
+plus 0x2 shift
+brokenbar 0x02 altgr
+#
+# Scan Code 3
+quotedbl 0x03 shift
+at 0x03 altgr
+#
+# Scan Code 4
+asterisk 0x04 shift
+numbersign 0x04 altgr
+#
+# Scan Code 5
+ccedilla 0x05 shift
+onequarter 0x05 altgr inhibit
+#
+# Scan Code 6
+percent 0x06 shift
+onehalf 0x06 altgr inhibit
+#
+# Scan Code 7
+ampersand 0x07 shift
+notsign 0x07 altgr
+#
+# Scan Code 8
+slash 0x08 shift
+bar 0x08 altgr
+#
+# Scan Code 9
+parenleft 0x09 shift
+cent 0x09 altgr
+# 
+# Scan Code 10
+parenright 0x0a shift
+#
+# Scan Code 11
+equal 0x0b shift
+braceright 0x0b altgr inhibit
+#
+# Scan Code 12
+apostrophe 0x0c 
+question 0x0c shift
+dead_acute 0x0c altgr
+#
+# Scan Code 13
+dead_circumflex 0x0d
+dead_grave 0x0d shift
+dead_tilde 0x0d altgr
+#
+# Scan Code 19
+EuroSign 0x12 altgr
+#
+# Scan Code 22
+z 0x15 addupper
+#
+# Scan Code 27
+udiaeresis 0x1a shift
+egrave 0x1a 
+bracketleft 0x1a altgr
+# 
+# Scan Code 28
+dead_diaeresis 0x1b
+exclam 0x1b shift 
+bracketright 0x1b altgr
+#
+# Scan Code 40
+odiaeresis 0x27 shift
+eacute 0x27 
+#
+# Scan Code 41
+adiaeresis 0x28 shift
+agrave 0x28 
+braceleft 0x28 altgr
+#
+# Scan Code 42 (only on international keyboards)
+dollar 0x2b
+sterling 0x2b shift
+braceright 0x2b altgr
+#
+# Scan Code 45 (only on international keyboards)
+backslash 0x56 altgr
+#
+# Scan Code 46
+y 0x2c addupper
+# 
+# Scan Code 53
+comma 0x33
+semicolon 0x33 shift
+# 
+# Scan Code 54
+period 0x34
+colon 0x34 shift
+#
+# Scan Code 55
+minus 0x35 
+underscore 0x35 shift
+#
+# Suppress Windows unsupported AltGr keys
+#
+# Scan Code 17
+paragraph 0x10 altgr inhibit
+#
+# Scan Code 21
+tslash 0x14 altgr inhibit
+#
+# Scan Code 22
+leftarrow 0x15 altgr inhibit
+#
+# Scan Code 23
+downarrow 0x16 altgr inhibit
+#
+# Scan Code 24
+rightarrow 0x17 altgr inhibit
+#
+# Scan Code 25
+oslash 0x18 altgr inhibit
+#
+# Scan Code 26
+thorn 0x19 altgr inhibit
+#
+# Scan Code 31
+ae 0x1e altgr inhibit
+#
+# Scan Code 32
+ssharp 0x1f altgr inhibit
+#
+# Scan Code 33
+eth 0x20 altgr inhibit
+#
+# Scan Code 34
+dstroke 0x21 altgr inhibit
+#
+# Scan Code 35
+eng 0x22 altgr inhibit
+#
+# Scan Code 36
+hstroke 0x23 altgr inhibit
+#
+# Scan Code 38
+kra 0x25 altgr inhibit
+#
+# Scan Code 39
+lstroke 0x26 altgr inhibit
+#
+# Scan Code 46
+guillemotleft 0x2c altgr inhibit
+#
+# Scan Code 47
+guillemotright 0x2d altgr inhibit
+#
+# Scan Code 49
+leftdoublequotemark 0x2f altgr inhibit
+#
+# Scan Code 50
+rightdoublequotemark 0x30 altgr inhibit
+#
+# Scan Code 52
+mu 0x32 altgr inhibit
Index: /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/he
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/he	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/he	(revision 540)
@@ -0,0 +1,91 @@
+# Generated by Shlomil
+# Please send your comments and corrections to <shlomister@gmail.com>
+include common
+map 0x040D
+
+
+#
+# Top row
+#
+
+slash 0x10 altgr
+apostrophe 0x11 altgr
+hebrew_qoph 0x12 altgr
+hebrew_resh 0x13 altgr
+hebrew_aleph 0x14 altgr
+hebrew_tet 0x15 altgr
+hebrew_waw 0x16 altgr
+hebrew_finalnun 0x17 altgr
+hebrew_finalmem 0x18 altgr
+hebrew_pe 0x19 altgr
+
+#
+# Second row
+#
+
+hebrew_shin 0x1e altgr
+hebrew_dalet 0x1f altgr
+hebrew_gimel 0x20 altgr
+hebrew_kaph 0x21 altgr
+hebrew_ayin 0x22 altgr
+hebrew_yod 0x23 altgr
+hebrew_chet 0x24 altgr
+hebrew_lamed 0x25 altgr
+hebrew_finalkaph 0x26 altgr
+hebrew_finalpe 0x27 altgr
+comma 0x28 altgr
+
+#
+# Third row
+#
+
+hebrew_zain 0x2c altgr
+hebrew_samech 0x2d altgr
+hebrew_bet 0x2e altgr
+hebrew_he 0x2f altgr
+hebrew_nun 0x30 altgr
+hebrew_mem 0x31 altgr
+hebrew_zade 0x32 altgr
+
+hebrew_taw 0x33 altgr
+hebrew_finalzade 0x34 altgr
+period 0x35 altgr
+
+
+#
+# en-us
+#
+
+
+exclam 0x02 shift
+at 0x03 shift
+numbersign 0x04 shift
+dollar 0x05 shift
+percent 0x06 shift
+asciicircum 0x07 shift
+ampersand 0x08 shift
+asterisk 0x09 shift
+parenleft 0x0a shift
+parenright 0x0b shift
+minus 0x0c
+underscore 0x0c shift
+equal 0x0d
+plus 0x0d shift
+bracketleft 0x1a
+braceleft 0x1a shift
+bracketright 0x1b
+braceright 0x1b shift
+semicolon 0x27
+colon 0x27 shift
+apostrophe 0x28
+quotedbl 0x28 shift
+grave 0x29
+asciitilde 0x29 shift
+backslash 0x2b
+bar 0x2b shift
+comma 0x33
+less 0x33 shift
+period 0x34
+greater 0x34 shift
+slash 0x35
+question 0x35 shift
Index: /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/hr
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/hr	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/hr	(revision 540)
@@ -0,0 +1,125 @@
+# generated from XKB map hr
+include common
+map 0x41a
+exclam 0x02 shift
+asciitilde 0x02 altgr
+dead_tilde 0x02 shift altgr
+quotedbl 0x03 shift
+dead_caron 0x03 altgr
+caron 0x03 shift altgr
+numbersign 0x04 shift
+asciicircum 0x04 altgr
+dead_circumflex 0x04 shift altgr
+dollar 0x05 shift
+dead_breve 0x05 altgr
+breve 0x05 shift altgr
+percent 0x06 shift
+degree 0x06 altgr
+dead_abovering 0x06 shift altgr
+ampersand 0x07 shift
+dead_ogonek 0x07 altgr
+ogonek 0x07 shift altgr
+slash 0x08 shift
+grave 0x08 altgr
+dead_grave 0x08 shift altgr
+parenleft 0x09 shift
+dead_abovedot 0x09 altgr
+abovedot 0x09 shift altgr
+parenright 0x0a shift
+dead_acute 0x0a altgr
+apostrophe 0x0a shift altgr
+equal 0x0b shift
+dead_doubleacute 0x0b altgr
+doubleacute 0x0b shift altgr
+apostrophe 0x0c
+question 0x0c shift
+dead_diaeresis 0x0c altgr
+diaeresis 0x0c shift altgr
+plus 0x0d
+asterisk 0x0d shift
+dead_cedilla 0x0d altgr
+cedilla 0x0d shift altgr
+backslash 0x10 altgr
+Greek_OMEGA 0x10 shift altgr
+bar 0x11 altgr
+Lstroke 0x11 shift altgr
+EuroSign 0x12 altgr
+paragraph 0x13 altgr
+registered 0x13 shift altgr
+tslash 0x14 altgr
+Tslash 0x14 shift altgr
+z 0x15 addupper
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+downarrow 0x16 altgr
+uparrow 0x16 shift altgr
+rightarrow 0x17 altgr
+idotless 0x17 shift altgr
+oslash 0x18 altgr
+Ooblique 0x18 shift altgr
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+scaron 0x1a
+Scaron 0x1a shift
+division 0x1a altgr
+dead_abovering 0x1a shift altgr
+dstroke 0x1b
+Dstroke 0x1b shift
+multiply 0x1b altgr
+dead_macron 0x1b shift altgr
+ae 0x1e altgr
+AE 0x1e shift altgr
+ssharp 0x1f altgr
+section 0x1f shift altgr
+eth 0x20 altgr
+ETH 0x20 shift altgr
+bracketleft 0x21 altgr
+ordfeminine 0x21 shift altgr
+bracketright 0x22 altgr
+ENG 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+lstroke 0x25 altgr
+ampersand 0x25 shift altgr
+Lstroke 0x26 altgr
+ccaron 0x27
+Ccaron 0x27 shift
+dead_acute 0x27 altgr
+dead_doubleacute 0x27 shift altgr
+cacute 0x28
+Cacute 0x28 shift
+ssharp 0x28 altgr
+dead_caron 0x28 shift altgr
+dead_cedilla 0x29
+dead_diaeresis 0x29 shift
+notsign 0x29 altgr
+zcaron 0x2b
+Zcaron 0x2b shift
+currency 0x2b altgr
+dead_breve 0x2b shift altgr
+y 0x2c addupper
+guillemotleft 0x2c altgr
+less 0x2c shift altgr
+guillemotright 0x2d altgr
+greater 0x2d shift altgr
+cent 0x2e altgr
+copyright 0x2e shift altgr
+at 0x2f altgr
+grave 0x2f shift altgr
+braceleft 0x30 altgr
+apostrophe 0x30 shift altgr
+braceright 0x31 altgr
+section 0x32 altgr
+masculine 0x32 shift altgr
+comma 0x33
+semicolon 0x33 shift
+horizconnector 0x33 altgr
+multiply 0x33 shift altgr
+period 0x34
+colon 0x34 shift
+periodcentered 0x34 altgr
+division 0x34 shift altgr
+minus 0x35
+underscore 0x35 shift
+dead_belowdot 0x35 altgr
+dead_abovedot 0x35 shift altgr
Index: /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/hu
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/hu	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/hu	(revision 540)
@@ -0,0 +1,115 @@
+# Hungarian keyboard layout (QWERTZ)
+# Created by: The NeverGone <never@delfin.klte.hu>
+
+include common
+map 0x40e
+
+
+# AltGr keys:
+notsign 0x29 altgr
+asciitilde 0x02 altgr
+caron 0x03 altgr
+asciicircum 0x04 altgr
+breve 0x05 altgr
+degree 0x06 altgr
+ogonek 0x07 altgr
+grave 0x08 altgr
+abovedot 0x09 altgr
+acute 0x0a altgr
+doubleacute 0x0b altgr
+diaeresis 0x0c altgr
+cedilla 0x0d altgr
+backslash 0x10 altgr
+bar 0x11 altgr
+EuroSign 0x12 altgr
+Iacute 0x17 altgr
+division 0x1a altgr
+multiply 0x1b altgr
+dstroke 0x1f altgr
+Dstroke 0x20 altgr
+bracketleft 0x21 altgr
+bracketright 0x22 altgr
+iacute 0x24 altgr
+lstroke 0x25 altgr
+Lstroke 0x26 altgr
+dollar 0x27 altgr
+ssharp 0x28 altgr
+currency 0x2b altgr
+less 0x56 altgr
+greater 0x2c altgr
+numbersign 0x2d altgr
+ampersand 0x2e altgr
+at 0x2f altgr
+braceleft 0x30 altgr
+braceright 0x31 altgr
+semicolon 0x33 altgr
+asterisk 0x35 altgr
+
+
+# Shift keys:
+section 0x29 shift
+apostrophe 0x02 shift
+quotedbl 0x03 shift
+plus 0x04 shift
+exclam 0x05 shift
+percent 0x06 shift
+slash 0x07 shift
+equal 0x08 shift
+parenleft 0x09 shift
+parenright 0x0a shift
+Odiaeresis 0x0b shift
+Udiaeresis 0x0c shift
+Oacute 0x0d shift
+Z 0x15 shift
+Odoubleacute 0x1a shift
+Uacute 0x1b shift
+Eacute 0x27 shift
+Aacute 0x28 shift
+Udoubleacute 0x2b shift
+Y 0x2c shift
+question 0x33 shift
+colon 0x34 shift
+underscore 0x35 shift
+F13 0x3b shift
+F14 0x3c shift
+F15 0x3d shift
+F16 0x3e shift
+F17 0x3f shift
+F18 0x40 shift
+F19 0x41 shift
+F20 0x42 shift
+F21 0x43 shift
+F22 0x44 shift
+F23 0x57 shift
+F24 0x58 shift
+
+
+# Ctrl keys:
+F25 0x3b ctrl
+F26 0x3c ctrl
+F27 0x3d ctrl
+F28 0x3e ctrl
+F29 0x3f ctrl
+F30 0x40 ctrl
+F31 0x41 ctrl
+F32 0x42 ctrl
+F33 0x43 ctrl
+F34 0x44 ctrl
+F35 0x57 ctrl
+#NoSymbol 0x58 ctrl
+
+
+0 0x29
+odiaeresis 0x0b
+udiaeresis 0x0c
+oacute 0x0d
+z 0x15
+odoubleacute 0x1a
+uacute 0x1b
+eacute 0x27
+aacute 0x28
+udoubleacute 0x2b
+y 0x2c
+comma 0x33
+period 0x34
+minus 0x35
Index: /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/is
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/is	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/is	(revision 540)
@@ -0,0 +1,140 @@
+# 2004-03-16 Halldór Guðmundsson and Morten Lange 
+# Keyboard definition file for the Icelandic keyboard
+# to be used in rdesktop 1.3.x ( See rdesktop.org) 
+# generated from XKB map de, and changed manually
+# Location for example /usr/local/share/rdesktop/keymaps/is
+include common
+map 0x40f
+exclam 0x02 shift
+onesuperior 0x02 altgr
+exclamdown 0x02 shift altgr
+quotedbl 0x03 shift
+twosuperior 0x03 altgr
+oneeighth 0x03 shift altgr
+#section 0x04 shift
+numbersign 0x04 shift
+threesuperior 0x04 altgr
+sterling 0x04 shift altgr
+dollar 0x05 shift
+onequarter 0x05 altgr
+currency 0x05 shift altgr
+percent 0x06 shift
+onehalf 0x06 altgr
+threeeighths 0x06 shift altgr
+ampersand 0x07 shift
+threequarters 0x07 altgr
+fiveeighths 0x07 shift altgr
+slash 0x08 shift
+braceleft 0x08 altgr
+seveneighths 0x08 shift altgr
+parenleft 0x09 shift
+bracketleft 0x09 altgr
+trademark 0x09 shift altgr
+parenright 0x0a shift
+bracketright 0x0a altgr
+plusminus 0x0a shift altgr
+equal 0x0b shift
+braceright 0x0b altgr
+#ssharp 0x0c
+odiaeresis 0x0c
+#question 0x0c shift
+Odiaeresis 0x0c shift
+backslash 0x0c altgr
+questiondown 0x0c shift altgr
+#acute 0x0d
+minus  0x0d
+#dead_acute 0x0d
+#grave 0x0d shift
+#dead_grave 0x0d shift
+underscore 0x0d shift
+dead_cedilla 0x0d altgr
+dead_ogonek 0x0d shift altgr
+at 0x10 altgr
+Greek_OMEGA 0x10 shift altgr
+EuroSign 0x12 altgr
+paragraph 0x13 altgr
+registered 0x13 shift altgr
+tslash 0x14 altgr
+Tslash 0x14 shift altgr
+#z 0x15 addupper
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+downarrow 0x16 altgr
+uparrow 0x16 shift altgr
+rightarrow 0x17 altgr
+idotless 0x17 shift altgr
+oslash 0x18 altgr
+Ooblique 0x18 shift altgr
+#thorn 0x19 altgr
+#THORN 0x19 shift altgr
+#udiaeresis 0x1a
+#Udiaeresis 0x1a shift
+#dead_diaeresis 0x1a altgr
+#dead_abovering 0x1a shift altgr
+eth 0x1a 
+ETH 0x1a shift 
+apostrophe 0x1b
+question 0x1b shift
+#plus 0x1b
+#asterisk 0x1b shift
+asciitilde 0x1b altgr
+#grave 0x1b altgr
+#dead_tilde 0x1b altgr
+#dead_macron 0x1b shift altgr
+#ae 0x1e altgr
+#AE 0x1e shift altgr
+#eth 0x20 altgr
+#eth 0x20 
+#ETH 0x20 shift altgr
+#ETH 0x20 shift 
+dstroke 0x21 altgr
+ordfeminine 0x21 shift altgr
+eng 0x22 altgr
+ENG 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+kra 0x25 altgr
+#adiaeresis 0x27
+#Adiaeresis 0x27 shift
+ae 0x27 
+AE 0x27 shift 
+dead_doubleacute 0x27 altgr
+#adiaeresis 0x28
+#Adiaeresis 0x28 shift
+#dead_caron 0x28 shift altgr
+#asciicircum 0x29
+acute  0x28
+dead_acute 0x28
+#dead_circumflex 0x29
+#degree 0x29 shift
+#notsign 0x29 altgr
+plus 0x2b
+asterisk 0x2b shift
+grave 0x2b altgr
+#numbersign 0x2b
+#apostrophe 0x2b shift
+#dead_breve 0x2b shift altgr
+#y 0x2c addupper
+guillemotleft 0x2c altgr
+guillemotright 0x2d altgr
+cent 0x2e altgr
+copyright 0x2e shift altgr
+leftdoublequotemark 0x2f altgr
+rightdoublequotemark 0x30 altgr
+mu 0x32 altgr
+masculine 0x32 shift altgr
+comma 0x33
+semicolon 0x33 shift
+horizconnector 0x33 altgr
+multiply 0x33 shift altgr
+period 0x34
+colon 0x34 shift
+periodcentered 0x34 altgr
+division 0x34 shift altgr
+#minus 0x35
+#underscore 0x35 shift
+thorn 0x35 
+THORN 0x35 shift 
+dead_belowdot 0x35 altgr
+dead_abovedot 0x35 shift altgr
+
Index: /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/it
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/it	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/it	(revision 540)
@@ -0,0 +1,115 @@
+# generated from XKB map it
+include common
+map 0x410
+exclam 0x02 shift
+onesuperior 0x02 altgr
+exclamdown 0x02 shift altgr
+quotedbl 0x03 shift
+twosuperior 0x03 altgr
+oneeighth 0x03 shift altgr
+sterling 0x04 shift
+threesuperior 0x04 altgr
+dollar 0x05 shift
+onequarter 0x05 altgr
+percent 0x06 shift
+onehalf 0x06 altgr
+threeeighths 0x06 shift altgr
+ampersand 0x07 shift
+threequarters 0x07 altgr
+fiveeighths 0x07 shift altgr
+slash 0x08 shift
+braceleft 0x08 altgr
+seveneighths 0x08 shift altgr
+parenleft 0x09 shift
+trademark 0x09 shift altgr
+parenright 0x0a shift
+plusminus 0x0a shift altgr
+equal 0x0b shift
+braceright 0x0b altgr
+degree 0x0b shift altgr
+apostrophe 0x0c
+question 0x0c shift
+grave 0x0c altgr
+questiondown 0x0c shift altgr
+igrave 0x0d
+asciicircum 0x0d shift
+asciitilde 0x0d altgr
+dead_ogonek 0x0d shift altgr
+at 0x10 altgr
+Greek_OMEGA 0x10 shift altgr
+lstroke 0x11 altgr
+Lstroke 0x11 shift altgr
+EuroSign 0x12 altgr
+cent 0x12 shift altgr
+paragraph 0x13 altgr
+registered 0x13 shift altgr
+tslash 0x14 altgr
+Tslash 0x14 shift altgr
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+downarrow 0x16 altgr
+uparrow 0x16 shift altgr
+rightarrow 0x17 altgr
+idotless 0x17 shift altgr
+oslash 0x18 altgr
+Ooblique 0x18 shift altgr
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+egrave 0x1a
+eacute 0x1a shift
+bracketleft 0x1a altgr
+braceleft 0x1a shift altgr
+plus 0x1b
+asterisk 0x1b shift
+bracketright 0x1b altgr
+braceright 0x1b shift altgr
+ae 0x1e altgr
+AE 0x1e shift altgr
+ssharp 0x1f altgr
+section 0x1f shift altgr
+eth 0x20 altgr
+ETH 0x20 shift altgr
+dstroke 0x21 altgr
+ordfeminine 0x21 shift altgr
+eng 0x22 altgr
+ENG 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+kra 0x25 altgr
+lstroke 0x26 altgr
+Lstroke 0x26 shift altgr
+ograve 0x27
+ccedilla 0x27 shift
+at 0x27 altgr
+dead_doubleacute 0x27 shift altgr
+agrave 0x28
+degree 0x28 shift
+numbersign 0x28 altgr
+backslash 0x29
+bar 0x29 shift
+notsign 0x29 altgr
+ugrave 0x2b
+section 0x2b shift
+dead_grave 0x2b altgr
+dead_breve 0x2b shift altgr
+guillemotleft 0x2c altgr
+guillemotright 0x2d altgr
+cent 0x2e altgr
+copyright 0x2e shift altgr
+leftdoublequotemark 0x2f altgr
+grave 0x2f shift altgr
+rightdoublequotemark 0x30 altgr
+mu 0x32 altgr
+masculine 0x32 shift altgr
+comma 0x33
+semicolon 0x33 shift
+horizconnector 0x33 altgr
+multiply 0x33 shift altgr
+period 0x34
+colon 0x34 shift
+periodcentered 0x34 altgr
+division 0x34 shift altgr
+minus 0x35
+underscore 0x35 shift
+dead_belowdot 0x35 altgr
+dead_abovedot 0x35 shift altgr
Index: /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/ja
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/ja	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/ja	(revision 540)
@@ -0,0 +1,119 @@
+# generated from XKB map jp106
+# See OADG Technical reference for official scancodes:
+# http://www.oadg.or.jp/tosho/index.htm#techref
+include common
+map 0xe0010411
+keyboard_type 0x7
+keyboard_subtype 0x2
+keyboard_functionkeys 0xc
+exclam 0x02 shift
+kana_NU 0x02 altgr
+quotedbl 0x03 shift
+kana_FU 0x03 altgr
+numbersign 0x04 shift
+kana_A 0x04 altgr
+kana_a 0x04 shift altgr
+dollar 0x05 shift
+kana_U 0x05 altgr
+kana_u 0x05 shift altgr
+percent 0x06 shift
+kana_E 0x06 altgr
+kana_e 0x06 shift altgr
+ampersand 0x07 shift
+kana_O 0x07 altgr
+kana_o 0x07 shift altgr
+apostrophe 0x08 shift
+kana_YA 0x08 altgr
+kana_ya 0x08 shift altgr
+parenleft 0x09 shift
+kana_YU 0x09 altgr
+kana_yu 0x09 shift altgr
+parenright 0x0a shift
+kana_YO 0x0a altgr
+kana_yo 0x0a shift altgr
+asciitilde 0x0b shift
+kana_WA 0x0b altgr
+kana_WO 0x0b shift altgr
+minus 0x0c
+equal 0x0c shift
+kana_HO 0x0c altgr
+asciicircum 0x0d
+asciitilde 0x0d shift
+kana_HE 0x0d altgr
+kana_TA 0x10 altgr
+kana_TE 0x11 altgr
+kana_I 0x12 altgr
+kana_i 0x12 shift altgr
+kana_SU 0x13 altgr
+kana_KA 0x14 altgr
+kana_N 0x15 altgr
+kana_NA 0x16 altgr
+kana_NI 0x17 altgr
+kana_RA 0x18 altgr
+kana_SE 0x19 altgr
+at 0x1a
+grave 0x1a shift
+voicedsound 0x1a altgr
+bracketleft 0x1b
+braceleft 0x1b shift
+semivoicedsound 0x1b altgr
+kana_openingbracket 0x1b shift altgr
+kana_CHI 0x1e altgr
+kana_TO 0x1f altgr
+kana_SHI 0x20 altgr
+kana_HA 0x21 altgr
+kana_KI 0x22 altgr
+kana_KU 0x23 altgr
+kana_MA 0x24 altgr
+kana_NO 0x25 altgr
+kana_RI 0x26 altgr
+semicolon 0x27
+plus 0x27 shift
+kana_RE 0x27 altgr
+colon 0x28
+asterisk 0x28 shift
+kana_KE 0x28 altgr
+Zenkaku_Hankaku 0x29
+Kanji 0x29
+bracketright 0x2b
+braceright 0x2b shift
+kana_MU 0x2b altgr
+kana_closingbracket 0x2b shift altgr
+kana_TSU 0x2c altgr
+kana_tsu 0x2c shift altgr
+kana_SA 0x2d altgr
+kana_SO 0x2e altgr
+kana_HI 0x2f altgr
+kana_KO 0x30 altgr
+kana_MI 0x31 altgr
+kana_MO 0x32 altgr
+comma 0x33
+less 0x33 shift
+kana_NE 0x33 altgr
+kana_comma 0x33 shift altgr
+period 0x34
+greater 0x34 shift
+kana_RU 0x34 altgr
+kana_fullstop 0x34 shift altgr
+slash 0x35
+question 0x35 shift
+kana_ME 0x35 altgr
+kana_conjunctive 0x35 shift altgr
+Execute 0x54 shift
+backslash 0x73
+bar 0x7d shift
+underscore 0x73 shift
+Henkan_Mode 0x79
+Hiragana_Katakana 0x70 localstate
+Katakana 0x70
+Romaji 0x70
+Muhenkan 0x7b
+# Plain [Eisu_toggle/Caps_Lock] should NOT have shift
+Eisu_toggle 0x3a
+# [Eisu_toggle/Caps_Lock] key will generate Caps_Lock keysym 
+# only with shift+capslock stroke. Windows also expect this, so prefix a shift
+Caps_Lock 0x3a shift
+# Windows,Menu
+F13 0xdc
+Menu 0xdd
+#todo: Alt_R+Romaji doesnt romaji the IME (Alt_L+Romaji works)
Index: /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/ko
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/ko	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/ko	(revision 540)
@@ -0,0 +1,37 @@
+# generated from XKB map ko
+include common
+map 0xe0010412
+exclam 0x02 shift
+at 0x03 shift
+numbersign 0x04 shift
+dollar 0x05 shift
+percent 0x06 shift
+asciicircum 0x07 shift
+ampersand 0x08 shift
+asterisk 0x09 shift
+parenleft 0x0a shift
+parenright 0x0b shift
+minus 0x0c
+underscore 0x0c shift
+equal 0x0d
+plus 0x0d shift
+bracketleft 0x1a
+braceleft 0x1a shift
+bracketright 0x1b
+braceright 0x1b shift
+semicolon 0x27
+colon 0x27 shift
+apostrophe 0x28
+quotedbl 0x28 shift
+grave 0x29
+asciitilde 0x29 shift
+backslash 0x2b
+bar 0x2b shift
+comma 0x33
+less 0x33 shift
+period 0x34
+greater 0x34 shift
+slash 0x35
+question 0x35 shift
+Hangul 0xf2
+Hangul_Hanja 0xf1
Index: /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/lt
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/lt	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/lt	(revision 540)
@@ -0,0 +1,57 @@
+# generated from XKB map lt
+include common
+map 0x427
+exclam 0x02 shift
+aogonek 0x02 altgr
+Aogonek 0x02 shift altgr
+at 0x03 shift
+ccaron 0x03 altgr
+Ccaron 0x03 shift altgr
+numbersign 0x04 shift
+eogonek 0x04 altgr
+Eogonek 0x04 shift altgr
+dollar 0x05 shift
+eabovedot 0x05 altgr
+Eabovedot 0x05 shift altgr
+percent 0x06 shift
+iogonek 0x06 altgr
+Iogonek 0x06 shift altgr
+asciicircum 0x07 shift
+scaron 0x07 altgr
+Scaron 0x07 shift altgr
+ampersand 0x08 shift
+uogonek 0x08 altgr
+Uogonek 0x08 shift altgr
+asterisk 0x09 shift
+umacron 0x09 altgr
+Umacron 0x09 shift altgr
+parenleft 0x0a shift
+doublelowquotemark 0x0a altgr
+parenright 0x0b shift
+leftdoublequotemark 0x0b altgr
+minus 0x0c
+underscore 0x0c shift
+equal 0x0d
+plus 0x0d shift
+zcaron 0x0d altgr
+Zcaron 0x0d shift altgr
+bracketleft 0x1a
+braceleft 0x1a shift
+bracketright 0x1b
+braceright 0x1b shift
+semicolon 0x27
+colon 0x27 shift
+apostrophe 0x28
+quotedbl 0x28 shift
+grave 0x29
+asciitilde 0x29 shift
+backslash 0x2b
+bar 0x2b shift
+comma 0x33
+less 0x33 shift
+period 0x34
+greater 0x34 shift
+slash 0x35
+question 0x35 shift
+endash 0x56
+EuroSign 0x56 shift
Index: /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/lv
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/lv	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/lv	(revision 540)
@@ -0,0 +1,128 @@
+# generated from XKB map lv
+include common
+map 0x426
+exclam 0x02 shift
+onesuperior 0x02 altgr
+exclamdown 0x02 shift altgr
+at 0x03 shift
+twosuperior 0x03 altgr
+oneeighth 0x03 shift altgr
+numbersign 0x04 shift
+threesuperior 0x04 altgr
+sterling 0x04 shift altgr
+dollar 0x05 shift
+EuroSign 0x05 altgr
+cent 0x05 shift altgr
+percent 0x06 shift
+onehalf 0x06 altgr
+threeeighths 0x06 shift altgr
+asciicircum 0x07 shift
+threequarters 0x07 altgr
+fiveeighths 0x07 shift altgr
+ampersand 0x08 shift
+braceleft 0x08 altgr
+seveneighths 0x08 shift altgr
+asterisk 0x09 shift
+bracketleft 0x09 altgr
+trademark 0x09 shift altgr
+parenleft 0x0a shift
+bracketright 0x0a altgr
+plusminus 0x0a shift altgr
+parenright 0x0b shift
+braceright 0x0b altgr
+degree 0x0b shift altgr
+minus 0x0c
+underscore 0x0c shift
+backslash 0x0c altgr
+questiondown 0x0c shift altgr
+equal 0x0d
+plus 0x0d shift
+dead_cedilla 0x0d altgr
+dead_ogonek 0x0d shift altgr
+at 0x10 altgr
+Greek_OMEGA 0x10 shift altgr
+lstroke 0x11 altgr
+Lstroke 0x11 shift altgr
+emacron 0x12 altgr
+Emacron 0x12 shift altgr
+rcedilla 0x13 altgr
+Rcedilla 0x13 shift altgr
+tslash 0x14 altgr
+Tslash 0x14 shift altgr
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+umacron 0x16 altgr
+Umacron 0x16 shift altgr
+imacron 0x17 altgr
+Imacron 0x17 shift altgr
+omacron 0x18 altgr
+Omacron 0x18 shift altgr
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+bracketleft 0x1a
+braceleft 0x1a shift
+dead_diaeresis 0x1a altgr
+dead_abovering 0x1a shift altgr
+bracketright 0x1b
+braceright 0x1b shift
+dead_tilde 0x1b altgr
+dead_macron 0x1b shift altgr
+ISO_Next_Group 0x1c shift
+amacron 0x1e altgr
+Amacron 0x1e shift altgr
+scaron 0x1f altgr
+Scaron 0x1f shift altgr
+eth 0x20 altgr
+ETH 0x20 shift altgr
+dstroke 0x21 altgr
+ordfeminine 0x21 shift altgr
+gcedilla 0x22 altgr
+Gcedilla 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+kcedilla 0x25 altgr
+Kcedilla 0x25 shift altgr
+lcedilla 0x26 altgr
+Lcedilla 0x26 shift altgr
+semicolon 0x27
+colon 0x27 shift
+dead_acute 0x27 altgr
+dead_doubleacute 0x27 shift altgr
+apostrophe 0x28
+quotedbl 0x28 shift
+leftdoublequotemark 0x28 altgr
+doublelowquotemark 0x28 shift altgr
+grave 0x29
+asciitilde 0x29 shift
+notsign 0x29 altgr
+backslash 0x2b
+bar 0x2b shift
+dead_grave 0x2b altgr
+dead_breve 0x2b shift altgr
+zcaron 0x2c altgr
+Zcaron 0x2c shift altgr
+guillemotright 0x2d altgr
+greater 0x2d shift altgr
+ccaron 0x2e altgr
+Ccaron 0x2e shift altgr
+leftdoublequotemark 0x2f altgr
+grave 0x2f shift altgr
+rightdoublequotemark 0x30 altgr
+apostrophe 0x30 shift altgr
+ncedilla 0x31 altgr
+Ncedilla 0x31 shift altgr
+mu 0x32 altgr
+masculine 0x32 shift altgr
+comma 0x33
+less 0x33 shift
+horizconnector 0x33 altgr
+multiply 0x33 shift altgr
+period 0x34
+greater 0x34 shift
+periodcentered 0x34 altgr
+division 0x34 shift altgr
+slash 0x35
+question 0x35 shift
+dead_belowdot 0x35 altgr
+dead_abovedot 0x35 shift altgr
+nobreakspace 0x39 altgr
Index: /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/mk
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/mk	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/mk	(revision 540)
@@ -0,0 +1,101 @@
+# generated from XKB map mk
+include common
+map 0x42f
+exclam 0x02 shift
+at 0x03 shift
+doublelowquotemark 0x03 shift altgr
+numbersign 0x04 shift
+leftdoublequotemark 0x04 shift altgr
+dollar 0x05 shift
+percent 0x06 shift
+asciicircum 0x07 shift
+ampersand 0x08 shift
+asterisk 0x09 shift
+parenleft 0x0a shift
+parenright 0x0b shift
+minus 0x0c
+underscore 0x0c shift
+equal 0x0d
+plus 0x0d shift
+Cyrillic_lje 0x10 altgr
+Cyrillic_LJE 0x10 shift altgr
+Cyrillic_nje 0x11 altgr
+Cyrillic_NJE 0x11 shift altgr
+Cyrillic_ie 0x12 altgr
+Cyrillic_IE 0x12 shift altgr
+Cyrillic_er 0x13 altgr
+Cyrillic_ER 0x13 shift altgr
+Cyrillic_te 0x14 altgr
+Cyrillic_TE 0x14 shift altgr
+Macedonia_dse 0x15 altgr
+Macedonia_DSE 0x15 shift altgr
+Cyrillic_u 0x16 altgr
+Cyrillic_U 0x16 shift altgr
+Cyrillic_i 0x17 altgr
+Cyrillic_I 0x17 shift altgr
+Cyrillic_o 0x18 altgr
+Cyrillic_O 0x18 shift altgr
+Cyrillic_pe 0x19 altgr
+Cyrillic_PE 0x19 shift altgr
+bracketleft 0x1a
+braceleft 0x1a shift
+Cyrillic_sha 0x1a altgr
+Cyrillic_SHA 0x1a shift altgr
+bracketright 0x1b
+braceright 0x1b shift
+Macedonia_gje 0x1b altgr
+Macedonia_GJE 0x1b shift altgr
+Cyrillic_a 0x1e altgr
+Cyrillic_A 0x1e shift altgr
+Cyrillic_es 0x1f altgr
+Cyrillic_ES 0x1f shift altgr
+Cyrillic_de 0x20 altgr
+Cyrillic_DE 0x20 shift altgr
+Cyrillic_ef 0x21 altgr
+Cyrillic_EF 0x21 shift altgr
+Cyrillic_ghe 0x22 altgr
+Cyrillic_GHE 0x22 shift altgr
+Cyrillic_ha 0x23 altgr
+Cyrillic_HA 0x23 shift altgr
+Cyrillic_je 0x24 altgr
+Cyrillic_JE 0x24 shift altgr
+Cyrillic_ka 0x25 altgr
+Cyrillic_KA 0x25 shift altgr
+Cyrillic_el 0x26 altgr
+Cyrillic_EL 0x26 shift altgr
+semicolon 0x27
+colon 0x27 shift
+Cyrillic_che 0x27 altgr
+Cyrillic_CHE 0x27 shift altgr
+apostrophe 0x28
+quotedbl 0x28 shift
+Macedonia_kje 0x28 altgr
+Macedonia_KJE 0x28 shift altgr
+grave 0x29
+asciitilde 0x29 shift
+backslash 0x2b
+bar 0x2b shift
+Cyrillic_zhe 0x2b altgr
+Cyrillic_ZHE 0x2b shift altgr
+Cyrillic_ze 0x2c altgr
+Cyrillic_ZE 0x2c shift altgr
+Cyrillic_dzhe 0x2d altgr
+Cyrillic_DZHE 0x2d shift altgr
+Cyrillic_tse 0x2e altgr
+Cyrillic_TSE 0x2e shift altgr
+Cyrillic_ve 0x2f altgr
+Cyrillic_VE 0x2f shift altgr
+Cyrillic_be 0x30 altgr
+Cyrillic_BE 0x30 shift altgr
+Cyrillic_en 0x31 altgr
+Cyrillic_EN 0x31 shift altgr
+Cyrillic_em 0x32 altgr
+Cyrillic_EM 0x32 shift altgr
+comma 0x33
+less 0x33 shift
+semicolon 0x33 shift altgr
+period 0x34
+greater 0x34 shift
+colon 0x34 shift altgr
+slash 0x35
+question 0x35 shift
Index: /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/modifiers
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/modifiers	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/modifiers	(revision 540)
@@ -0,0 +1,18 @@
+Shift_R 0x36
+Shift_L 0x2a
+
+Alt_R 0xb8
+Mode_switch 0xb8
+ISO_Level3_Shift 0xb8
+
+Alt_L 0x38
+
+Control_R 0x9d
+Control_L 0x1d
+
+# Translate Meta, Super and Hyper to Windows keys. 
+# This is hardcoded. See documentation for details. 
+
+# Translate Menu to the Windows Application key. 
+# This one does not work either. 
+Menu 0xdd
Index: /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/nl
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/nl	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/nl	(revision 540)
@@ -0,0 +1,60 @@
+# Dutch (Netherlands)
+include common
+map 0x413
+
+exclam 0x02 shift
+onesuperior 0x02 altgr
+quotebl 0x03 shift
+twosuperior 0x03 altgr
+numbersign 0x04 shift
+threesuperior 0x04 altgr
+dollar 0x05 shift
+onequarter 0x05 altgr
+percent 0x06 shift
+onehalf 0x06 altgr
+ampersand 0x07 shift
+threequarters 0x07 altgr
+underscore 0x08 shift
+sterling 0x08 altgr
+parenleft 0x09 shift
+braceleft 0x09 altgr
+parenright 0x0a shift
+braceright 0x0a altgr
+apostrophe 0x0b shift
+slash 0x0c
+question 0x0c shift
+backslash 0x0c altgr
+degree 0x0d
+dead_tilde 0x0d shift
+dead_cedilla 0x0d altgr
+EuroSign 0x12 altgr
+paragraph 0x13 altgr
+dead_diaeresis 0x1a
+dead_circumflex 0x1a shift
+asterisk 0x1b
+bar 0x1b shift
+ssharp 0x1f altgr
+plus 0x27
+plusminus 0x27 shift
+dead_acute 0x28
+dead_grave 0x28 shift
+at 0x29
+section 0x29 shift
+notsign 0x29 altgr
+less 0x2b
+greater 0x2b shift
+guillemotleft 0x2c altgr
+guillemotright 0x2d altgr
+copyright 0x2e altgr 
+mu 0x32 altgr
+comma 0x33
+semicolon 0x33 shift
+period 0x34
+colon 0x34 shift
+periodcentered 0x34 altgr
+hyphen 0x35
+equal 0x35 shift
+bracketright 0x56
+bracketleft 0x56 shift
+brokenbar 0x56 altgr
+
Index: /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/nl-be
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/nl-be	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/nl-be	(revision 540)
@@ -0,0 +1,142 @@
+# Dutch (Belgium)
+map 0x813
+include common
+ampersand 0x02
+1 0x02 shift
+bar 0x02 altgr
+exclamdown 0x02 shift altgr
+eacute 0x03
+2 0x03 shift
+at 0x03 altgr
+oneeighth 0x03 shift altgr
+quotedbl 0x04
+3 0x04 shift
+numbersign 0x04 altgr
+sterling 0x04 shift altgr
+apostrophe 0x05
+4 0x05 shift
+onequarter 0x05 altgr
+dollar 0x05 shift altgr
+parenleft 0x06
+5 0x06 shift
+onehalf 0x06 altgr
+threeeighths 0x06 shift altgr
+section 0x07
+6 0x07 shift
+asciicircum 0x07 altgr
+fiveeighths 0x07 shift altgr
+egrave 0x08
+7 0x08 shift
+braceleft 0x08 altgr
+seveneighths 0x08 shift altgr
+exclam 0x09
+8 0x09 shift
+bracketleft 0x09 altgr
+trademark 0x09 shift altgr
+ccedilla 0x0a
+9 0x0a shift
+braceleft 0x0a altgr
+plusminus 0x0a shift altgr
+agrave 0x0b
+0 0x0b shift
+braceright 0x0b altgr
+degree 0x0b shift altgr
+parenright 0x0c
+degree 0x0c shift
+backslash 0x0c altgr
+questiondown 0x0c shift altgr
+minus 0x0d
+underscore 0x0d shift
+dead_cedilla 0x0d altgr
+dead_ogonek 0x0d shift altgr
+a 0x10 addupper
+# at 0x10 altgr
+Greek_OMEGA 0x10 shift altgr
+z 0x11 addupper
+lstroke 0x11 altgr
+Lstroke 0x11 shift altgr
+EuroSign 0x12 altgr
+cent 0x12 shift altgr
+paragraph 0x13 altgr
+registered 0x13 shift altgr
+tslash 0x14 altgr
+Tslash 0x14 shift altgr
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+downarrow 0x16 altgr
+uparrow 0x16 shift altgr
+rightarrow 0x17 altgr
+idotless 0x17 shift altgr
+oslash 0x18 altgr
+Ooblique 0x18 shift altgr
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+dead_circumflex 0x1a
+dead_diaeresis 0x1a shift
+bracketleft 0x1a altgr
+dead_abovering 0x1a shift altgr
+dollar 0x1b
+asterisk 0x1b shift
+bracketright 0x1b altgr
+dead_macron 0x1b shift altgr
+q 0x1e addupper
+ae 0x1e altgr
+AE 0x1e shift altgr
+ssharp 0x1f altgr
+section 0x1f shift altgr
+eth 0x20 altgr
+ETH 0x20 shift altgr
+dstroke 0x21 altgr
+ordfeminine 0x21 shift altgr
+eng 0x22 altgr
+ENG 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+kra 0x25 altgr
+# ampersand 0x25 shift altgr
+lstroke 0x26 altgr
+Lstroke 0x26 shift altgr
+m 0x27 addupper
+dead_acute 0x27 altgr
+dead_doubleacute 0x27 shift altgr
+ugrave 0x28
+percent 0x28 shift
+dead_acute 0x28 altgr
+dead_caron 0x28 shift altgr
+twosuperior 0x29
+threesuperior 0x29 shift
+notsign 0x29 altgr
+mu 0x2b
+sterling 0x2b shift
+dead_grave 0x2b altgr
+dead_breve 0x2b shift altgr
+w 0x2c addupper
+guillemotleft 0x2c altgr
+less 0x2c shift altgr
+guillemotright 0x2d altgr
+greater 0x2d shift altgr
+cent 0x2e altgr
+copyright 0x2e shift altgr
+leftdoublequotemark 0x2f altgr
+grave 0x2f shift altgr
+rightdoublequotemark 0x30 altgr
+# apostrophe 0x30 shift altgr
+comma 0x32
+question 0x32 shift
+dead_cedilla 0x32 altgr
+masculine 0x32 shift altgr
+semicolon 0x33
+period 0x33 shift
+horizconnector 0x33 altgr
+multiply 0x33 shift altgr
+colon 0x34
+slash 0x34 shift
+periodcentered 0x34 altgr
+division 0x34 shift altgr
+equal 0x35
+plus 0x35 shift
+dead_tilde 0x35 altgr
+dead_abovedot 0x35 shift altgr
+backslash 0x56 altgr
+less 0x56 
+greater 0x56 shift
Index: /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/no
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/no	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/no	(revision 540)
@@ -0,0 +1,119 @@
+# generated from XKB map no
+include common
+map 0x414
+exclam 0x02 shift
+exclamdown 0x02 altgr
+onesuperior 0x02 shift altgr
+quotedbl 0x03 shift
+at 0x03 altgr
+twosuperior 0x03 shift altgr
+numbersign 0x04 shift
+sterling 0x04 altgr
+threesuperior 0x04 shift altgr
+currency 0x05 shift
+dollar 0x05 altgr
+onequarter 0x05 shift altgr
+percent 0x06 shift
+onehalf 0x06 altgr
+cent 0x06 shift altgr
+ampersand 0x07 shift
+yen 0x07 altgr
+fiveeighths 0x07 shift altgr
+slash 0x08 shift
+braceleft 0x08 altgr
+division 0x08 shift altgr
+parenleft 0x09 shift
+bracketleft 0x09 altgr
+guillemotleft 0x09 shift altgr
+parenright 0x0a shift
+bracketright 0x0a altgr
+guillemotright 0x0a shift altgr
+equal 0x0b shift
+braceright 0x0b altgr
+degree 0x0b shift altgr
+plus 0x0c
+question 0x0c shift
+plusminus 0x0c altgr
+questiondown 0x0c shift altgr
+backslash 0x0d
+dead_grave 0x0d shift
+dead_acute 0x0d altgr
+notsign 0x0d shift altgr
+Greek_OMEGA 0x10 shift altgr
+lstroke 0x11 altgr
+Lstroke 0x11 shift altgr
+EuroSign 0x12 altgr
+cent 0x12 shift altgr
+registered 0x13 altgr
+thorn 0x14 altgr
+THORN 0x14 shift altgr
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+downarrow 0x16 altgr
+uparrow 0x16 shift altgr
+rightarrow 0x17 altgr
+idotless 0x17 shift altgr
+oe 0x18 altgr
+OE 0x18 shift altgr
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+aring 0x1a
+Aring 0x1a shift
+dead_diaeresis 0x1a altgr
+dead_abovering 0x1a shift altgr
+dead_diaeresis 0x1b
+dead_circumflex 0x1b shift
+asciicircum 0x01b shift
+dead_tilde 0x1b altgr
+asciitilde 0x1b altgr
+dead_caron 0x1b shift altgr
+ordfeminine 0x1e altgr
+masculine 0x1e shift altgr
+ssharp 0x1f altgr
+section 0x1f shift altgr
+eth 0x20 altgr
+ETH 0x20 shift altgr
+dstroke 0x21 altgr
+ordfeminine 0x21 shift altgr
+eng 0x22 altgr
+ENG 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+kra 0x25 altgr
+lstroke 0x26 altgr
+Lstroke 0x26 shift altgr
+oslash 0x27
+Ooblique 0x27 shift
+dead_doubleacute 0x27 shift altgr
+ae 0x28
+AE 0x28 shift
+dead_caron 0x28 shift altgr
+bar 0x29
+section 0x29 shift
+brokenbar 0x29 altgr
+paragraph 0x29 shift altgr
+apostrophe 0x2b
+asterisk 0x2b shift
+multiply 0x2b shift altgr
+guillemotleft 0x2c altgr
+guillemotright 0x2d altgr
+copyright 0x2e altgr
+leftdoublequotemark 0x2f altgr
+rightdoublequotemark 0x30 altgr
+mu 0x32 altgr
+masculine 0x32 shift altgr
+comma 0x33
+semicolon 0x33 shift
+dead_cedilla 0x33 altgr
+dead_ogonek 0x33 shift altgr
+period 0x34
+colon 0x34 shift
+periodcentered 0x34 altgr
+dead_abovedot 0x34 shift altgr
+minus 0x35
+underscore 0x35 shift
+hyphen 0x35 altgr
+macron 0x35 shift altgr
+nobreakspace 0x39 altgr
+onehalf 0x56 altgr
+threequarters 0x56 shift altgr
Index: /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/pl
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/pl	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/pl	(revision 540)
@@ -0,0 +1,122 @@
+# generated from XKB map pl
+include common
+map 0x415
+exclam 0x02 shift
+onesuperior 0x02 altgr
+exclamdown 0x02 shift altgr
+at 0x03 shift
+twosuperior 0x03 altgr
+oneeighth 0x03 shift altgr
+numbersign 0x04 shift
+threesuperior 0x04 altgr
+sterling 0x04 shift altgr
+dollar 0x05 shift
+onequarter 0x05 altgr
+percent 0x06 shift
+onehalf 0x06 altgr
+threeeighths 0x06 shift altgr
+asciicircum 0x07 shift
+threequarters 0x07 altgr
+fiveeighths 0x07 shift altgr
+ampersand 0x08 shift
+braceleft 0x08 altgr
+seveneighths 0x08 shift altgr
+asterisk 0x09 shift
+bracketleft 0x09 altgr
+trademark 0x09 shift altgr
+parenleft 0x0a shift
+bracketright 0x0a altgr
+plusminus 0x0a shift altgr
+parenright 0x0b shift
+braceright 0x0b altgr
+degree 0x0b shift altgr
+minus 0x0c
+underscore 0x0c shift
+backslash 0x0c altgr
+questiondown 0x0c shift altgr
+equal 0x0d
+plus 0x0d shift
+dead_cedilla 0x0d altgr
+dead_ogonek 0x0d shift altgr
+Greek_OMEGA 0x10 shift altgr
+lstroke 0x11 altgr
+Lstroke 0x11 shift altgr
+eogonek 0x12 altgr
+Eogonek 0x12 shift altgr
+paragraph 0x13 altgr
+registered 0x13 shift altgr
+tslash 0x14 altgr
+Tslash 0x14 shift altgr
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+EuroSign 0x16 altgr
+uparrow 0x16 shift altgr
+rightarrow 0x17 altgr
+idotless 0x17 shift altgr
+oacute 0x18 altgr
+Oacute 0x18 shift altgr
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+bracketleft 0x1a
+braceleft 0x1a shift
+dead_diaeresis 0x1a altgr
+dead_abovering 0x1a shift altgr
+bracketright 0x1b
+braceright 0x1b shift
+dead_tilde 0x1b altgr
+dead_macron 0x1b shift altgr
+aogonek 0x1e altgr
+Aogonek 0x1e shift altgr
+sacute 0x1f altgr
+Sacute 0x1f shift altgr
+eth 0x20 altgr
+ETH 0x20 shift altgr
+dstroke 0x21 altgr
+ordfeminine 0x21 shift altgr
+eng 0x22 altgr
+ENG 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+kra 0x25 altgr
+lstroke 0x26 altgr
+Lstroke 0x26 shift altgr
+semicolon 0x27
+colon 0x27 shift
+dead_acute 0x27 altgr
+dead_doubleacute 0x27 shift altgr
+apostrophe 0x28
+quotedbl 0x28 shift
+dead_circumflex 0x28 altgr
+dead_caron 0x28 shift altgr
+grave 0x29
+asciitilde 0x29 shift
+notsign 0x29 altgr
+backslash 0x2b
+bar 0x2b shift
+dead_grave 0x2b altgr
+dead_breve 0x2b shift altgr
+zabovedot 0x2c altgr
+Zabovedot 0x2c shift altgr
+zacute 0x2d altgr
+Zacute 0x2d shift altgr
+cacute 0x2e altgr
+Cacute 0x2e shift altgr
+leftdoublequotemark 0x2f altgr
+grave 0x2f shift altgr
+rightdoublequotemark 0x30 altgr
+nacute 0x31 altgr
+Nacute 0x31 shift altgr
+mu 0x32 altgr
+masculine 0x32 shift altgr
+comma 0x33
+less 0x33 shift
+horizconnector 0x33 altgr
+multiply 0x33 shift altgr
+period 0x34
+greater 0x34 shift
+periodcentered 0x34 altgr
+division 0x34 shift altgr
+slash 0x35
+question 0x35 shift
+dead_belowdot 0x35 altgr
+dead_abovedot 0x35 shift altgr
Index: /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/pt
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/pt	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/pt	(revision 540)
@@ -0,0 +1,113 @@
+# generated from XKB map pt
+include common
+map 0x816
+exclam 0x02 shift
+onesuperior 0x02 altgr
+exclamdown 0x02 shift altgr
+quotedbl 0x03 shift
+at 0x03 altgr
+oneeighth 0x03 shift altgr
+numbersign 0x04 shift
+sterling 0x04 altgr
+dollar 0x05 shift
+section 0x05 altgr
+percent 0x06 shift
+onehalf 0x06 altgr
+threeeighths 0x06 shift altgr
+ampersand 0x07 shift
+threequarters 0x07 altgr
+fiveeighths 0x07 shift altgr
+slash 0x08 shift
+braceleft 0x08 altgr
+seveneighths 0x08 shift altgr
+parenleft 0x09 shift
+bracketleft 0x09 altgr
+trademark 0x09 shift altgr
+parenright 0x0a shift
+bracketright 0x0a altgr
+plusminus 0x0a shift altgr
+equal 0x0b shift
+braceright 0x0b altgr
+degree 0x0b shift altgr
+apostrophe 0x0c
+question 0x0c shift
+backslash 0x0c altgr
+questiondown 0x0c shift altgr
+guillemotleft 0x0d
+guillemotright 0x0d shift
+dead_cedilla 0x0d altgr
+dead_ogonek 0x0d shift altgr
+Greek_OMEGA 0x10 shift altgr
+lstroke 0x11 altgr
+Lstroke 0x11 shift altgr
+EuroSign 0x12 altgr
+cent 0x12 shift altgr
+paragraph 0x13 altgr
+registered 0x13 shift altgr
+tslash 0x14 altgr
+Tslash 0x14 shift altgr
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+downarrow 0x16 altgr
+uparrow 0x16 shift altgr
+rightarrow 0x17 altgr
+idotless 0x17 shift altgr
+oslash 0x18 altgr
+Ooblique 0x18 shift altgr
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+plus 0x1a
+asterisk 0x1a shift
+dead_diaeresis 0x1a altgr
+dead_abovering 0x1a shift altgr
+dead_acute 0x1b
+dead_grave 0x1b shift
+dead_tilde 0x1b altgr
+dead_macron 0x1b shift altgr
+ae 0x1e altgr
+AE 0x1e shift altgr
+ssharp 0x1f altgr
+eth 0x20 altgr
+ETH 0x20 shift altgr
+dstroke 0x21 altgr
+ordfeminine 0x21 shift altgr
+eng 0x22 altgr
+ENG 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+kra 0x25 altgr
+lstroke 0x26 altgr
+Lstroke 0x26 shift altgr
+ccedilla 0x27
+Ccedilla 0x27 shift
+dead_doubleacute 0x27 shift altgr
+masculine 0x28
+ordfeminine 0x28 shift
+dead_circumflex 0x28 altgr
+dead_caron 0x28 shift altgr
+backslash 0x29
+bar 0x29 shift
+notsign 0x29 altgr
+dead_tilde 0x2b
+dead_circumflex 0x2b shift
+dead_breve 0x2b shift altgr
+less 0x56
+greater 0x56 shift
+cent 0x2e altgr
+copyright 0x2e shift altgr
+leftdoublequotemark 0x2f altgr
+grave 0x2f shift altgr
+rightdoublequotemark 0x30 altgr
+mu 0x32 altgr
+comma 0x33
+semicolon 0x33 shift
+horizconnector 0x33 altgr
+multiply 0x33 shift altgr
+period 0x34
+colon 0x34 shift
+periodcentered 0x34 altgr
+division 0x34 shift altgr
+minus 0x35
+underscore 0x35 shift
+dead_belowdot 0x35 altgr
+dead_abovedot 0x35 shift altgr
Index: /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/pt-br
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/pt-br	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/pt-br	(revision 540)
@@ -0,0 +1,69 @@
+# generated from XKB map br
+include common
+map 0x416
+exclam 0x02 shift
+onesuperior 0x02 altgr
+exclamdown 0x02 shift altgr
+at 0x03 shift
+twosuperior 0x03 altgr
+onehalf 0x03 shift altgr
+numbersign 0x04 shift
+threesuperior 0x04 altgr
+threequarters 0x04 shift altgr
+dollar 0x05 shift
+sterling 0x05 altgr
+onequarter 0x05 shift altgr
+percent 0x06 shift
+cent 0x06 altgr
+dead_diaeresis 0x07 shift
+notsign 0x07 altgr
+diaeresis 0x07 shift altgr
+ampersand 0x08 shift
+braceleft 0x08 altgr
+asterisk 0x09 shift
+bracketleft 0x09 altgr
+parenleft 0x0a shift
+bracketright 0x0a altgr
+parenright 0x0b shift
+braceright 0x0b altgr
+minus 0x0c
+underscore 0x0c shift
+backslash 0x0c altgr
+equal 0x0d
+plus 0x0d shift
+section 0x0d altgr
+EuroSign 0x12 altgr
+registered 0x13 altgr
+dead_acute 0x1a
+dead_grave 0x1a shift
+acute 0x1a altgr
+grave 0x1a shift altgr
+bracketleft 0x1b
+braceleft 0x1b shift
+ordfeminine 0x1b altgr
+ccedilla 0x27
+Ccedilla 0x27 shift
+dead_tilde 0x28
+dead_circumflex 0x28 shift
+asciitilde 0x28 altgr
+asciicircum 0x28 shift altgr
+apostrophe 0x29
+quotedbl 0x29 shift
+bracketright 0x2b
+braceright 0x2b shift
+masculine 0x2b altgr
+copyright 0x2e altgr
+mu 0x32 altgr
+comma 0x33
+less 0x33 shift
+period 0x34
+greater 0x34 shift
+semicolon 0x35
+colon 0x35 shift
+comma 0x53 numlock
+backslash 0x56
+bar 0x56 shift
+slash 0x73
+question 0x73 shift
+degree 0x73 altgr
+KP_Decimal 0x34
Index: /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/ru
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/ru	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/ru	(revision 540)
@@ -0,0 +1,109 @@
+# generated from XKB map ru
+include common
+map 0x419
+exclam 0x02 shift
+at 0x03 shift
+quotedbl 0x03 shift altgr
+numbersign 0x04 shift
+dollar 0x05 shift
+asterisk 0x05 shift altgr
+percent 0x06 shift
+colon 0x06 shift altgr
+asciicircum 0x07 shift
+comma 0x07 shift altgr
+ampersand 0x08 shift
+period 0x08 shift altgr
+asterisk 0x09 shift
+semicolon 0x09 shift altgr
+parenleft 0x0a shift
+parenright 0x0b shift
+minus 0x0c
+underscore 0x0c shift
+equal 0x0d
+plus 0x0d shift
+Cyrillic_shorti 0x10 altgr
+Cyrillic_SHORTI 0x10 shift altgr
+Cyrillic_tse 0x11 altgr
+Cyrillic_TSE 0x11 shift altgr
+Cyrillic_u 0x12 altgr
+Cyrillic_U 0x12 shift altgr
+Cyrillic_ka 0x13 altgr
+Cyrillic_KA 0x13 shift altgr
+Cyrillic_ie 0x14 altgr
+Cyrillic_IE 0x14 shift altgr
+Cyrillic_en 0x15 altgr
+Cyrillic_EN 0x15 shift altgr
+Cyrillic_ghe 0x16 altgr
+Cyrillic_GHE 0x16 shift altgr
+Cyrillic_sha 0x17 altgr
+Cyrillic_SHA 0x17 shift altgr
+Cyrillic_shcha 0x18 altgr
+Cyrillic_SHCHA 0x18 shift altgr
+Cyrillic_ze 0x19 altgr
+Cyrillic_ZE 0x19 shift altgr
+bracketleft 0x1a
+braceleft 0x1a shift
+Cyrillic_ha 0x1a altgr
+Cyrillic_HA 0x1a shift altgr
+bracketright 0x1b
+braceright 0x1b shift
+Cyrillic_hardsign 0x1b altgr
+Cyrillic_HARDSIGN 0x1b shift altgr
+Cyrillic_ef 0x1e altgr
+Cyrillic_EF 0x1e shift altgr
+Cyrillic_yeru 0x1f altgr
+Cyrillic_YERU 0x1f shift altgr
+Cyrillic_ve 0x20 altgr
+Cyrillic_VE 0x20 shift altgr
+Cyrillic_a 0x21 altgr
+Cyrillic_A 0x21 shift altgr
+Cyrillic_pe 0x22 altgr
+Cyrillic_PE 0x22 shift altgr
+Cyrillic_er 0x23 altgr
+Cyrillic_ER 0x23 shift altgr
+Cyrillic_o 0x24 altgr
+Cyrillic_O 0x24 shift altgr
+Cyrillic_el 0x25 altgr
+Cyrillic_EL 0x25 shift altgr
+Cyrillic_de 0x26 altgr
+Cyrillic_DE 0x26 shift altgr
+semicolon 0x27
+colon 0x27 shift
+Cyrillic_zhe 0x27 altgr
+Cyrillic_ZHE 0x27 shift altgr
+apostrophe 0x28
+quotedbl 0x28 shift
+Cyrillic_e 0x28 altgr
+Cyrillic_E 0x28 shift altgr
+grave 0x29
+asciitilde 0x29 shift
+Cyrillic_io 0x29 altgr
+Cyrillic_IO 0x29 shift altgr
+backslash 0x2b
+bar 0x2b shift
+Cyrillic_ya 0x2c altgr
+Cyrillic_YA 0x2c shift altgr
+Cyrillic_che 0x2d altgr
+Cyrillic_CHE 0x2d shift altgr
+Cyrillic_es 0x2e altgr
+Cyrillic_ES 0x2e shift altgr
+Cyrillic_em 0x2f altgr
+Cyrillic_EM 0x2f shift altgr
+Cyrillic_i 0x30 altgr
+Cyrillic_I 0x30 shift altgr
+Cyrillic_te 0x31 altgr
+Cyrillic_TE 0x31 shift altgr
+Cyrillic_softsign 0x32 altgr
+Cyrillic_SOFTSIGN 0x32 shift altgr
+comma 0x33
+less 0x33 shift
+Cyrillic_be 0x33 altgr
+Cyrillic_BE 0x33 shift altgr
+period 0x34
+greater 0x34 shift
+Cyrillic_yu 0x34 altgr
+Cyrillic_YU 0x34 shift altgr
+slash 0x35
+question 0x35 shift
+slash 0x56 altgr
+bar 0x56 shift altgr
Index: /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/sl
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/sl	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/sl	(revision 540)
@@ -0,0 +1,110 @@
+# generated from XKB map sl
+include common
+map 0x424
+exclam 0x02 shift
+asciitilde 0x02 altgr
+dead_tilde 0x02 shift altgr
+quotedbl 0x03 shift
+dead_caron 0x03 altgr
+caron 0x03 shift altgr
+numbersign 0x04 shift
+asciicircum 0x04 altgr
+dead_circumflex 0x04 shift altgr
+dollar 0x05 shift
+dead_breve 0x05 altgr
+breve 0x05 shift altgr
+percent 0x06 shift
+degree 0x06 altgr
+dead_abovering 0x06 shift altgr
+ampersand 0x07 shift
+dead_ogonek 0x07 altgr
+ogonek 0x07 shift altgr
+slash 0x08 shift
+grave 0x08 altgr
+dead_grave 0x08 shift altgr
+parenleft 0x09 shift
+dead_abovedot 0x09 altgr
+abovedot 0x09 shift altgr
+parenright 0x0a shift
+dead_acute 0x0a altgr
+equal 0x0b shift
+dead_doubleacute 0x0b altgr
+doubleacute 0x0b shift altgr
+apostrophe 0x0c
+question 0x0c shift
+dead_diaeresis 0x0c altgr
+diaeresis 0x0c shift altgr
+plus 0x0d
+asterisk 0x0d shift
+dead_cedilla 0x0d altgr
+cedilla 0x0d shift altgr
+backslash 0x10 altgr
+Greek_OMEGA 0x10 shift altgr
+bar 0x11 altgr
+Lstroke 0x11 shift altgr
+EuroSign 0x12 altgr
+paragraph 0x13 altgr
+registered 0x13 shift altgr
+tslash 0x14 altgr
+Tslash 0x14 shift altgr
+z 0x15 addupper
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+downarrow 0x16 altgr
+uparrow 0x16 shift altgr
+rightarrow 0x17 altgr
+idotless 0x17 shift altgr
+oslash 0x18 altgr
+Ooblique 0x18 shift altgr
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+scaron 0x1a
+Scaron 0x1a shift
+division 0x1a altgr
+dstroke 0x1b
+Dstroke 0x1b shift
+multiply 0x1b altgr
+dead_macron 0x1b shift altgr
+ae 0x1e altgr
+AE 0x1e shift altgr
+ssharp 0x1f altgr
+section 0x1f shift altgr
+eth 0x20 altgr
+ETH 0x20 shift altgr
+bracketleft 0x21 altgr
+ordfeminine 0x21 shift altgr
+bracketright 0x22 altgr
+ENG 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+lstroke 0x25 altgr
+Lstroke 0x26 altgr
+ccaron 0x27
+Ccaron 0x27 shift
+cacute 0x28
+Cacute 0x28 shift
+ssharp 0x28 altgr
+dead_cedilla 0x29
+notsign 0x29 altgr
+zcaron 0x2b
+Zcaron 0x2b shift
+currency 0x2b altgr
+y 0x2c addupper
+guillemotleft 0x2c altgr
+guillemotright 0x2d altgr
+cent 0x2e altgr
+copyright 0x2e shift altgr
+at 0x2f altgr
+braceleft 0x30 altgr
+braceright 0x31 altgr
+section 0x32 altgr
+masculine 0x32 shift altgr
+comma 0x33
+semicolon 0x33 shift
+horizconnector 0x33 altgr
+period 0x34
+colon 0x34 shift
+periodcentered 0x34 altgr
+minus 0x35
+underscore 0x35 shift
+dead_belowdot 0x35 altgr
Index: /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/sv
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/sv	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/sv	(revision 540)
@@ -0,0 +1,80 @@
+map 0x0000041d
+include common
+
+#
+# Top row
+#
+section 0x29
+onehalf 0x29 shift
+
+# 1
+exclam 0x2 shift
+
+# 2
+quotedbl 0x3 shift
+at 0x3 altgr
+
+# 3
+numbersign 0x4 shift
+sterling 0x4 altgr
+# 4
+currency 0x5 shift
+dollar 0x5 altgr
+# 5
+percent 0x6 shift
+# 6
+ampersand 0x7 shift
+# 7
+slash 0x8 shift
+braceleft 0x8 altgr
+# 8
+parenleft 0x9 shift
+bracketleft 0x9 altgr
+# 9
+parenright 0xa shift
+bracketright 0xa altgr
+# 0
+equal 0xb shift
+braceright 0xb altgr
+
+plus 0xc
+question 0xc shift
+backslash 0xc altgr
+
+dead_acute 0xd
+dead_grave 0xd shift
+
+#
+# QWERTY first row
+#
+EuroSign 0x12 altgr
+aring 0x1a 
+Aring 0x1a shift
+dead_diaeresis 0x1b 
+dead_circumflex 0x1b shift
+dead_tilde 0x1b altgr
+
+#
+# QWERTY second row
+#
+odiaeresis 0x27 
+Odiaeresis 0x27 shift
+adiaeresis 0x28 
+Adiaeresis 0x28 shift
+apostrophe 0x2b
+asterisk 0x2b shift
+
+#
+# QWERTY third row
+#
+less 0x56
+greater 0x56 shift
+bar 0x56 altgr
+mu 0x32 altgr
+comma 0x33
+semicolon 0x33 shift
+period 0x34
+colon 0x34 shift
+minus 0x35
+underscore 0x35 shift
+
Index: /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/th
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/th	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/th	(revision 540)
@@ -0,0 +1,131 @@
+# generated from XKB map th
+include common
+map 0x41e
+exclam 0x02 shift
+Thai_lakkhangyao 0x02 altgr
+plus 0x02 shift altgr
+at 0x03 shift
+slash 0x03 altgr
+Thai_leknung 0x03 shift altgr
+numbersign 0x04 shift
+minus 0x04 altgr
+Thai_leksong 0x04 shift altgr
+dollar 0x05 shift
+Thai_phosamphao 0x05 altgr
+Thai_leksam 0x05 shift altgr
+percent 0x06 shift
+Thai_thothung 0x06 altgr
+Thai_leksi 0x06 shift altgr
+asciicircum 0x07 shift
+Thai_sarau 0x07 altgr
+Thai_sarauu 0x07 shift altgr
+ampersand 0x08 shift
+Thai_saraue 0x08 altgr
+Thai_baht 0x08 shift altgr
+asterisk 0x09 shift
+Thai_khokhwai 0x09 altgr
+Thai_lekha 0x09 shift altgr
+parenleft 0x0a shift
+Thai_totao 0x0a altgr
+Thai_lekhok 0x0a shift altgr
+parenright 0x0b shift
+Thai_chochan 0x0b altgr
+Thai_lekchet 0x0b shift altgr
+minus 0x0c
+underscore 0x0c shift
+Thai_khokhai 0x0c altgr
+Thai_lekpaet 0x0c shift altgr
+equal 0x0d
+plus 0x0d shift
+Thai_chochang 0x0d altgr
+Thai_lekkao 0x0d shift altgr
+Thai_maiyamok 0x10 altgr
+Thai_leksun 0x10 shift altgr
+Thai_saraaimaimalai 0x11 altgr
+quotedbl 0x11 shift altgr
+Thai_saraam 0x12 altgr
+Thai_dochada 0x12 shift altgr
+Thai_phophan 0x13 altgr
+Thai_thonangmontho 0x13 shift altgr
+Thai_saraa 0x14 altgr
+Thai_thothong 0x14 shift altgr
+Thai_maihanakat 0x15 altgr
+Thai_nikhahit 0x15 shift altgr
+Thai_saraii 0x16 altgr
+Thai_maitri 0x16 shift altgr
+Thai_rorua 0x17 altgr
+Thai_nonen 0x17 shift altgr
+Thai_nonu 0x18 altgr
+Thai_paiyannoi 0x18 shift altgr
+Thai_yoyak 0x19 altgr
+Thai_yoying 0x19 shift altgr
+bracketleft 0x1a
+braceleft 0x1a shift
+Thai_bobaimai 0x1a altgr
+Thai_thothan 0x1a shift altgr
+bracketright 0x1b
+braceright 0x1b shift
+Thai_loling 0x1b altgr
+comma 0x1b shift altgr
+Thai_fofan 0x1e altgr
+Thai_ru 0x1e shift altgr
+Thai_hohip 0x1f altgr
+Thai_khorakhang 0x1f shift altgr
+Thai_kokai 0x20 altgr
+Thai_topatak 0x20 shift altgr
+Thai_dodek 0x21 altgr
+Thai_sarao 0x21 shift altgr
+Thai_sarae 0x22 altgr
+Thai_chochoe 0x22 shift altgr
+Thai_maitho 0x23 altgr
+Thai_maitaikhu 0x23 shift altgr
+Thai_maiek 0x24 altgr
+Thai_maichattawa 0x24 shift altgr
+Thai_saraaa 0x25 altgr
+Thai_sorusi 0x25 shift altgr
+Thai_sosua 0x26 altgr
+Thai_sosala 0x26 shift altgr
+semicolon 0x27
+colon 0x27 shift
+Thai_wowaen 0x27 altgr
+Thai_soso 0x27 shift altgr
+apostrophe 0x28
+quotedbl 0x28 shift
+Thai_ngongu 0x28 altgr
+period 0x28 shift altgr
+grave 0x29
+asciitilde 0x29 shift
+underscore 0x29 altgr
+percent 0x29 shift altgr
+ISO_First_Group 0x2a shift
+backslash 0x2b
+bar 0x2b shift
+Thai_khokhuat 0x2b altgr
+Thai_khokhon 0x2b shift altgr
+Thai_phophung 0x2c altgr
+parenleft 0x2c shift altgr
+Thai_popla 0x2d altgr
+parenright 0x2d shift altgr
+Thai_saraae 0x2e altgr
+Thai_choching 0x2e shift altgr
+Thai_oang 0x2f altgr
+Thai_honokhuk 0x2f shift altgr
+Thai_sarai 0x30 altgr
+Thai_phinthu 0x30 shift altgr
+Thai_sarauee 0x31 altgr
+Thai_thanthakhat 0x31 shift altgr
+Thai_thothahan 0x32 altgr
+question 0x32 shift altgr
+comma 0x33
+less 0x33 shift
+Thai_moma 0x33 altgr
+Thai_thophuthao 0x33 shift altgr
+period 0x34
+greater 0x34 shift
+Thai_saraaimaimuan 0x34 altgr
+Thai_lochula 0x34 shift altgr
+slash 0x35
+question 0x35 shift
+Thai_fofa 0x35 altgr
+Thai_lu 0x35 shift altgr
+ISO_Last_Group 0x36 shift
Index: /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/tr
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/tr	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-misc/src/main/resources/keymaps/tr	(revision 540)
@@ -0,0 +1,138 @@
+# rdesktop Turkish Q Keyboard Layout
+#
+# Modified by Umit Oztosun <umit@liqia.com> 20040328
+#
+# Modified from the original mapping file provided with rdesktop 1.3.1.
+# This version works correctly with the right X settings.
+
+include common
+map 0x41f
+
+# First row
+quotedbl 0x29
+eacute 0x29 shift
+backslash 0x29 altgr
+
+exclam 0x02 shift
+onesuperior 0x02 altgr
+exclamdown 0x02 shift altgr
+
+apostrophe 0x03 shift
+sterling 0x03 altgr
+twosuperior 0x03 shift altgr
+
+dead_circumflex 0x04 shift
+numbersign 0x04 altgr
+threesuperior 0x04 shift altgr
+
+plus 0x05 shift
+dollar 0x05 altgr
+onequarter 0x05 shift altgr
+
+percent 0x06 shift
+onehalf 0x06 altgr
+threeeighths 0x06 shift altgr
+
+ampersand 0x07 shift
+threequarters 0x07 altgr
+
+slash 0x08 shift
+braceleft 0x08 altgr
+
+parenleft 0x09 shift
+bracketleft 0x09 altgr
+
+parenright 0x0a shift
+bracketright 0x0a altgr
+plusminus 0x0a shift altgr
+
+equal 0x0b shift
+braceright 0x0b altgr
+degree 0x0b shift altgr
+
+asterisk 0x0c
+question 0x0c shift
+backslash 0x0c altgr
+questiondown 0x0c shift altgr
+
+minus 0x0d
+underscore 0x0d shift
+division 0x0d altgr
+
+at 0x10 altgr
+
+EuroSign 0x12 altgr
+
+trademark 0x14 altgr
+
+ucircumflex 0x16 altgr
+Ucircumflex 0x16 shift altgr
+
+idotless 0x17
+I 0x17 shift
+icircumflex 0x17 altgr
+Icircumflex 0x17 altgr shift
+
+ocircumflex 0x18 altgr
+Ocircumflex 0x18 shift altgr
+
+gbreve 0x1a
+Gbreve 0x1a shift
+
+udiaeresis 0x1b
+Udiaeresis 0x1b shift
+asciitilde 0x1b altgr
+dead_macron 0x1b shift altgr
+
+comma 0x2b
+semicolon 0x2b shift
+grave 0x2b altgr
+dead_grave 0x2b altgr shift
+
+# Second row
+
+acircumflex 0x1e altgr
+Acircumflex 0x1e shift altgr
+
+section 0x1f altgr
+
+ordfeminine 0x21 altgr
+
+scedilla 0x27
+Scedilla 0x27 shift
+acute 0x27 altgr
+dead_acute 0x27 shift altgr
+
+i 0x28
+Iabovedot 0x28 shift
+dead_caron 0x28 shift altgr
+
+less 0x56
+greater 0x56 shift
+bar 0x56 altgr
+brokenbar 0x56 shift altgr
+
+cent 0x2e altgr
+copyright 0x2e shift altgr
+
+leftdoublequotemark 0x2f altgr
+
+rightdoublequotemark 0x30 altgr
+
+mu 0x32 altgr
+masculine 0x32 shift altgr
+
+odiaeresis 0x33
+Odiaeresis 0x33 shift
+multiply 0x33 altgr
+
+ccedilla 0x34
+Ccedilla 0x34 shift
+periodcentered 0x34 altgr
+division 0x34 shift altgr
+
+period 0x35
+colon 0x35 shift
+dead_abovedot 0x35 altgr
+dead_abovedot 0x35 shift altgr
+
Index: /tags/quest-pre-eventrefactoring/quest-plugin-core-test/.classpath
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-plugin-core-test/.classpath	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-plugin-core-test/.classpath	(revision 540)
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/test-classes" path="src/test/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="src" output="target/classes" path="src/main/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
Index: /tags/quest-pre-eventrefactoring/quest-plugin-core-test/.project
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-plugin-core-test/.project	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-plugin-core-test/.project	(revision 540)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>quest-plugin-core-test</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
Index: /tags/quest-pre-eventrefactoring/quest-plugin-core-test/pom.xml
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-plugin-core-test/pom.xml	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-plugin-core-test/pom.xml	(revision 540)
@@ -0,0 +1,134 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>de.ugoe.cs.quest</groupId>
+	<artifactId>quest-plugin-core-test</artifactId>
+	<version>0.0.1-SNAPSHOT</version>
+	<name>quest-plugin-core-test</name>
+	<scm>
+		<url>https://quest.informatik.uni-goettingen.de/svn/quest/trunk/quest-plugin-core-test</url>
+	</scm>
+  <dependencies>
+    <dependency>
+      <groupId>de.ugoe.cs.quest</groupId>
+      <artifactId>quest-plugin-core</artifactId>
+      <version>0.0.1-SNAPSHOT</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+        <groupId>junit</groupId>
+        <artifactId>junit</artifactId>
+        <version>4.8.1</version>
+        <scope>test</scope>
+    </dependency>
+    <dependency>
+	  <groupId>junit-addons</groupId>
+	  <artifactId>junit-addons</artifactId>
+	  <version>1.4</version>
+    </dependency>
+  </dependencies>
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.eclipse.m2e</groupId>
+          <artifactId>lifecycle-mapping</artifactId>
+          <version>1.0.0</version>
+          <configuration>
+            <lifecycleMappingMetadata>
+              <pluginExecutions>
+                <pluginExecution>
+                  <pluginExecutionFilter>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-dependency-plugin</artifactId>
+                    <versionRange>[1.0.0,)</versionRange>
+                    <goals>
+                      <goal>unpack</goal>
+                    </goals>
+                  </pluginExecutionFilter>
+                  <action>
+                    <ignore/>
+                  </action>
+                </pluginExecution>
+                <pluginExecution>
+                  <pluginExecutionFilter>
+                    <groupId>org.codehaus.mojo</groupId>
+                    <artifactId>emma-maven-plugin</artifactId>
+                    <versionRange>[1.0-alpha-3,)</versionRange>
+                    <goals>
+                      <goal>emma</goal>
+                    </goals>
+                  </pluginExecutionFilter>
+                  <action>
+                    <ignore/>
+                  </action>
+                </pluginExecution>
+              </pluginExecutions>
+            </lifecycleMappingMetadata>
+          </configuration>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>2.3.2</version>
+        <configuration>
+          <source>1.6</source>
+          <target>1.6</target>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-dependency-plugin</artifactId>
+        <version>2.4</version>
+        <executions>
+          <execution>
+            <id>unpack</id>
+            <phase>process-classes</phase>
+            <goals>
+              <goal>unpack</goal>
+            </goals>
+            <configuration>
+              <artifactItems>
+                <artifactItem>
+                  <groupId>de.ugoe.cs.quest</groupId>
+                  <artifactId>quest-plugin-core</artifactId>
+                  <version>0.0.1-SNAPSHOT</version>
+                  <outputDirectory>${project.build.directory}/classes</outputDirectory>
+                </artifactItem>
+              </artifactItems>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>emma-maven-plugin</artifactId>
+        <version>1.0-alpha-3</version>
+        <inherited>true</inherited>          
+        <executions>
+          <execution>
+            <phase>process-classes</phase>
+            <goals>
+              <goal>emma</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <version>2.3.2</version>
+        <executions>
+          <execution>
+            <goals>
+              <goal>test-jar</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>
Index: /tags/quest-pre-eventrefactoring/quest-plugin-core-test/src/test/java/de/ugoe/cs/quest/plugin/PluginLoaderTest.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-plugin-core-test/src/test/java/de/ugoe/cs/quest/plugin/PluginLoaderTest.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-plugin-core-test/src/test/java/de/ugoe/cs/quest/plugin/PluginLoaderTest.java	(revision 540)
@@ -0,0 +1,207 @@
+package de.ugoe.cs.quest.plugin;
+
+import java.io.File;
+import java.util.Collection;
+
+import junitx.framework.ArrayAssert;
+
+import org.junit.*;
+import static org.junit.Assert.*;
+
+/**
+ * The class <code>PluginLoaderTest</code> contains tests for the class
+ * <code>{@link PluginLoader}</code>.
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class PluginLoaderTest {
+	
+	@Test
+	public void testPluginLoader_1() throws Exception {
+		PluginLoader loader = new PluginLoader(new File("."));
+		assertNotNull(loader);
+	}
+	
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testPluginLoader_2() throws Exception {
+		new PluginLoader(null);
+	}
+	
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testPluginLoader_3() throws Exception {
+		new PluginLoader(new File("testdata/de.ugoe.cs.quest.plugin.PluginLoaderTest/jfcmonitor.jar"));
+	}
+		
+	@Test
+	public void testCheckNameConformity_1() throws Exception {
+		PluginLoader loader = new PluginLoader(new File("."));
+		String filename = "quest-plugin-jfc-1.0.jar";
+		boolean expected = true;
+		
+		boolean result = loader.checkNameConformity(filename);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testCheckNameConformity_2() throws Exception {
+		PluginLoader loader = new PluginLoader(new File("."));
+		String filename = "quest-plugin-jf-c-1.0.jar";
+		boolean expected = false;
+		
+		boolean result = loader.checkNameConformity(filename);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testCheckNameConformity_3() throws Exception {
+		PluginLoader loader = new PluginLoader(new File("."));
+		String filename = "quest-plugin-jfc.jar";
+		boolean expected = false;
+		
+		boolean result = loader.checkNameConformity(filename);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testCheckNameConformity_4() throws Exception {
+		PluginLoader loader = new PluginLoader(new File("."));
+		String filename = "quest-plugi-jfc-1.0.jar";
+		boolean expected = false;
+		
+		boolean result = loader.checkNameConformity(filename);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testCheckNameConformity_5() throws Exception {
+		PluginLoader loader = new PluginLoader(new File("."));
+		String filename = "quest-pluginjfc-1.0.jar";
+		boolean expected = false;
+		
+		boolean result = loader.checkNameConformity(filename);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testCheckNameConformity_6() throws Exception {
+		PluginLoader loader = new PluginLoader(new File("."));
+		String filename = "quest-plugin-jfc-1-0.jar";
+		boolean expected = false;
+		
+		boolean result = loader.checkNameConformity(filename);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testCheckNameConformity_7() throws Exception {
+		PluginLoader loader = new PluginLoader(new File("."));
+		String filename = "quest-plugin-jfc-1.0.nojar";
+		boolean expected = false;
+		
+		boolean result = loader.checkNameConformity(filename);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testCheckNameConformity_8() throws Exception {
+		PluginLoader loader = new PluginLoader(new File("."));
+		String filename = null;
+		boolean expected = false;
+		
+		boolean result = loader.checkNameConformity(filename);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testCheckNameConformity_9() throws Exception {
+		PluginLoader loader = new PluginLoader(new File("."));
+		String filename = "";
+		boolean expected = false;
+		
+		boolean result = loader.checkNameConformity(filename);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testGetClassPathFromJar_1() throws Exception {
+		PluginLoader loader = new PluginLoader(new File("."));
+		File jarFile = new File("testdata/de.ugoe.cs.quest.plugin.PluginLoaderTest/jfcmonitor.jar");
+		
+		String[] expected = new String[]{ "file:" + jarFile.getParentFile().getAbsolutePath()+"/javahelperlib.jar" };
+				
+		String[] result = loader.getClassPathFromJar(jarFile);
+		
+		ArrayAssert.assertEquivalenceArrays(expected, result);
+	}
+	
+	@Test
+	public void testGetClassPathFromJar_2() throws Exception {
+		PluginLoader loader = new PluginLoader(new File("."));
+		File jarFile = new File("testdata/de.ugoe.cs.quest.plugin.PluginLoaderTest/jmi.jar");
+		
+		String[] expected = new String[]{ };
+				
+		String[] result = loader.getClassPathFromJar(jarFile);
+		
+		ArrayAssert.assertEquivalenceArrays(expected, result);
+	}
+	
+	@Test 
+	public void testLoad_1() throws Exception {
+		PluginLoader loader = new PluginLoader(new File("testdata/de.ugoe.cs.quest.plugin.PluginLoaderTest"));
+		
+		loader.load();
+		
+		Collection<QuestPlugin> plugins = loader.getPlugins();
+		
+		assertEquals(1, plugins.size());
+		QuestPlugin plugin = plugins.iterator().next();
+		assertNotNull(plugin);
+		assertEquals("Mock Plugin", plugin.getTitle());
+		assertArrayEquals(new String[]{"de.ugoe.cs.quest.plugin.mock.commands"}, plugin.getCommandPackages());
+	}
+	
+	@Test 
+	public void testLoad_2() throws Exception {
+		PluginLoader loader = new PluginLoader(new File("testdata/de.ugoe.cs.quest.plugin.PluginLoaderTestInvalid_1"));
+		
+		try {
+			loader.load();
+		} catch(PluginLoaderException e) {
+			e.getMessage().endsWith("not instance of QuestPlugin");
+		}
+	}
+	
+	@Test 
+	public void testLoad_3() throws Exception {
+		PluginLoader loader = new PluginLoader(new File("testdata/de.ugoe.cs.quest.plugin.PluginLoaderTestInvalid_2"));
+		
+		try {
+			loader.load();
+		} catch(PluginLoaderException e) {
+			e.getMessage().startsWith("No class");
+		}
+	}
+	
+	@Test 
+	public void testLoad_4() throws Exception {
+		PluginLoader loader = new PluginLoader(new File("testdata/de.ugoe.cs.quest.plugin.PluginLoaderTestInvalid_3"));
+		
+		try {
+			loader.load();
+		} catch(PluginLoaderException e) {
+			e.getMessage().endsWith("Could not access");
+		}
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-plugin-core/.classpath
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-plugin-core/.classpath	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-plugin-core/.classpath	(revision 540)
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/classes" path="src/main/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="src" output="target/test-classes" path="src/test/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
Index: /tags/quest-pre-eventrefactoring/quest-plugin-core/.project
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-plugin-core/.project	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-plugin-core/.project	(revision 540)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>quest-plugin-core</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
Index: /tags/quest-pre-eventrefactoring/quest-plugin-core/pom.xml
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-plugin-core/pom.xml	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-plugin-core/pom.xml	(revision 540)
@@ -0,0 +1,23 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>de.ugoe.cs.quest</groupId>
+	<artifactId>quest-plugin-core</artifactId>
+	<version>0.0.1-SNAPSHOT</version>
+	<name>quest-plugin-core</name>
+	<scm>
+		<url>https://quest.informatik.uni-goettingen.de/svn/quest/trunk/quest-plugin-core</url>
+	</scm>
+	<build>
+		<plugins>
+			<plugin>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>2.3.2</version>
+				<configuration>
+					<source>1.6</source>
+					<target>1.6</target>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+</project>
Index: /tags/quest-pre-eventrefactoring/quest-plugin-core/src/main/java/de/ugoe/cs/quest/plugin/PluginLoader.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-plugin-core/src/main/java/de/ugoe/cs/quest/plugin/PluginLoader.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-plugin-core/src/main/java/de/ugoe/cs/quest/plugin/PluginLoader.java	(revision 540)
@@ -0,0 +1,238 @@
+package de.ugoe.cs.quest.plugin;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.security.InvalidParameterException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.jar.JarInputStream;
+import java.util.jar.Manifest;
+
+/**
+ * <p>
+ * This class provides the functionality to load QUEST plug-ins from a
+ * pre-defined folder.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class PluginLoader {
+
+	/**
+	 * <p>
+	 * Handle of the plug-in directory.
+	 * </p>
+	 */
+	private final File pluginDir;
+
+	/**
+	 * <p>
+	 * Collection of the loaded plug-ins.
+	 * </p>
+	 */
+	private final Collection<QuestPlugin> plugins;
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new PluginLoader that can load plug-ins the
+	 * defined directory.
+	 * </p>
+	 * 
+	 * @param pluginDir
+	 *            handle of the directory; in case the handle is
+	 *            <code>null</code> or does not describe a directory, an
+	 *            {@link InvalidParameterException} is thrown
+	 */
+	public PluginLoader(File pluginDir) {
+		if (pluginDir == null) {
+			throw new InvalidParameterException(
+					"Parameter pluginDir must not be null!");
+		}
+		if (!pluginDir.isDirectory()) {
+			throw new InvalidParameterException("File " + pluginDir.getPath()
+					+ " is not a directory");
+		}
+		this.pluginDir = pluginDir;
+		plugins = new LinkedList<QuestPlugin>();
+	}
+
+	/**
+	 * <p>
+	 * Loads plug-ins from {@link #pluginDir}.
+	 * </p>
+	 * 
+	 * @throws PluginLoaderException
+	 *             thrown if there is a problem loading a plug-in or updating
+	 *             the classpath
+	 */
+	public void load() throws PluginLoaderException {
+		File[] jarFiles = pluginDir.listFiles(new FilenameFilter() {
+			@Override
+			public boolean accept(File dir, String name) {
+				return checkNameConformity(name);
+			}
+		});
+
+		for (File jarFile : jarFiles) {
+			updateClassLoader(jarFile);
+
+			String pluginName = jarFile.getName().split("-")[2];
+			String pluginClassName = "de.ugoe.cs.quest.plugin." + pluginName
+					+ "." + pluginName.toUpperCase() + "Plugin";
+
+			Class<?> pluginClass = null;
+			try {
+				pluginClass = Class.forName(pluginClassName);
+			} catch (ClassNotFoundException e) {
+				throw new PluginLoaderException("No class '" + pluginClassName
+						+ "' found in " + pluginDir + "/" + jarFile.getName());
+			}
+			try {
+				QuestPlugin pluginObject = (QuestPlugin) pluginClass
+						.newInstance();
+				plugins.add(pluginObject);
+			} catch (InstantiationException e) {
+				throw new PluginLoaderException("Could not instantiate "
+						+ pluginClassName);
+			} catch (IllegalAccessException e) {
+				throw new PluginLoaderException("Could not access "
+						+ pluginClassName);
+			} catch (ClassCastException e) {
+				throw new PluginLoaderException("Class " + pluginClassName
+						+ " not instance of QuestPlugin");
+			}
+		}
+	}
+
+	/**
+	 * <p>
+	 * Retrieves the classpath from a Jar file's MANIFEST.
+	 * </p>
+	 * 
+	 * @throws IOException
+	 * @throws FileNotFoundException
+	 */
+	protected String[] getClassPathFromJar(File jarFile) {
+		String[] classPath;
+
+		JarInputStream jarInputStream = null;
+		try {
+			jarInputStream = new JarInputStream(new FileInputStream(jarFile));
+		} catch (FileNotFoundException e) {
+			throw new AssertionError(
+					"FileNotFoundException should be impossible!");
+		} catch (IOException e) {
+			throw new PluginLoaderException(e);
+		}
+
+		Manifest manifest = jarInputStream.getManifest();
+
+		String jarClassPath = manifest.getMainAttributes().getValue(
+				"Class-Path");
+
+		if (jarClassPath != null) {
+			String[] jarClassPathElements = jarClassPath.split(" ");
+			classPath = new String[jarClassPathElements.length];
+			for (int i = 0; i < jarClassPathElements.length; i++) {
+				classPath[i] = "file:"
+						+ jarFile.getParentFile().getAbsolutePath() + "/"
+						+ jarClassPathElements[i];
+			}
+			try {
+				jarInputStream.close();
+			} catch (IOException e) {
+				throw new PluginLoaderException(e);
+			}
+		} else {
+			classPath = new String[] {};
+		}
+		return classPath;
+	}
+
+	/**
+	 * <p>
+	 * Updates the classpath of the {@link ClassLoader} to include the plug-in
+	 * jar as well as further libraries required by the plug-in jar as defined
+	 * in the <code>Class-Path</code> section of its manifest.
+	 * </p>
+	 * 
+	 * @param jarFile
+	 *            handle of the plug-in jar file
+	 * @throws PluginLoaderException
+	 *             thrown if there is a problem updating the class loader or
+	 *             loading the plug-in jar
+	 */
+	private void updateClassLoader(File jarFile) throws PluginLoaderException {
+		String[] classPath = getClassPathFromJar(jarFile);
+		URLClassLoader classLoader = (URLClassLoader) ClassLoader
+				.getSystemClassLoader();
+		Method method;
+
+		try {
+			method = URLClassLoader.class.getDeclaredMethod("addURL",
+					new Class[] { URL.class });
+		} catch (SecurityException e) {
+			throw new PluginLoaderException(
+					"addURL method of URLClassLoader not accessible via reflection.");
+		} catch (NoSuchMethodException e) {
+			throw new AssertionError(
+					"URLClassLoader does not have addURL method. Should be impossible!!");
+		}
+		method.setAccessible(true);
+
+		try {
+			method.invoke(
+					classLoader,
+					new Object[] { new URL("file:" + jarFile.getAbsoluteFile()) });
+			for (String element : classPath) {
+				method.invoke(classLoader, new Object[] { new URL(element) });
+			}
+		} catch (IllegalArgumentException e) {
+			throw new AssertionError(
+					"Illegal arguments for addURL method. Should be impossible!!");
+		} catch (MalformedURLException e) {
+			throw new PluginLoaderException(e);
+		} catch (IllegalAccessException e) {
+			throw new PluginLoaderException(
+					"addURL method of URLClassLoader not accessible via reflection.");
+		} catch (InvocationTargetException e) {
+			throw new PluginLoaderException(e);
+		}
+	}
+
+	/**
+	 * <p>
+	 * Checks if the name of a file indicates that it defines a QUEST plug-in.
+	 * The structure of valid plug-in filenames is
+	 * <code>quest-plugin-%PLUGIN_NAME%-version.jar</code>, where
+	 * <code>%PLUGIN_NAME%</code> is replaced by the name of the plug-in. Note
+	 * that plug-in names must not contain any dashes.
+	 * </p>
+	 * 
+	 * @param filename
+	 *            filename that is checked
+	 * @return true if filename matches pattern of QUEST plug-in; false
+	 *         otherwise
+	 */
+	protected boolean checkNameConformity(String filename) {
+		if (filename == null) {
+			return false;
+		}
+		return filename.startsWith("quest-plugin-")
+				&& filename.endsWith(".jar") && filename.split("-").length == 4;
+	}
+	
+	public Collection<QuestPlugin> getPlugins() {
+		return Collections.unmodifiableCollection(plugins);
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-plugin-core/src/main/java/de/ugoe/cs/quest/plugin/PluginLoaderException.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-plugin-core/src/main/java/de/ugoe/cs/quest/plugin/PluginLoaderException.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-plugin-core/src/main/java/de/ugoe/cs/quest/plugin/PluginLoaderException.java	(revision 540)
@@ -0,0 +1,37 @@
+package de.ugoe.cs.quest.plugin;
+
+/**
+ * <p>
+ * This exception is thrown in case there is an error during the loading of
+ * QUEST plugins. Note that the failures during the loading may result in an
+ * invalid classpath and this exception should, therefore, be treated with
+ * appropriate care.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class PluginLoaderException extends RuntimeException {
+
+	/**
+	 * @see RuntimeException#RuntimeException(String)
+	 */
+	public PluginLoaderException(String msg) {
+		super(msg);
+	}
+	
+	/**
+	 * @see RuntimeException#RuntimeException(Throwable)
+	 */
+	public PluginLoaderException(Throwable throwable) {
+		super(throwable);
+	}
+
+	/**
+	 * <p>
+	 * Id for object serialization.
+	 * </p>
+	 */
+	private static final long serialVersionUID = 1L;
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-plugin-core/src/main/java/de/ugoe/cs/quest/plugin/QuestPlugin.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-plugin-core/src/main/java/de/ugoe/cs/quest/plugin/QuestPlugin.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-plugin-core/src/main/java/de/ugoe/cs/quest/plugin/QuestPlugin.java	(revision 540)
@@ -0,0 +1,35 @@
+package de.ugoe.cs.quest.plugin;
+
+/**
+ * <p>
+ * Interface for QUEST plug-ins.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public interface QuestPlugin {
+
+	/**
+	 * <p>
+	 * Title of the plug-in.
+	 * </p>
+	 * 
+	 * @return
+	 */
+	public String getTitle();
+
+	/**
+	 * <p>
+	 * Collection of {@link String}s that contain the commands defined by this
+	 * plug-in.
+	 * </p>
+	 * <p>
+	 * Consult the de.ugoe.cs.utils.console package of the java-utils project
+	 * for more information.
+	 * </p>
+	 * 
+	 * @return
+	 */
+	public String[] getCommandPackages();
+}
Index: /tags/quest-pre-eventrefactoring/quest-plugin-guitar/.classpath
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-plugin-guitar/.classpath	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-plugin-guitar/.classpath	(revision 540)
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/classes" path="src/main/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="src" output="target/test-classes" path="src/test/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
Index: /tags/quest-pre-eventrefactoring/quest-plugin-guitar/.project
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-plugin-guitar/.project	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-plugin-guitar/.project	(revision 540)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>quest-plugin-guitar</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
Index: /tags/quest-pre-eventrefactoring/quest-plugin-guitar/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-plugin-guitar/.settings/org.eclipse.jdt.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-plugin-guitar/.settings/org.eclipse.jdt.core.prefs	(revision 540)
@@ -0,0 +1,5 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.6
Index: /tags/quest-pre-eventrefactoring/quest-plugin-guitar/.settings/org.eclipse.m2e.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-plugin-guitar/.settings/org.eclipse.m2e.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-plugin-guitar/.settings/org.eclipse.m2e.core.prefs	(revision 540)
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
Index: /tags/quest-pre-eventrefactoring/quest-plugin-guitar/pom.xml
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-plugin-guitar/pom.xml	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-plugin-guitar/pom.xml	(revision 540)
@@ -0,0 +1,34 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>de.ugoe.cs.quest</groupId>
+  <artifactId>quest-plugin-guitar</artifactId>
+  <version>0.0.1-SNAPSHOT</version>
+  <name>quest-plugin-guitar</name>
+	<scm>
+		<url>https://quest.informatik.uni-goettingen.de/svn/quest/trunk/quest-plugin-guitar</url>
+	</scm>
+	<dependencies>
+		<dependency>
+			<groupId>de.ugoe.cs</groupId>
+			<artifactId>java-utils</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+		</dependency>
+		<dependency>
+			<groupId>de.ugoe.cs.quest</groupId>
+			<artifactId>quest-plugin-core</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+		</dependency>
+	</dependencies>
+	<build>
+		<plugins>
+			<plugin>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>2.3.2</version>
+				<configuration>
+					<source>1.6</source>
+					<target>1.6</target>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+</project>
Index: /tags/quest-pre-eventrefactoring/quest-plugin-guitar/src/main/java/de/ugoe/cs/quest/plugin/guitar/GUITARPlugin.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-plugin-guitar/src/main/java/de/ugoe/cs/quest/plugin/guitar/GUITARPlugin.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-plugin-guitar/src/main/java/de/ugoe/cs/quest/plugin/guitar/GUITARPlugin.java	(revision 540)
@@ -0,0 +1,42 @@
+package de.ugoe.cs.quest.plugin.guitar;
+
+import de.ugoe.cs.quest.plugin.QuestPlugin;
+
+/**
+ * <p>
+ * Identifier class for the QUEST GUITAR plug-in.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class GUITARPlugin implements QuestPlugin {
+
+	/**
+	 * <p>
+	 * The command packages of this plug-in.
+	 * </p>
+	 */
+	private final static String[] commandPackages = new String[] { "de.ugoe.cs.quest.plugin.guitar.commands" };
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.plugin.QuestPlugin#getTitle()
+	 */
+	@Override
+	public String getTitle() {
+		return "GUITAR-Plugin";
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.plugin.QuestPlugin#getCommandPackages()
+	 */
+	@Override
+	public String[] getCommandPackages() {
+		return commandPackages;
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-plugin-jfc/.classpath
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-plugin-jfc/.classpath	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-plugin-jfc/.classpath	(revision 540)
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/classes" path="src/main/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="src" output="target/test-classes" path="src/test/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
Index: /tags/quest-pre-eventrefactoring/quest-plugin-jfc/.project
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-plugin-jfc/.project	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-plugin-jfc/.project	(revision 540)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>quest-plugin-jfc</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
Index: /tags/quest-pre-eventrefactoring/quest-plugin-jfc/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-plugin-jfc/.settings/org.eclipse.jdt.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-plugin-jfc/.settings/org.eclipse.jdt.core.prefs	(revision 540)
@@ -0,0 +1,5 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.6
Index: /tags/quest-pre-eventrefactoring/quest-plugin-jfc/.settings/org.eclipse.m2e.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-plugin-jfc/.settings/org.eclipse.m2e.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-plugin-jfc/.settings/org.eclipse.m2e.core.prefs	(revision 540)
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
Index: /tags/quest-pre-eventrefactoring/quest-plugin-jfc/pom.xml
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-plugin-jfc/pom.xml	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-plugin-jfc/pom.xml	(revision 540)
@@ -0,0 +1,35 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>de.ugoe.cs.quest</groupId>
+	<artifactId>quest-plugin-jfc</artifactId>
+	<version>0.0.1-SNAPSHOT</version>
+	<name>quest-plugin-jfc</name>
+	<scm>
+		<url>https://quest.informatik.uni-goettingen.de/svn/quest/trunk/quest-plugin-jfc</url>
+	</scm>
+	<dependencies>
+		<dependency>
+			<groupId>de.ugoe.cs</groupId>
+			<artifactId>java-utils</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+		</dependency>
+		<dependency>
+			<groupId>de.ugoe.cs.quest</groupId>
+			<artifactId>quest-plugin-core</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+		</dependency>
+	</dependencies>
+	<build>
+		<plugins>
+			<plugin>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>2.3.2</version>
+				<configuration>
+					<source>1.6</source>
+					<target>1.6</target>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+</project>
Index: /tags/quest-pre-eventrefactoring/quest-plugin-jfc/src/main/java/de/ugoe/cs/quest/plugin/jfc/JFCPlugin.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-plugin-jfc/src/main/java/de/ugoe/cs/quest/plugin/jfc/JFCPlugin.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-plugin-jfc/src/main/java/de/ugoe/cs/quest/plugin/jfc/JFCPlugin.java	(revision 540)
@@ -0,0 +1,42 @@
+package de.ugoe.cs.quest.plugin.jfc;
+
+import de.ugoe.cs.quest.plugin.QuestPlugin;
+
+/**
+ * <p>
+ * Identifier class for the QUEST JFC plug-in.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class JFCPlugin implements QuestPlugin {
+
+	/**
+	 * <p>
+	 * The command packages of this plug-in.
+	 * </p>
+	 */
+	private final static String[] commandPackages = new String[] { "de.ugoe.cs.quest.plugin.jfc.commands" };
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.plugin.QuestPlugin#getTitle()
+	 */
+	@Override
+	public String getTitle() {
+		return "JFC-Plugin";
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.plugin.QuestPlugin#getCommandPackages()
+	 */
+	@Override
+	public String[] getCommandPackages() {
+		return commandPackages;
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-plugin-mfc/.classpath
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-plugin-mfc/.classpath	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-plugin-mfc/.classpath	(revision 540)
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/classes" path="src/main/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="src" output="target/test-classes" path="src/test/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
Index: /tags/quest-pre-eventrefactoring/quest-plugin-mfc/.project
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-plugin-mfc/.project	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-plugin-mfc/.project	(revision 540)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>quest-plugin-mfc</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
Index: /tags/quest-pre-eventrefactoring/quest-plugin-mfc/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-plugin-mfc/.settings/org.eclipse.jdt.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-plugin-mfc/.settings/org.eclipse.jdt.core.prefs	(revision 540)
@@ -0,0 +1,5 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.6
Index: /tags/quest-pre-eventrefactoring/quest-plugin-mfc/.settings/org.eclipse.m2e.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-plugin-mfc/.settings/org.eclipse.m2e.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-plugin-mfc/.settings/org.eclipse.m2e.core.prefs	(revision 540)
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
Index: /tags/quest-pre-eventrefactoring/quest-plugin-mfc/pom.xml
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-plugin-mfc/pom.xml	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-plugin-mfc/pom.xml	(revision 540)
@@ -0,0 +1,35 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>de.ugoe.cs.quest</groupId>
+	<artifactId>quest-plugin-mfc</artifactId>
+	<version>0.0.1-SNAPSHOT</version>
+	<name>quest-plugin-mfc</name>
+	<scm>
+		<url>https://quest.informatik.uni-goettingen.de/svn/quest/trunk/quest-plugin-mfc</url>
+	</scm>
+	<dependencies>
+		<dependency>
+			<groupId>de.ugoe.cs</groupId>
+			<artifactId>java-utils</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+		</dependency>
+		<dependency>
+			<groupId>de.ugoe.cs.quest</groupId>
+			<artifactId>quest-plugin-core</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+		</dependency>
+	</dependencies>
+	<build>
+		<plugins>
+			<plugin>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>2.3.2</version>
+				<configuration>
+					<source>1.6</source>
+					<target>1.6</target>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+</project>
Index: /tags/quest-pre-eventrefactoring/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/MFCPlugin.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/MFCPlugin.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/MFCPlugin.java	(revision 540)
@@ -0,0 +1,42 @@
+package de.ugoe.cs.quest.plugin.mfc;
+
+import de.ugoe.cs.quest.plugin.QuestPlugin;
+
+/**
+ * <p>
+ * Identifier class for the QUEST MFC plug-in.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class MFCPlugin implements QuestPlugin {
+
+	/**
+	 * <p>
+	 * The command packages of this plug-in.
+	 * </p>
+	 */
+	private final static String[] commandPackages = new String[] { "de.ugoe.cs.quest.plugin.mfc.commands" };
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.plugin.QuestPlugin#getTitle()
+	 */
+	@Override
+	public String getTitle() {
+		return "MFC-Plugin";
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.plugin.QuestPlugin#getCommandPackages()
+	 */
+	@Override
+	public String[] getCommandPackages() {
+		return commandPackages;
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-plugin-php/.classpath
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-plugin-php/.classpath	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-plugin-php/.classpath	(revision 540)
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/classes" path="src/main/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="src" output="target/test-classes" path="src/test/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
Index: /tags/quest-pre-eventrefactoring/quest-plugin-php/.project
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-plugin-php/.project	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-plugin-php/.project	(revision 540)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>quest-plugin-php</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
Index: /tags/quest-pre-eventrefactoring/quest-plugin-php/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-plugin-php/.settings/org.eclipse.jdt.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-plugin-php/.settings/org.eclipse.jdt.core.prefs	(revision 540)
@@ -0,0 +1,5 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.6
Index: /tags/quest-pre-eventrefactoring/quest-plugin-php/.settings/org.eclipse.m2e.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-plugin-php/.settings/org.eclipse.m2e.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-plugin-php/.settings/org.eclipse.m2e.core.prefs	(revision 540)
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
Index: /tags/quest-pre-eventrefactoring/quest-plugin-php/pom.xml
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-plugin-php/pom.xml	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-plugin-php/pom.xml	(revision 540)
@@ -0,0 +1,35 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>de.ugoe.cs.quest</groupId>
+	<artifactId>quest-plugin-php</artifactId>
+	<version>0.0.1-SNAPSHOT</version>
+	<name>quest-plugin-php</name>
+	<scm>
+		<url>https://quest.informatik.uni-goettingen.de/svn/quest/trunk/quest-plugin-php</url>
+	</scm>
+	<dependencies>
+		<dependency>
+			<groupId>de.ugoe.cs</groupId>
+			<artifactId>java-utils</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+		</dependency>
+		<dependency>
+			<groupId>de.ugoe.cs.quest</groupId>
+			<artifactId>quest-plugin-core</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+		</dependency>
+	</dependencies>
+	<build>
+		<plugins>
+			<plugin>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>2.3.2</version>
+				<configuration>
+					<source>1.6</source>
+					<target>1.6</target>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+</project>
Index: /tags/quest-pre-eventrefactoring/quest-plugin-php/src/main/java/de/ugoe/cs/quest/plugin/php/PHPPlugin.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-plugin-php/src/main/java/de/ugoe/cs/quest/plugin/php/PHPPlugin.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-plugin-php/src/main/java/de/ugoe/cs/quest/plugin/php/PHPPlugin.java	(revision 540)
@@ -0,0 +1,42 @@
+package de.ugoe.cs.quest.plugin.php;
+
+import de.ugoe.cs.quest.plugin.QuestPlugin;
+
+/**
+ * <p>
+ * Identifier class for the QUEST PHP plug-in.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class PHPPlugin implements QuestPlugin {
+
+	/**
+	 * <p>
+	 * The command packages of this plug-in.
+	 * </p>
+	 */
+	private final static String[] commandPackages = new String[] { "de.ugoe.cs.quest.plugin.php.commands" };
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.plugin.QuestPlugin#getTitle()
+	 */
+	@Override
+	public String getTitle() {
+		return "GUITAR-Plugin";
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.plugin.QuestPlugin#getCommandPackages()
+	 */
+	@Override
+	public String[] getCommandPackages() {
+		return commandPackages;
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-runner/.classpath
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-runner/.classpath	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-runner/.classpath	(revision 540)
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/classes" path="src/main/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
Index: /tags/quest-pre-eventrefactoring/quest-runner/.project
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-runner/.project	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-runner/.project	(revision 540)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>quest-runner</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
Index: /tags/quest-pre-eventrefactoring/quest-runner/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-runner/.settings/org.eclipse.jdt.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-runner/.settings/org.eclipse.jdt.core.prefs	(revision 540)
@@ -0,0 +1,5 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.6
Index: /tags/quest-pre-eventrefactoring/quest-runner/.settings/org.eclipse.m2e.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-runner/.settings/org.eclipse.m2e.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-runner/.settings/org.eclipse.m2e.core.prefs	(revision 540)
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
Index: /tags/quest-pre-eventrefactoring/quest-runner/pom.xml
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-runner/pom.xml	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-runner/pom.xml	(revision 540)
@@ -0,0 +1,53 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>de.ugoe.cs.quest</groupId>
+	<artifactId>quest-runner</artifactId>
+	<version>0.0.1-SNAPSHOT</version>
+	<name>quest-runner</name>
+	<scm>
+		<url>https://quest.informatik.uni-goettingen.de/svn/quest/trunk/quest-runner</url>
+	</scm>
+	<dependencies>
+		<dependency>
+			<groupId>de.ugoe.cs</groupId>
+			<artifactId>java-utils</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+		</dependency>
+		<dependency>
+			<groupId>de.ugoe.cs.quest</groupId>
+			<artifactId>quest-plugin-core</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+		</dependency>
+		<dependency>
+			<groupId>de.ugoe.cs.quest</groupId>
+			<artifactId>quest-ui-core</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+		</dependency>
+		<dependency>
+			<groupId>de.ugoe.cs.quest</groupId>
+			<artifactId>quest-ui-swt</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+		</dependency>
+		<dependency>
+			<groupId>net.sf.jopt-simple</groupId>
+			<artifactId>jopt-simple</artifactId>
+			<version>4.3</version>
+		</dependency>
+	</dependencies>
+	<build>
+		<plugins>
+			<plugin>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>2.3.2</version>
+				<configuration>
+					<source>1.6</source>
+					<target>1.6</target>
+					<compilerArgument>-Xlint:all</compilerArgument>
+					<showWarnings>true</showWarnings>
+					<showDeprecation>true</showDeprecation>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+</project>
Index: /tags/quest-pre-eventrefactoring/quest-runner/src/main/java/de/ugoe/cs/quest/ui/Runner.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-runner/src/main/java/de/ugoe/cs/quest/ui/Runner.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-runner/src/main/java/de/ugoe/cs/quest/ui/Runner.java	(revision 540)
@@ -0,0 +1,144 @@
+package de.ugoe.cs.quest.ui;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+import joptsimple.OptionException;
+import joptsimple.OptionParser;
+import joptsimple.OptionSet;
+import joptsimple.OptionSpec;
+import de.ugoe.cs.quest.log4j.Log4JLogger;
+import de.ugoe.cs.quest.plugin.PluginLoader;
+import de.ugoe.cs.quest.plugin.QuestPlugin;
+import de.ugoe.cs.quest.ui.swt.MainWindow;
+import de.ugoe.cs.util.console.CommandExecuter;
+import de.ugoe.cs.util.console.Console;
+import de.ugoe.cs.util.console.TextConsole;
+
+/**
+ * <p>
+ * Start-up class of the application.
+ * </p>
+ * <p>
+ * It sets up and starts the {@link Console}.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class Runner {
+
+	public enum UITYPE {
+		text, swt
+	};
+
+	public enum LOG4JTYPE {
+		enable, disable
+	}
+
+	/**
+	 * <p>
+	 * Main method of the application.
+	 * </p>
+	 * 
+	 * @param args
+	 *            if parameters are defined, they are interpreted as commands
+	 *            for the {@link Console} and executed before the user can use
+	 *            the console; can be used to perform batch operations
+	 */
+	public static void main(String[] args) {
+
+		CommandExecuter.getInstance().addCommandPackage(
+				"de.ugoe.cs.quest.ui.commands");
+		CommandExecuter.getInstance().addCommandPackage(
+				"de.ugoe.cs.quest.ui.swt.commands");
+
+		// The following four command packages are added automatically, once the
+		// plugin-mechanism works correctly. Hence, these calls should be
+		// removed then.
+		CommandExecuter.getInstance().addCommandPackage(
+				"de.ugoe.cs.quest.plugin.mfc.commands");
+		CommandExecuter.getInstance().addCommandPackage(
+				"de.ugoe.cs.quest.plugin.php.commands");
+		CommandExecuter.getInstance().addCommandPackage(
+				"de.ugoe.cs.quest.plugin.guitar.commands");
+		CommandExecuter.getInstance().addCommandPackage(
+				"de.ugoe.cs.quest.plugin.jfc.commands");
+		
+		int i;
+		if(false) {
+			int j;
+		}
+
+		/*
+		 * Code for loading plugins. Should be uncommented once the
+		 * plugin-mechanism works correctly.
+		 * TODO: uncomment as soon as plug-in mechanism works
+		 * 
+		 * PluginLoader pluginLoader = new PluginLoader(new File("plugins"));
+		 * pluginLoader.load();
+		 * 
+		 * for( QuestPlugin plugin : pluginLoader.getPlugins()) { for( String
+		 * commandPackage : plugin.getCommandPackages()) {
+		 * CommandExecuter.getInstance().addCommandPackage(commandPackage); } }
+		 */
+
+		OptionParser parser = new OptionParser();
+		OptionSpec<LOG4JTYPE> log4j = parser
+				.accepts("log4j", "Allowed values: enable, disable")
+				.withRequiredArg().ofType(LOG4JTYPE.class)
+				.defaultsTo(LOG4JTYPE.enable);
+		OptionSpec<UITYPE> ui = parser
+				.accepts("ui", "Allowed values: text, swt").withRequiredArg()
+				.ofType(UITYPE.class).defaultsTo(UITYPE.text);
+		OptionSpec<LOG4JTYPE> trace = parser
+				.accepts("trace", "Allowed values: enable, disable")
+				.withRequiredArg().ofType(LOG4JTYPE.class)
+				.defaultsTo(LOG4JTYPE.enable);
+		OptionSet options = parser.parse(args);
+
+		List<String> startupCommands = options.nonOptionArguments();
+		try {
+			switch (options.valueOf(log4j)) {
+			case enable:
+				new Log4JLogger();
+				break;
+			case disable:
+				// do nothing
+				break;
+			default:
+				throw new AssertionError(
+						"reached source code that should be unreachable");
+			}
+
+			switch (options.valueOf(ui)) {
+			case text:
+				TextConsole textConsole = new TextConsole();
+				if (options.valueOf(trace) == LOG4JTYPE.disable) {
+					textConsole.setDebug(false);
+				}
+				for (String command : startupCommands) {
+					CommandExecuter.getInstance().exec(command);
+				}
+				textConsole.run(true);
+				break;
+			case swt:
+				MainWindow mainWindow = new MainWindow(startupCommands);
+				mainWindow.open();
+				break;
+			default:
+				throw new AssertionError(
+						"reached source code that should be unreachable");
+			}
+		} catch (OptionException e) {
+			System.err.println("Invalid Parameters: " + e.getMessage());
+			try {
+				parser.printHelpOn(System.out);
+			} catch (IOException e1) {
+				// ignore exception.
+			}
+		}
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core-test/.classpath
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core-test/.classpath	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core-test/.classpath	(revision 540)
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/test-classes" path="src/test/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
Index: /tags/quest-pre-eventrefactoring/quest-ui-core-test/.project
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core-test/.project	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core-test/.project	(revision 540)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>quest-ui-core-test</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
Index: /tags/quest-pre-eventrefactoring/quest-ui-core-test/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core-test/.settings/org.eclipse.jdt.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core-test/.settings/org.eclipse.jdt.core.prefs	(revision 540)
@@ -0,0 +1,5 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.6
Index: /tags/quest-pre-eventrefactoring/quest-ui-core-test/.settings/org.eclipse.m2e.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core-test/.settings/org.eclipse.m2e.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core-test/.settings/org.eclipse.m2e.core.prefs	(revision 540)
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
Index: /tags/quest-pre-eventrefactoring/quest-ui-core-test/pom.xml
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core-test/pom.xml	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core-test/pom.xml	(revision 540)
@@ -0,0 +1,139 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>quest-ui-core-test</groupId>
+	<artifactId>quest-ui-core-test</artifactId>
+	<version>0.0.1-SNAPSHOT</version>
+	<scm>
+		<url>https://quest.informatik.uni-goettingen.de/svn/quest/trunk/quest-ui-core-test</url>
+	</scm>
+	<dependencies>
+		<dependency>
+			<groupId>de.ugoe.cs.quest</groupId>
+			<artifactId>quest-ui-core</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<version>4.8.1</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>junit-addons</groupId>
+			<artifactId>junit-addons</artifactId>
+			<version>1.4</version>
+		</dependency>
+		<dependency>
+			<groupId>org.mockito</groupId>
+			<artifactId>mockito-core</artifactId>
+			<version>1.9.0</version>
+			<scope>test</scope>
+		</dependency>
+	</dependencies>
+	<build>
+		<pluginManagement>
+			<plugins>
+				<plugin>
+					<groupId>org.eclipse.m2e</groupId>
+					<artifactId>lifecycle-mapping</artifactId>
+					<version>1.0.0</version>
+					<configuration>
+						<lifecycleMappingMetadata>
+							<pluginExecutions>
+								<pluginExecution>
+									<pluginExecutionFilter>
+										<groupId>org.apache.maven.plugins</groupId>
+										<artifactId>maven-dependency-plugin</artifactId>
+										<versionRange>[1.0.0,)</versionRange>
+										<goals>
+											<goal>unpack</goal>
+										</goals>
+									</pluginExecutionFilter>
+									<action>
+										<ignore />
+									</action>
+								</pluginExecution>
+								<pluginExecution>
+									<pluginExecutionFilter>
+										<groupId>org.codehaus.mojo</groupId>
+										<artifactId>emma-maven-plugin</artifactId>
+										<versionRange>[1.0-alpha-3,)</versionRange>
+										<goals>
+											<goal>emma</goal>
+										</goals>
+									</pluginExecutionFilter>
+									<action>
+										<ignore />
+									</action>
+								</pluginExecution>
+							</pluginExecutions>
+						</lifecycleMappingMetadata>
+					</configuration>
+				</plugin>
+			</plugins>
+		</pluginManagement>
+		<plugins>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>2.3.2</version>
+				<configuration>
+					<source>1.6</source>
+					<target>1.6</target>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-dependency-plugin</artifactId>
+				<version>2.4</version>
+				<executions>
+					<execution>
+						<id>unpack</id>
+						<phase>process-classes</phase>
+						<goals>
+							<goal>unpack</goal>
+						</goals>
+						<configuration>
+							<artifactItems>
+								<artifactItem>
+									<groupId>de.ugoe.cs.quest</groupId>
+									<artifactId>quest-ui-core</artifactId>
+									<version>0.0.1-SNAPSHOT</version>
+									<outputDirectory>${project.build.directory}/classes</outputDirectory>
+								</artifactItem>
+							</artifactItems>
+						</configuration>
+					</execution>
+				</executions>
+			</plugin>
+			<plugin>
+				<groupId>org.codehaus.mojo</groupId>
+				<artifactId>emma-maven-plugin</artifactId>
+				<version>1.0-alpha-3</version>
+				<inherited>true</inherited>
+				<executions>
+					<execution>
+						<phase>process-classes</phase>
+						<goals>
+							<goal>emma</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-jar-plugin</artifactId>
+				<version>2.3.2</version>
+				<executions>
+					<execution>
+						<goals>
+							<goal>test-jar</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+		</plugins>
+	</build>
+</project>
Index: /tags/quest-pre-eventrefactoring/quest-ui-core-test/src/test/java/de/ugoe/cs/quest/plugin/jfc/eventcore/JFCEventTest.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core-test/src/test/java/de/ugoe/cs/quest/plugin/jfc/eventcore/JFCEventTest.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core-test/src/test/java/de/ugoe/cs/quest/plugin/jfc/eventcore/JFCEventTest.java	(revision 540)
@@ -0,0 +1,376 @@
+package de.ugoe.cs.quest.plugin.jfc.eventcore;
+
+import org.junit.*;
+
+import de.ugoe.cs.quest.plugin.jfc.eventcore.JFCEvent;
+import de.ugoe.cs.quest.plugin.jfc.eventcore.JFCTargetComparator;
+
+import static org.junit.Assert.*;
+
+/**
+ * The class <code>JFCEventTest</code> contains tests for the class <code>{@link JFCEvent}</code>.
+ *
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class JFCEventTest {
+	
+	@Test
+	public void testTargetEquals_1()
+		throws Exception {
+		JFCEvent event = new JFCEvent("type");
+		String target1 = "['title1','class1','text1','index1','hash1'].['title2','class2','text2','index2','hash2']";
+		String target2 = "['title1','class1','text1','index1','hash1'].['title2','class2','text2','index2','hash2']";
+		event.setTarget(target1);
+		boolean expected = true;
+		
+		boolean result = event.targetEquals(target2);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testTargetEquals_2()
+		throws Exception {
+		JFCEvent event = new JFCEvent("type");
+		String target1 = "['title1','class1','text1','index1','hash1'].['title2','class2','text2','index2','hash2']";
+		String target2 = "['title1','class1','text1','index1','hash1'].['titleOther','class2','text2','index2','hash2']";
+		event.setTarget(target1);
+		boolean expected = true;
+		
+		boolean result = event.targetEquals(target2);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testTargetEquals_3()
+		throws Exception {
+		JFCEvent event = new JFCEvent("type");
+		String target1 = "['title1','class1','text1','index1','hash1'].['title2','class2','text2','index2','hash2']";
+		String target2 = "['title1','class1','text1','index1','hash1'].['title2','class2','text2','index2','hashOther']";
+		event.setTarget(target1);
+		boolean expected = true;
+		
+		boolean result = event.targetEquals(target2);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testTargetEquals_4()
+		throws Exception {
+		JFCEvent event = new JFCEvent("type");
+		String target1 = "['title1','class1','text1','index1','hash1'].['title2','class2','text2','index2','hash2']";
+		String target2 = "['titleOther','class1','text1','index1','hash1'].['title2','class2','text2','index2','hash2']";
+		event.setTarget(target1);
+		boolean expected = true;
+		
+		boolean result = event.targetEquals(target2);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testTargetEquals_5()
+		throws Exception {
+		JFCEvent event = new JFCEvent("type");
+		String target1 = "['title1','class1','text1','index1','hash1'].['title2','class2','text2','index2','hash2']";
+		String target2 = "['title1','class1','text1','index1','hashOther'].['title2','class2','text2','index2','hash2']";
+		event.setTarget(target1);
+		boolean expected = true;
+		
+		boolean result = event.targetEquals(target2);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testTargetEquals_6()
+		throws Exception {
+		JFCEvent event = new JFCEvent("type");
+		String target1 = "['title1','class1','text1','index1','hash1'].['title2','class2','text2','index2','hash2']";
+		String target2 = "['title1','class1','text1','index1','hash1'].['titleOther','class2','text2','index2','hashOther']";
+		event.setTarget(target1);
+		boolean expected = false;
+		
+		boolean result = event.targetEquals(target2);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testTargetEquals_7()
+		throws Exception {
+		JFCEvent event = new JFCEvent("type");
+		String target1 = "['title1','class1','text1','index1','hash1'].['title2','class2','text2','index2','hash2']";
+		String target2 = "['titleOther','class1','text1','index1','hashOther'].['title2','class2','text2','index2','hash2']";
+		event.setTarget(target1);
+		boolean expected = false;
+		
+		boolean result = event.targetEquals(target2);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testTargetEquals_8()
+		throws Exception {
+		JFCEvent event = new JFCEvent("type");
+		String target1 = "['title1','class1','text1','index1','hash1'].['title2','class2','text2','index2','hash2']";
+		String target2 = "['title1','class1','text1','index1','hash1'].['title2','classOther','text2','index2','hash2']";
+		event.setTarget(target1);
+		boolean expected = false;
+		
+		boolean result = event.targetEquals(target2);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testTargetEquals_9()
+		throws Exception {
+		JFCEvent event = new JFCEvent("type");
+		String target1 = "['title1','class1','text1','index1','hash1'].['title2','class2','text2','index2','hash2']";
+		String target2 = "['title1','class1','text1','index1','hash1'].['title2','class2','textOther','index2','hash2']";
+		event.setTarget(target1);
+		boolean expected = false;
+		
+		boolean result = event.targetEquals(target2);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testTargetEquals_10()
+		throws Exception {
+		JFCEvent event = new JFCEvent("type");
+		String target1 = "['title1','class1','text1','index1','hash1'].['title2','class2','text2','index2','hash2']";
+		String target2 = "['title1','class1','text1','index1','hash1'].['title2','class2','text2','indexOther','hash2']";
+		event.setTarget(target1);
+		boolean expected = false;
+		
+		boolean result = event.targetEquals(target2);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testTargetEquals_11()
+		throws Exception {
+		JFCEvent event = new JFCEvent("type");
+		String target1 = "['title1','class1','text1','index1','hash1'].['title2','class2','text2','index2','hash2']";
+		String target2 = "['title1','classOther','text1','index1','hash1'].['title2','class2','text2','index2','hash2']";
+		event.setTarget(target1);
+		boolean expected = false;
+		
+		boolean result = event.targetEquals(target2);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testTargetEquals_12()
+		throws Exception {
+		JFCEvent event = new JFCEvent("type");
+		String target1 = "['title1','class1','text1','index1','hash1'].['title2','class2','text2','index2','hash2']";
+		String target2 = "['title1','class1','textOther','index1','hash1'].['title2','class2','text2','index2','hash2']";
+		event.setTarget(target1);
+		boolean expected = false;
+		
+		boolean result = event.targetEquals(target2);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testTargetEquals_13()
+		throws Exception {
+		JFCEvent event = new JFCEvent("type");
+		String target1 = "['title1','class1','text1','index1','hash1'].['title2','class2','text2','index2','hash2']";
+		String target2 = "['title1','class1','text1','indexOther','hash1'].['title2','class2','text2','index2','hash2']";
+		event.setTarget(target1);
+		boolean expected = false;
+		
+		boolean result = event.targetEquals(target2);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testTargetEquals_14()
+		throws Exception {
+		JFCEvent event = new JFCEvent("type");
+		String target1 = "['title'1','class1','text1','index1','hash1'].['title2','class2','text2','index2','hash2']";
+		String target2 = "['title'1','class1','text1','index1','hash1'].['title2','class2','text2','index2','hash2']";
+		event.setTarget(target1);
+		boolean expected = true;
+		
+		boolean result = event.targetEquals(target2);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testTargetEquals_15()
+		throws Exception {
+		JFCEvent event = new JFCEvent("type");
+		String target1 = "['title]1','class1','text1','index1','hash1'].['title2','class2','text2','index2','hash2']";
+		String target2 = "['title]1','class1','text1','index1','hash1'].['title2','class2','text2','index2','hash2']";
+		event.setTarget(target1);
+		boolean expected = true;
+		
+		boolean result = event.targetEquals(target2);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testTargetEquals_16()
+		throws Exception {
+		JFCEvent event = new JFCEvent("type");
+		String target1 = "['title[1','class1','text1','index1','hash1'].['title2','class2','text2','index2','hash2']";
+		String target2 = "['title[1','class1','text1','index1','hash1'].['title2','class2','text2','index2','hash2']";
+		event.setTarget(target1);
+		boolean expected = true;
+		
+		boolean result = event.targetEquals(target2);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testTargetEquals_17()
+		throws Exception {
+		JFCEvent event = new JFCEvent("type");
+		String target1 = "['title].1','class1','text1','index1','hash1'].['title2','class2','text2','index2','hash2']";
+		String target2 = "['title].1','class1','text1','index1','hash1'].['title2','class2','text2','index2','hash2']";
+		event.setTarget(target1);
+		boolean expected = true;
+		
+		boolean result = event.targetEquals(target2);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testTargetEquals_18()
+		throws Exception {
+		JFCEvent event = new JFCEvent("type");
+		String target1 = "['title.[1','class1','text1','index1','hash1'].['title2','class2','text2','index2','hash2']";
+		String target2 = "['title.[1','class1','text1','index1','hash1'].['title2','class2','text2','index2','hash2']";
+		event.setTarget(target1);
+		boolean expected = true;
+		
+		boolean result = event.targetEquals(target2);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testTargetEquals_19()
+		throws Exception {
+		JFCEvent event = new JFCEvent("type");
+		String target1 = "['title1','class1','text1','index1','hash1']";
+		String target2 = "['title1','class1','text1','index1','hash1'].['title2','class2','text2','index2','hash2']";
+		event.setTarget(target1);
+		boolean expected = false;
+		
+		boolean result = event.targetEquals(target2);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testTargetEquals_20()
+		throws Exception {
+		JFCEvent event = new JFCEvent("type");
+		String target1 = "['title1','class1','text1','index1','hash1']";
+		String target2 = "['title1','class1','text1','index1','hash1']";
+		event.setTarget(target1);
+		boolean expected = true;
+		
+		boolean result = event.targetEquals(target2);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testTargetEquals_21()
+		throws Exception {
+		JFCEvent event = new JFCEvent("type");
+		String target1 = "['title1','class1','text1','index1','hash1']";
+		String target2 = "['titleOther','class1','text1','index1','hash1']";
+		event.setTarget(target1);
+		boolean expected = true;
+		
+		boolean result = event.targetEquals(target2);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testTargetEquals_22()
+		throws Exception {
+		JFCEvent event = new JFCEvent("type");
+		String target1 = "['title1','class1','text1','index1','hash1']";
+		String target2 = "['title1','class1','text1','index1','hashOther']";
+		event.setTarget(target1);
+		boolean expected = true;
+		
+		boolean result = event.targetEquals(target2);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testTargetEquals_23()
+		throws Exception {
+		JFCEvent event = new JFCEvent("type");
+		String target1 = "['title1','class1','text1','index1','hash1']";
+		String target2 = "['titleOther','class1','text1','index1','hashOther']";
+		event.setTarget(target1);
+		boolean expected = false;
+		
+		boolean result = event.targetEquals(target2);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testTargetEquals_24()
+		throws Exception {
+		JFCEvent event = new JFCEvent("type");
+		String target1 = null;
+		String target2 = "['titleOther','class1','text1','index1','hash1']";
+		event.setTarget(target1);
+		boolean expected = false;
+		
+		boolean result = event.targetEquals(target2);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testTargetEquals_25()
+		throws Exception {
+		JFCEvent event = new JFCEvent("type");
+		String target1 = "['title1','class1','text1','index1','hash1']";
+		String target2 = null;
+		event.setTarget(target1);
+		boolean expected = false;
+		
+		boolean result = event.targetEquals(target2);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Before
+	public void setUp() {
+		JFCTargetComparator.reset();
+	}
+	
+	public static void main(String[] args) {
+		new org.junit.runner.JUnitCore().run(JFCEventTest.class);
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core-test/src/test/java/de/ugoe/cs/quest/plugin/mfc/eventcore/WindowsEventTest.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core-test/src/test/java/de/ugoe/cs/quest/plugin/mfc/eventcore/WindowsEventTest.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core-test/src/test/java/de/ugoe/cs/quest/plugin/mfc/eventcore/WindowsEventTest.java	(revision 540)
@@ -0,0 +1,50 @@
+package de.ugoe.cs.quest.plugin.mfc.eventcore;
+
+import org.junit.*;
+
+import de.ugoe.cs.quest.plugin.mfc.eventcore.MFCTargetComparator;
+import de.ugoe.cs.quest.plugin.mfc.eventcore.WindowsEvent;
+
+import static org.junit.Assert.*;
+
+/**
+ * The class <code>WindowsEventTest</code> contains tests for the class <code>{@link WindowsEvent}</code>.
+ *
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class WindowsEventTest {
+	
+	@Test
+	public void testTargetEquals_1() throws Exception {
+		WindowsEvent event = new WindowsEvent("type");
+		String target1 = "<window name=\"name1\" class=\"class1\" resourceId=\"id1\" isModal=\"modal1\" hwnd=\"111\"/>";
+		String target2 = "<window name=\"name1\" class=\"class1\" resourceId=\"id1\" isModal=\"modal1\" hwnd=\"111\"/>";
+		event.setTarget(target1);
+		boolean expected = true;
+		
+		boolean result = event.targetEquals(target2);
+		
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testTargetEquals_2() throws Exception {
+		WindowsEvent event = new WindowsEvent("type");
+		String target1 = "<window name=\"Messplatz\" class=\"#32770\" resourceId=\"0\" isModal=\"true\" hwnd=\"1770138\"/><window name=\"Messplatz im Einstellmodus\" class=\"#32770\" resourceId=\"0\" isModal=\"true\" hwnd=\"2032262\"/><window name=\"\" class=\"#32770\" resourceId=\"0\" isModal=\"false\" hwnd=\"459658\"/><window name=\"\" class=\"SysTabControl32\" resourceId=\"12320\" isModal=\"false\" hwnd=\"983734\"/>";
+		String target2 = "<window name=\"Messplatz\" class=\"#32770\" resourceId=\"0\" isModal=\"true\" hwnd=\"1770138\"/><window name=\"Messplatz im Einstellmodus\" class=\"#32770\" resourceId=\"0\" isModal=\"true\" hwnd=\"2032262\"/><window name=\"\" class=\"#32770\" resourceId=\"0\" isModal=\"false\" hwnd=\"459658\"/><window name=\"\" class=\"SysTabControl32\" resourceId=\"12320\" isModal=\"false\" hwnd=\"983734\"/>";
+		event.setTarget(target1);
+		boolean expected = true;
+		
+		boolean result = event.targetEquals(target2);
+		
+		assertEquals(expected, result);
+		
+		MFCTargetComparator.setMutable(false);
+		
+		result = event.targetEquals(target2);
+		
+		assertEquals(expected, result);
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core-test/src/test/java/de/ugoe/cs/quest/ui/GlobalDataContainerTest.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core-test/src/test/java/de/ugoe/cs/quest/ui/GlobalDataContainerTest.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core-test/src/test/java/de/ugoe/cs/quest/ui/GlobalDataContainerTest.java	(revision 540)
@@ -0,0 +1,462 @@
+package de.ugoe.cs.quest.ui;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Modifier;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.junit.*;
+
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.usageprofiles.IStochasticProcess;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+/**
+ * The class <code>WindowsEventTest</code> contains tests for the class
+ * <code>{@link WindowsEvent}</code>.
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class GlobalDataContainerTest {
+
+	private static void assertCollectionContent(Collection<?> c1,
+			Collection<?> c2) {
+		assertEquals(c1.size(), c2.size());
+		for (Object obj : c1) {
+			assertTrue(c2.contains(obj));
+		}
+	}
+	
+	@Test
+	public void testGlobalDataContainer_1() throws Exception {
+		// assure that all constructors are private
+		Constructor<?>[] constructors = GlobalDataContainer.class.getDeclaredConstructors();
+		for (int i = 0; i < constructors.length; i++) { 
+			int modifier = constructors[i].getModifiers();
+			if(modifier != Modifier.PRIVATE) {
+				fail(constructors[i].getName()+" - "+Modifier.toString(modifier));
+			}
+		}
+	}
+
+	@Test
+	public void testGetInstance_1() throws Exception {
+		GlobalDataContainer instance1 = GlobalDataContainer.getInstance();
+		GlobalDataContainer instance2 = GlobalDataContainer.getInstance();
+		assertNotNull(instance1);
+		assertSame(instance1, instance2);
+	}
+
+	@Test
+	public void testDatahandling_1() throws Exception {
+		// test is data can be added and retrieved as expected
+		GlobalDataContainer instance = GlobalDataContainer.getInstance();
+
+		String key1 = "key1";
+		String data1 = "data1";
+		String key2 = "key2";
+		String data2 = "data2";
+		String key3 = "key3";
+		Integer data3 = 1;
+		String key4 = "key4";
+		Integer data4 = 2;
+		String key5 = "key5";
+		Integer data5 = 3;
+
+		assertFalse(instance.addData(key1, data1));
+		assertFalse(instance.addData(key2, data2));
+		assertFalse(instance.addData(key3, data3));
+		assertFalse(instance.addData(key4, data4));
+		assertFalse(instance.addData(key5, data5));
+
+		assertEquals(data1, instance.getData(key1));
+		assertEquals(data2, instance.getData(key2));
+		assertEquals(data3, instance.getData(key3));
+		assertEquals(data4, instance.getData(key4));
+		assertEquals(data5, instance.getData(key5));
+	}
+
+	@Test
+	public void testDatahandling_2() throws Exception {
+		// test is data can be added, overwritten, and retrieved as expected
+		GlobalDataContainer instance = GlobalDataContainer.getInstance();
+
+		String key1 = "key1";
+		String data1 = "data1";
+		String data1changed = "data1changed";
+		String key2 = "key2";
+		String data2 = "data2";
+		String data2changed = "data2changed";
+		String key3 = "key3";
+		Integer data3 = 1;
+		Integer data3changed = 11;
+		String key4 = "key4";
+		Integer data4 = 2;
+		Integer data4changed = 22;
+		String key5 = "key5";
+		Integer data5 = 3;
+		Integer data5changed = 33;
+
+		assertFalse(instance.addData(key1, data1));
+		assertFalse(instance.addData(key2, data2));
+		assertFalse(instance.addData(key3, data3));
+		assertFalse(instance.addData(key4, data4));
+		assertFalse(instance.addData(key5, data5));
+
+		assertTrue(instance.addData(key1, data1changed));
+		assertTrue(instance.addData(key2, data2changed));
+		assertTrue(instance.addData(key3, data3changed));
+		assertTrue(instance.addData(key4, data4changed));
+		assertTrue(instance.addData(key5, data5changed));
+
+		assertEquals(data1changed, instance.getData(key1));
+		assertEquals(data2changed, instance.getData(key2));
+		assertEquals(data3changed, instance.getData(key3));
+		assertEquals(data4changed, instance.getData(key4));
+		assertEquals(data5changed, instance.getData(key5));
+	}
+	
+	@Test
+	public void testDatahandling_3() throws Exception {
+		// test is data can be removed as expected
+		GlobalDataContainer instance = GlobalDataContainer.getInstance();
+
+		String key1 = "key1";
+		String data1 = "data1";
+		String key2 = "key2";
+		String data2 = "data2";
+		String key3 = "key3";
+		Integer data3 = 1;
+		String key4 = "key4";
+		Integer data4 = 2;
+		String key5 = "key5";
+		Integer data5 = 3;
+
+		assertFalse(instance.addData(key1, data1));
+		assertFalse(instance.addData(key2, data2));
+		assertFalse(instance.addData(key3, data3));
+		assertFalse(instance.addData(key4, data4));
+		assertFalse(instance.addData(key5, data5));
+
+		assertFalse(instance.removeData("keyNotFound"));
+		assertTrue(instance.removeData(key1));
+		
+		assertNull(instance.getData(key1));
+	}
+	
+	@Test
+	public void testDatahandling_4() throws Exception {
+		// test is data can be removed as expected
+		GlobalDataContainer instance = GlobalDataContainer.getInstance();
+
+		String key1 = "key1";
+		String data1 = "data1";
+		String key2 = "key2";
+		String data2 = "data2";
+		String key3 = "key3";
+		Integer data3 = 1;
+		String key4 = "key4";
+		Integer data4 = 2;
+		String key5 = "key5";
+		Integer data5 = 3;
+
+		assertFalse(instance.addData(key1, data1));
+		assertFalse(instance.addData(key2, data2));
+		assertFalse(instance.addData(key3, data3));
+		assertFalse(instance.addData(key4, data4));
+		assertFalse(instance.addData(key5, data5));
+
+		assertNull(instance.getData("keyNotFound"));
+	}
+	
+	@Test
+	public void testReset_1() throws Exception {
+		// check if data container is empty after reset
+		GlobalDataContainer instance = GlobalDataContainer.getInstance();
+		String key1 = "key1";
+		String data1 = "data1";
+		String key2 = "key2";
+		String data2 = "data2";
+		String key3 = "key3";
+		Integer data3 = 1;
+		String key4 = "key4";
+		Integer data4 = 2;
+		String key5 = "key5";
+		Integer data5 = 3;
+
+		assertFalse(instance.addData(key1, data1));
+		assertFalse(instance.addData(key2, data2));
+		assertFalse(instance.addData(key3, data3));
+		assertFalse(instance.addData(key4, data4));
+		assertFalse(instance.addData(key5, data5));
+		
+		instance.reset();
+		
+		assertNull(instance.getData(key1));
+		assertNull(instance.getData(key2));
+		assertNull(instance.getData(key3));
+		assertNull(instance.getData(key4));
+		assertNull(instance.getData(key5));
+	}
+	 
+	@Test
+	public void testGetAllKeys_1() throws Exception {
+		// check if data container is empty after reset
+		GlobalDataContainer instance = GlobalDataContainer.getInstance();
+		String key1 = "key1";
+		String data1 = "data1";
+		String key2 = "key2";
+		String data2 = "data2";
+		String key3 = "key3";
+		Integer data3 = 1;
+		String key4 = "key4";
+		Integer data4 = 2;
+		String key5 = "key5";
+		Integer data5 = 3;
+
+		assertFalse(instance.addData(key1, data1));
+		assertFalse(instance.addData(key2, data2));
+		assertFalse(instance.addData(key3, data3));
+		assertFalse(instance.addData(key4, data4));
+		assertFalse(instance.addData(key5, data5));
+		
+		Collection<String> expected = new LinkedList<String>();
+		expected.add(key1);
+		expected.add(key2);
+		expected.add(key3);
+		expected.add(key4);
+		expected.add(key5);
+		
+		assertCollectionContent(expected, instance.getAllKeys());
+	}
+	
+	@Test
+	public void testGetAllSequencesNames_1() {
+		GlobalDataContainer instance = GlobalDataContainer.getInstance();
+		String key1 = "key1";
+		String data1 = "data1";
+		String key2 = "key2";
+		String data2 = "data2";
+		String key3 = "key3";
+		Integer data3 = 1;
+		String key4 = "key4";
+		Integer data4 = 2;
+		String key5 = "key5";
+		Integer data5 = 3;
+		
+		assertFalse(instance.addData(key1, data1));
+		assertFalse(instance.addData(key2, data2));
+		assertFalse(instance.addData(key3, data3));
+		assertFalse(instance.addData(key4, data4));
+		assertFalse(instance.addData(key5, data5));
+		
+		String keySeq1 = "seq1";
+		Collection<List<Event<?>>> seq1 = new LinkedList<List<Event<?>>>();
+		List<Event<?>> subseq1 = new LinkedList<Event<?>>();
+		subseq1.add(Event.STARTEVENT);
+		seq1.add(subseq1);
+		
+		String keySeq2 = "seq2";
+		Collection<List<Event<?>>> seq2 = new LinkedList<List<Event<?>>>();
+		List<Event<?>> subseq2 = new LinkedList<Event<?>>();
+		subseq2.add(Event.STARTEVENT);
+		seq2.add(subseq2);
+		
+		assertFalse(instance.addData(keySeq1, seq1));
+		assertFalse(instance.addData(keySeq2, seq2));
+		
+		Collection<String> expected = new LinkedList<String>();
+		expected.add(keySeq1);
+		expected.add(keySeq2);
+		
+		assertCollectionContent(expected, instance.getAllSequencesNames());
+	}
+	
+	@Test
+	public void testGetAllSequencesNames_2() {
+		GlobalDataContainer instance = GlobalDataContainer.getInstance();
+		String key1 = "key1";
+		String data1 = "data1";
+		String key2 = "key2";
+		String data2 = "data2";
+		String key3 = "key3";
+		Integer data3 = 1;
+		String key4 = "key4";
+		Integer data4 = 2;
+		String key5 = "key5";
+		Integer data5 = 3;
+		
+		assertFalse(instance.addData(key1, data1));
+		assertFalse(instance.addData(key2, data2));
+		assertFalse(instance.addData(key3, data3));
+		assertFalse(instance.addData(key4, data4));
+		assertFalse(instance.addData(key5, data5));
+		
+		String keySeq1 = "seq1";
+		Collection<List<Event<?>>> seq1 = new LinkedList<List<Event<?>>>();
+		List<Event<?>> subseq1 = new LinkedList<Event<?>>();
+		subseq1.add(Event.STARTEVENT);
+		seq1.add(subseq1);
+		
+		String keySeq2 = "seq2";
+		Collection<List<Event<?>>> seq2 = new LinkedList<List<Event<?>>>();
+		
+		assertFalse(instance.addData(keySeq1, seq1));
+		assertFalse(instance.addData(keySeq2, seq2));
+		
+		Collection<String> expected = new LinkedList<String>();
+		expected.add(keySeq1);
+		
+		assertCollectionContent(expected, instance.getAllSequencesNames());
+	}
+	
+	@Test
+	public void testGetAllSequencesNames_3() {
+		GlobalDataContainer instance = GlobalDataContainer.getInstance();
+		String key1 = "key1";
+		String data1 = "data1";
+		String key2 = "key2";
+		String data2 = "data2";
+		String key3 = "key3";
+		Integer data3 = 1;
+		String key4 = "key4";
+		Integer data4 = 2;
+		String key5 = "key5";
+		Integer data5 = 3;
+		
+		assertFalse(instance.addData(key1, data1));
+		assertFalse(instance.addData(key2, data2));
+		assertFalse(instance.addData(key3, data3));
+		assertFalse(instance.addData(key4, data4));
+		assertFalse(instance.addData(key5, data5));
+		
+		Collection<String> expected = new LinkedList<String>();
+		
+		assertCollectionContent(expected, instance.getAllSequencesNames());
+	}
+	
+	@Test
+	public void testGetAllModelNames_1() {
+		GlobalDataContainer instance = GlobalDataContainer.getInstance();
+		String key1 = "key1";
+		String data1 = "data1";
+		String key2 = "key2";
+		String data2 = "data2";
+		String key3 = "key3";
+		Integer data3 = 1;
+		String key4 = "key4";
+		Integer data4 = 2;
+		String key5 = "key5";
+		Integer data5 = 3;
+		
+		assertFalse(instance.addData(key1, data1));
+		assertFalse(instance.addData(key2, data2));
+		assertFalse(instance.addData(key3, data3));
+		assertFalse(instance.addData(key4, data4));
+		assertFalse(instance.addData(key5, data5));
+		
+		String modelKey1 = "model1";
+		IStochasticProcess model1 = mock(IStochasticProcess.class);
+		String modelKey2 = "model2";
+		IStochasticProcess model2 = mock(IStochasticProcess.class);
+				
+		assertFalse(instance.addData(modelKey1, model1));
+		assertFalse(instance.addData(modelKey2, model2));
+		
+		Collection<String> expected = new LinkedList<String>();
+		expected.add(modelKey1);
+		expected.add(modelKey2);
+		
+		assertCollectionContent(expected, instance.getAllModelNames());
+	}
+	
+	@Test
+	public void testGetAllModelNames_2() {
+		GlobalDataContainer instance = GlobalDataContainer.getInstance();
+		String key1 = "key1";
+		String data1 = "data1";
+		String key2 = "key2";
+		String data2 = "data2";
+		String key3 = "key3";
+		Integer data3 = 1;
+		String key4 = "key4";
+		Integer data4 = 2;
+		String key5 = "key5";
+		Integer data5 = 3;
+		
+		assertFalse(instance.addData(key1, data1));
+		assertFalse(instance.addData(key2, data2));
+		assertFalse(instance.addData(key3, data3));
+		assertFalse(instance.addData(key4, data4));
+		assertFalse(instance.addData(key5, data5));
+		
+		Collection<String> expected = new LinkedList<String>();
+		
+		assertCollectionContent(expected, instance.getAllModelNames());
+	}
+	
+	@Test
+	public void testSerialization_1() throws Exception {
+		GlobalDataContainer instance = GlobalDataContainer.getInstance();
+		String key1 = "key1";
+		String data1 = "data1";
+		String key2 = "key2";
+		String data2 = "data2";
+		String key3 = "key3";
+		Integer data3 = 1;
+		String key4 = "key4";
+		Integer data4 = 2;
+		String key5 = "key5";
+		Integer data5 = 3;
+		
+		String key6 = "key6";
+		Double data6 = 6.0d;
+
+		assertFalse(instance.addData(key1, data1));
+		assertFalse(instance.addData(key2, data2));
+		assertFalse(instance.addData(key3, data3));
+		assertFalse(instance.addData(key4, data4));
+		assertFalse(instance.addData(key5, data5));
+		
+		 // serialize
+	    ByteArrayOutputStream out = new ByteArrayOutputStream();
+	    ObjectOutputStream oos = new ObjectOutputStream(out);
+	    oos.writeObject(instance);
+	    oos.close();
+	    
+	    instance.reset();
+	    assertFalse(instance.addData(key6, data6));
+	    
+
+	    //deserialize
+	    byte[] pickled = out.toByteArray();
+	    InputStream in = new ByteArrayInputStream(pickled);
+	    ObjectInputStream ois = new ObjectInputStream(in);
+	    ois.readObject();
+	    ois.close();
+
+	    // test the result
+	    assertEquals(data1, instance.getData(key1));
+		assertEquals(data2, instance.getData(key2));
+		assertEquals(data3, instance.getData(key3));
+		assertEquals(data4, instance.getData(key4));
+		assertEquals(data5, instance.getData(key5));
+		assertNull(instance.getData(key6));
+	}
+	
+
+	@Before
+	public void setUp() {
+		GlobalDataContainer.getInstance().reset();
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/.classpath
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/.classpath	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/.classpath	(revision 540)
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/classes" path="src/main/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="src" output="target/test-classes" path="src/test/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/.project
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/.project	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/.project	(revision 540)
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>quest-ui-core</name>
+	<comment></comment>
+	<projects>
+		<project>Build</project>
+		<project>EventBenchCore</project>
+		<project>JavaHelperLib</project>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>net.sourceforge.metrics.builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>net.sourceforge.metrics.nature</nature>
+	</natures>
+</projectDescription>
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/.settings/org.eclipse.jdt.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/.settings/org.eclipse.jdt.core.prefs	(revision 540)
@@ -0,0 +1,12 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.6
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/.settings/org.eclipse.m2e.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/.settings/org.eclipse.m2e.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/.settings/org.eclipse.m2e.core.prefs	(revision 540)
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/misc/log4j.properties
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/misc/log4j.properties	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/misc/log4j.properties	(revision 540)
@@ -0,0 +1,10 @@
+log4j.rootLogger=TRACE, file
+
+log4j.appender.file=org.apache.log4j.RollingFileAppender
+log4j.appender.file.File=log/log4j.log
+
+log4j.appender.file.MaxFileSize=100KB
+log4j.appender.file.MaxBackupIndex=1
+
+log4j.appender.file.layout=org.apache.log4j.PatternLayout
+log4j.appender.file.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/misc/robotfilter.txt
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/misc/robotfilter.txt	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/misc/robotfilter.txt	(revision 540)
@@ -0,0 +1,66 @@
+findlinks
+discobot
+Googlebot
+Slurp
+YandexBot
+Spider
+ScholarUniverse
+Baiduspider
+Exabot
+Robot
+MetaGer-Bot
+YandexImages
+Gigabot
+SiteBot
+bingbot
+Ezooms
+Jeeves/Teoma
+msnbot
+DotBot
+changedetection.com/bot.html
+FAST Enterprise Crawler 6
+psbot
+http://ws.daum.net/aboutWebSearch.html
+NerdByNature.Bot
+Sogou web spider
+ssearch_bot
+Purebot
+http://www.icjobs.de
+scoutjet
+Netcraft Web Server Survey
+TurnitinBot
+ia_archiver
+MJ12bot
+Domnutch-Bot
+Eurobot
+GarlikCrawler
+CMS Crawler
+MSIECrawler
+NaverBot
+80legs
+AhrefsBot
+SISTRIX Crawler
+NetcraftSurveyAgent
+Search17Bot
+Semager
+YandexFavicons
+heritrix
+suggybot
+Netluchs
+Ocelli
+PHPCrawl
+SolomonoBot
+Sosospider
+Xerka WebBot
+YahooCacheSystem
+Xenu Link Sleuth
+cmsworldmap
+suchen.de
+amaredo.com/de/suche.html
+ibot
+w3af.sourceforge.net
+w3af.sf.net
+yacybot
+larbin2
+t-h-u-n-d-e-r-s-t-o-n-e
+sqlmap
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/pom.xml
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/pom.xml	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/pom.xml	(revision 540)
@@ -0,0 +1,91 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>de.ugoe.cs.quest</groupId>
+	<artifactId>quest-ui-core</artifactId>
+	<version>0.0.1-SNAPSHOT</version>
+	<name>quest-ui-core</name>
+	<scm>
+		<url>https://quest.informatik.uni-goettingen.de/svn/quest/trunk/quest-ui-core</url>
+	</scm>
+	<repositories>
+		<repository>
+			<id>quest-repo</id>
+			<url>https://trex.informatik.uni-goettingen.de/nexus/content/repositories/thirdparty</url>
+		</repository>
+	</repositories>
+	<dependencies>
+		<dependency>
+			<groupId>de.ugoe.cs</groupId>
+			<artifactId>java-utils</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+		</dependency>
+		<dependency>
+			<groupId>de.ugoe.cs.quest</groupId>
+			<artifactId>quest-core-events</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+		</dependency>
+		<dependency>
+			<groupId>de.ugoe.cs.quest</groupId>
+			<artifactId>quest-core-usageprofiles</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+		</dependency>
+		<dependency>
+			<groupId>de.ugoe.cs.quest</groupId>
+			<artifactId>quest-core-coverage</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+		</dependency>
+		<dependency>
+			<groupId>de.ugoe.cs.quest</groupId>
+			<artifactId>quest-core-assertions</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+		</dependency>
+		<dependency>
+			<groupId>de.ugoe.cs.quest</groupId>
+			<artifactId>quest-core-testgeneration</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+		</dependency>
+		<dependency>
+			<groupId>net.sf.jung</groupId>
+			<artifactId>jung-visualization</artifactId>
+			<version>2.0.1</version>
+		</dependency>
+		<dependency>
+			<groupId>net.sf.jung</groupId>
+			<artifactId>jung-graph-impl</artifactId>
+			<version>2.0.1</version>
+		</dependency>
+		<dependency>
+			<groupId>log4j</groupId>
+			<artifactId>log4j</artifactId>
+			<version>1.2.17</version>
+		</dependency>
+		<dependency>
+			<groupId>commons-codec</groupId>
+			<artifactId>commons-codec</artifactId>
+			<version>1.6</version>
+		</dependency>
+		<dependency>
+			<groupId>jdom</groupId>
+			<artifactId>jdom</artifactId>
+			<version>1.1</version>
+		</dependency>
+		<dependency>
+			<groupId>edu.umd.cs</groupId>
+			<artifactId>guitar-model-core</artifactId>
+			<version>1.0</version>
+		</dependency>
+	</dependencies>
+	<build>
+		<plugins>
+			<plugin>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>2.3.2</version>
+				<configuration>
+					<source>1.6</source>
+					<target>1.6</target>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+</project>
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/rules/ruleDoctype.dtd
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/rules/ruleDoctype.dtd	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/rules/ruleDoctype.dtd	(revision 540)
@@ -0,0 +1,160 @@
+<!ENTITY WM_NULL "0">
+<!ENTITY WM_CREATE "1">
+<!ENTITY WM_DESTROY "2">
+<!ENTITY WM_MOVE "3">
+<!ENTITY WM_SIZE "5">
+<!ENTITY WM_ACTIVATE "6">
+<!ENTITY WM_SETFOCUS "7">
+<!ENTITY WM_KILLFOCUS "8">
+<!ENTITY WM_ENABLE "10">
+<!ENTITY WM_SETREDRAW "11">
+<!ENTITY WM_SETTEXT "12">
+<!ENTITY WM_GETTEXT "13">
+<!ENTITY WM_GETTEXTLENGTH "14">
+<!ENTITY WM_PAINT "15">
+<!ENTITY WM_CLOSE "16">
+<!ENTITY WM_QUERYENDSESSION "17">
+<!ENTITY WM_QUIT "18">
+<!ENTITY WM_QUERYOPEN "19">
+<!ENTITY WM_ERASEBKGND "20">
+<!ENTITY WM_SYSCOLORCHANGE "21">
+<!ENTITY WM_ENDSESSION "22">
+<!ENTITY WM_SHOWWINDOW "24">
+<!ENTITY WM_CTLCOLOR "25">
+<!ENTITY WM_WININICHANGE "26">
+<!ENTITY WM_DEVMODECHANGE "27">
+<!ENTITY WM_ACTIVATEAPP "28">
+<!ENTITY WM_FONTCHANGE "29">
+<!ENTITY WM_TIMECHANGE "30">
+<!ENTITY WM_CANCELMODE "31">
+<!ENTITY WM_SETCURSOR "32">
+<!ENTITY WM_MOUSEACTIVATE "33">
+<!ENTITY WM_CHILDACTIVATE "34">
+<!ENTITY WM_QUEUESYNC "35">
+<!ENTITY WM_GETMINMAXINFO "36">
+<!ENTITY WM_PAINTICON "38">
+<!ENTITY WM_ICONERASEBKGND "39">
+<!ENTITY WM_NEXTDLGCTL "40">
+<!ENTITY WM_SPOOLERSTATUS "42">
+<!ENTITY WM_DRAWITEM "43">
+<!ENTITY WM_MEASUREITEM "44">
+<!ENTITY WM_DELETEITEM "45">
+<!ENTITY WM_VKEYTOITEM "46">
+<!ENTITY WM_CHARTOITEM "47">
+<!ENTITY WM_SETFONT "48">
+<!ENTITY WM_GETFONT "49">
+<!ENTITY WM_SETHOTKEY "50">
+<!ENTITY WM_GETHOTKEY "51">
+<!ENTITY WM_QUERYDRAGICON "55">
+<!ENTITY WM_COMPAREITEM "57">
+<!ENTITY WM_GETOBJECT "61">
+<!ENTITY WM_COMPACTING "65">
+<!ENTITY WM_COMMNOTIFY "68">
+<!ENTITY WM_WINDOWPOSCHANGING "70">
+<!ENTITY WM_WINDOWPOSCHANGED "71">
+<!ENTITY WM_POWER "72">
+<!ENTITY WM_COPYDATA "74">
+<!ENTITY WM_CANCELJOURNAL "75">
+<!ENTITY WM_NOTIFY "78">
+<!ENTITY WM_INPUTLANGCHANGEREQUEST "80">
+<!ENTITY WM_INPUTLANGCHANGE "81">
+<!ENTITY WM_TCARD "82">
+<!ENTITY WM_HELP "83">
+<!ENTITY WM_USERCHANGED "84">
+<!ENTITY WM_NOTIFYFORMAT "85">
+<!ENTITY WM_CONTEXTMENU "123">
+<!ENTITY WM_STYLECHANGING "124">
+<!ENTITY WM_STYLECHANGED "125">
+<!ENTITY WM_DISPLAYCHANGE "126">
+<!ENTITY WM_GETICON "127">
+<!ENTITY WM_SETICON "128">
+<!ENTITY WM_NCCREATE "129">
+<!ENTITY WM_NCDESTROY "130">
+<!ENTITY WM_NCCALCSIZE "131">
+<!ENTITY WM_NCHITTEST "132">
+<!ENTITY WM_NCPAINT "133">
+<!ENTITY WM_NCACTIVATE "134">
+<!ENTITY WM_GETDLGCODE "135">
+<!ENTITY WM_SYNCPAINT "136">
+<!ENTITY WM_NCMOUSEMOVE "160">
+<!ENTITY WM_NCLBUTTONDOWN "161">
+<!ENTITY WM_NCLBUTTONUP "162">
+<!ENTITY WM_NCLBUTTONDBLCLK "163">
+<!ENTITY WM_NCRBUTTONDOWN "164">
+<!ENTITY WM_NCRBUTTONUP "165">
+<!ENTITY WM_NCRBUTTONDBLCLK "166">
+<!ENTITY WM_NCMBUTTONDOWN "167">
+<!ENTITY WM_NCMBUTTONUP "168">
+<!ENTITY WM_NCMBUTTONDBLCLK "169">
+<!ENTITY WM_NCXBUTTONDOWN "171">
+<!ENTITY WM_NCXBUTTONUP "172">
+<!ENTITY WM_NCXBUTTONDBLCLK "173">
+<!ENTITY SBM_SETPOS "224">
+<!ENTITY BM_CLICK "245">
+<!ENTITY WM_INPUT "255">
+<!ENTITY WM_KEYDOWN "256">
+<!ENTITY WM_KEYFIRST "256">
+<!ENTITY WM_KEYUP "257">
+<!ENTITY WM_CHAR "258">
+<!ENTITY WM_DEADCHAR "259">
+<!ENTITY WM_SYSKEYDOWN "260">
+<!ENTITY WM_SYSKEYUP "261">
+<!ENTITY WM_SYSCHAR "262">
+<!ENTITY WM_SYSDEADCHAR "263">
+<!ENTITY WM_KEYLAST "264">
+<!ENTITY WM_WNT_CONVERTREQUESTEX "265">
+<!ENTITY WM_CONVERTREQUEST "266">
+<!ENTITY WM_CONVERTRESULT "267">
+<!ENTITY WM_INTERIM "268">
+<!ENTITY WM_IME_STARTCOMPOSITION "269">
+<!ENTITY WM_IME_ENDCOMPOSITION "270">
+<!ENTITY WM_IME_COMPOSITION "271">
+<!ENTITY WM_IME_KEYLAST "271">
+<!ENTITY WM_INITDIALOG "272">
+<!ENTITY WM_COMMAND "273">
+<!ENTITY WM_SYSCOMMAND "274">
+<!ENTITY WM_TIMER "275">
+<!ENTITY WM_HSCROLL "276">
+<!ENTITY WM_VSCROLL "277">
+<!ENTITY WM_INITMENU "278">
+<!ENTITY WM_INITMENUPOPUP "279">
+<!ENTITY WM_MENUSELECT "287">
+<!ENTITY WM_MENUCHAR "288">
+<!ENTITY WM_ENTERIDLE "289">
+<!ENTITY WM_MENURBUTTONUP "290">
+<!ENTITY WM_MENUDRAG "291">
+<!ENTITY WM_MENUGETOBJECT "292">
+<!ENTITY WM_UNINTMENUPOPUP "293">
+<!ENTITY WM_MENUCOMMAND "294">
+<!ENTITY WM_CHANGEUISTATE "295">
+<!ENTITY WM_UPDATEUISTATE "296">
+<!ENTITY WM_QUERYUISTATE "297">
+<!ENTITY WM_CTLCOLORMSGBOX "306">
+<!ENTITY WM_CTLCOLOREDIT "307">
+<!ENTITY WM_CTLCOLORLISTBOX "308">
+<!ENTITY WM_CTLCOLORBTN "309">
+<!ENTITY WM_CTLCOLORDLG "310">
+<!ENTITY WM_CTLCOLORSCROLLBAR "311">
+<!ENTITY WM_CTLCOLORSTATIC "312">
+<!ENTITY CB_SHOWDROPDOWN "335">
+<!ENTITY LB_SETCURSEL "390">
+<!ENTITY WM_MOUSEFIRST "512">
+<!ENTITY WM_MOUSEMOVE "512">
+<!ENTITY WM_LBUTTONDOWN "513">
+<!ENTITY WM_LBUTTONUP "514">
+<!ENTITY WM_LBUTTONDBLCLK "515">
+<!ENTITY WM_RBUTTONDOWN "516">
+<!ENTITY WM_RBUTTONUP "517">
+<!ENTITY WM_RBUTTONDBLCLK "518">
+<!ENTITY WM_MBUTTONDOWN "519">
+<!ENTITY WM_MBUTTONUP "520">
+<!ENTITY WM_MBUTTONDBLCLK "521">
+<!ENTITY WM_MOUSELAST "521">
+<!ENTITY WM_MOUSEWHEEL "522">
+<!ENTITY WM_XBUTTONDOWN "523">
+<!ENTITY WM_XBUTTONUP "524">
+<!ENTITY WM_XBUTTONDBLCLK "525">
+<!ENTITY WM_USER "1024">
+<!ENTITY CB_SETCURSEL "334">
+<!ENTITY TBM_SETPOS "1029">
+<!ENTITY TCM_SETCURSEL "4876">
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/rules/ruleSchema.xsd
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/rules/ruleSchema.xsd	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/rules/ruleSchema.xsd	(revision 540)
@@ -0,0 +1,209 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<xs:schema targetNamespace="ul:rules"
+    elementFormDefault="qualified"
+    xmlns="ul:rules"
+    xmlns:xs="http://www.w3.org/2001/XMLSchema"
+>
+
+  <xs:element name="rules">
+    <xs:complexType>
+      <xs:sequence minOccurs="0" maxOccurs="unbounded">
+        <xs:element name="rule" type="ruleType"/>
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
+
+  <!-- rule type definition -->
+  <xs:complexType name="ruleType">
+    <xs:sequence>
+      <xs:element name="msg" type="msgType" minOccurs="0" maxOccurs="unbounded"/>
+      <xs:choice minOccurs="0" maxOccurs="unbounded">
+        <xs:element name="genMsg" type="genMsgType"/>
+        <xs:element name="genMsgSeq" type="genMsgSeqType"/>
+      </xs:choice>
+      <xs:element name="idinfo" type="varType" minOccurs="0" maxOccurs="1"/>
+    </xs:sequence>
+    <xs:attribute name="name" type="xs:string" use="optional"/>
+  </xs:complexType>
+
+  <!-- message type definition -->
+  <xs:complexType name="msgType">
+    <xs:sequence minOccurs="0" maxOccurs="1">
+      <xs:choice minOccurs="0" maxOccurs="unbounded">
+        <xs:element name="equals" type="equalsType"/>
+        <xs:element name="equalsSeq" type="equalsSeqType"/>
+      </xs:choice>
+      <xs:choice minOccurs="0" maxOccurs="unbounded">
+        <xs:element name="store" type="storeType"/>
+        <xs:element name="storeSeq" type="storeSeqType"/>
+      </xs:choice>
+    </xs:sequence>
+    <xs:attribute name="type" type="xs:int" use="required"/>
+    <!-- problem: should be strings like WM_LBUTTONDOWN, but program needs ints -->
+    <!--<xs:attribute name="type" type="xs:string" use="required"/>-->
+    <xs:attribute name="multiple" type="xs:boolean" use="optional"/>
+  </xs:complexType>
+  
+  <!-- storage types for message nodes -->
+  <!-- a restriction forbidding "this" would be nice -->
+  <xs:complexType name="storeType">
+    <xs:sequence>
+      <xs:element name="resolveHwnd" type="resolveTargetType" minOccurs="0" maxOccurs="unbounded"/>
+    </xs:sequence>
+    <xs:attribute name="var" use="required" type="storVarName"/>
+  </xs:complexType>
+  <xs:complexType name="storeSeqType">
+    <xs:sequence>
+      <xs:element name="resolveHwnd" type="resolveTargetType" minOccurs="0" maxOccurs="unbounded"/>
+    </xs:sequence>
+    <xs:attribute name="varSeq" use="required" type="storVarName"/>
+  </xs:complexType>
+  <xs:complexType name="resolveTargetType">
+    <xs:attribute name="param" type="xs:string"/>
+    <xs:attribute name="storeParam" type="xs:string"/>
+  </xs:complexType>
+  
+  <!-- equals type for message nodes -->
+  <xs:complexType name="equalsType">
+    <xs:sequence minOccurs="2" maxOccurs="2">
+      <xs:group ref="valueGroup"/>
+    </xs:sequence>
+  </xs:complexType>
+  <xs:complexType name="equalsSeqType">
+    <xs:sequence>
+      <xs:element name="seqValue" type="seqValueType"/>
+      <xs:choice>
+        <xs:group ref="seqValueGroup"/>
+      </xs:choice>
+    </xs:sequence>
+  </xs:complexType>
+
+  <!-- types for generating messages -->
+  <xs:complexType name="genMsgType">
+    <xs:choice>
+      <xs:sequence>
+        <xs:element name="type" type="varType"/>
+        <xs:element name="target" type="varType"/>
+        <xs:element name="LPARAM" type="PARAMtype" minOccurs="0" maxOccurs="1"/>
+        <xs:element name="WPARAM" type="PARAMtype" minOccurs="0" maxOccurs="1"/>
+      </xs:sequence>
+      <xs:element name="storedVar">
+        <xs:complexType>
+          <xs:attribute name="obj" type="xs:string"/>
+        </xs:complexType>
+      </xs:element>
+    </xs:choice>
+    <xs:attribute name="delay" type="xs:int" use="required"/>
+  </xs:complexType>
+  <xs:complexType name="genMsgSeqType">
+    <xs:choice>
+      <xs:sequence>
+        <xs:element name="type" type="seqType"/>
+        <!-- target must be a variable! -->
+        <xs:element name="target">
+          <xs:complexType >
+            <xs:sequence>
+              <xs:element name="seqValue" type="seqValueType"/>
+            </xs:sequence>
+          </xs:complexType>
+        </xs:element>        
+        <xs:element name="LPARAM" type="seqPARAMtype" minOccurs="0" maxOccurs="1"/>
+        <xs:element name="WPARAM" type="seqPARAMtype" minOccurs="0" maxOccurs="1"/>
+      </xs:sequence>
+      <xs:element name="storedSeqVar">
+        <xs:complexType>
+          <xs:attribute name="seqObj" type="xs:string"/>
+        </xs:complexType>
+      </xs:element>
+    </xs:choice>
+    <xs:attribute name="delay" type="xs:int" use="required"/>
+  </xs:complexType>
+
+  <xs:complexType name="PARAMtype">
+    <xs:choice>
+      <xs:group ref="valueGroup"/>
+      <xs:sequence>
+        <xs:element name="LOWORD" type="varType"/>
+        <xs:element name="HIWORD" type="varType"/>
+      </xs:sequence>
+    </xs:choice>
+  </xs:complexType>
+  
+  <xs:complexType name="seqPARAMtype">
+    <xs:choice>
+      <xs:group ref="seqValueGroup"/>
+      <xs:sequence>
+        <xs:element name="LOWORD" type="seqType"/>
+        <xs:element name="HIWORD" type="seqType"/>
+      </xs:sequence>
+    </xs:choice>
+  </xs:complexType>
+  
+  
+  <xs:complexType name="seqValueType">
+    <xs:attribute name ="seqObj" type="xs:string" use="required"/>
+    <xs:attribute name ="param" type="xs:string" use="required"/>
+  </xs:complexType>
+
+  <!-- values that can be used by equals and genMsg nodes -->
+  <xs:group name="valueGroup">
+    <xs:choice>
+      <xs:element name="paramValue" type="paramValueType"/>
+      <xs:element name="constValue" type="constValueType"/>
+      <xs:element name="winInfoValue" type ="winInfoValueType"/>
+      <xs:element name="msgInfoValue" type="msgInfoType"/>
+    </xs:choice>
+  </xs:group>
+  <xs:complexType name="varType">
+    <xs:group ref="valueGroup"/>
+  </xs:complexType>
+  
+  <xs:group name="seqValueGroup">
+    <xs:choice>
+      <xs:element name="constValue" type="constValueType"/>
+      <xs:element name="seqValue" type="seqValueType"/>
+    </xs:choice>
+  </xs:group>
+  <xs:complexType name="seqType">
+    <xs:group ref="seqValueGroup"/>
+  </xs:complexType>
+  
+  <xs:complexType name="paramValueType">
+    <xs:attribute name="obj" type="xs:string" use="required"/>
+    <xs:attribute name="param" type="xs:string" use="required"/>
+  </xs:complexType>
+  <xs:complexType name="constValueType">
+    <xs:attribute name="value" use="required"/>
+  </xs:complexType>
+  <xs:complexType name="winInfoValueType">
+    <xs:attribute name="obj" type="xs:string" use="required"/>
+    <xs:attribute name="winParam" type="winParamType" use="required"/>
+  </xs:complexType>
+  <xs:complexType name="msgInfoType">
+    <xs:attribute name="obj" type="xs:string" use="required"/>
+    <xs:attribute name="msgParam" type="msgParamType" use="required"/>
+  </xs:complexType>
+  <xs:simpleType name="winParamType">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="class"/>
+      <xs:enumeration value="resourceId"/>
+      <xs:enumeration value="hwnd"/>
+      <xs:enumeration value="parentTarget"/>
+      <xs:enumeration value="parentClass"/>
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:simpleType name="msgParamType">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="type"/>
+      <xs:enumeration value="target"/>
+    </xs:restriction>
+  </xs:simpleType>
+  
+
+  <xs:simpleType name="storVarName">
+    <xs:restriction base="xs:string">
+      <!-- this regex is formally not supported by XMLSchema, als look-arounds and \b are not supported :/ -->
+      <xs:pattern value="(?:(?!(?>\bthis\b))\w)+"/>
+    </xs:restriction>
+  </xs:simpleType>
+</xs:schema>
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/rules/rules.xml
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/rules/rules.xml	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/rules/rules.xml	(revision 540)
@@ -0,0 +1,1079 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE rules SYSTEM "ruleDoctype.dtd">
+<rules xmlns="ul:rules" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="ul:rules ruleSchema.xsd">
+
+  <!-- rules regarding mouse clicks -->
+  <rule name="LeftClickButton">
+    <msg type="&WM_LBUTTONDOWN;">
+      <store var="clicked"/>
+    </msg>
+    <msg type="&WM_LBUTTONUP;">
+      <equals>
+        <constValue value="Button"/>
+        <winInfoValue obj="this" winParam="class"/>
+      </equals>
+      <equals>
+        <paramValue obj="clicked" param="window.hwnd"/>
+        <paramValue obj="this" param="window.hwnd"/>
+      </equals>
+    </msg>
+    <genMsg delay="500">
+      <type>
+        <constValue value="&BM_CLICK;"/>
+      </type>
+      <target>
+        <msgInfoValue obj="clicked" msgParam="target"/>
+      </target>
+    </genMsg>
+  </rule>
+
+  <rule name="LeftClickListBox">
+    <msg type="&WM_LBUTTONDOWN;">
+      <equals>
+        <winInfoValue obj="this" winParam="class"/>
+        <constValue value="ListBox"/>
+      </equals>
+      <store var="clicked"/>
+    </msg>
+    <msg type="&WM_LBUTTONUP;">
+      <equals>
+        <paramValue obj="this" param="window.hwnd"/>
+        <paramValue obj="clicked" param="window.hwnd"/>
+      </equals>
+      <store var="up"/>
+    </msg>
+    <genMsg delay="500">
+      <type>
+        <constValue value="&LB_SETCURSEL;"/>
+      </type>
+      <target>
+        <msgInfoValue obj="clicked" msgParam="target"/>
+      </target>
+      <WPARAM>
+        <paramValue obj="up" param="scrollPos"/>
+      </WPARAM>
+    </genMsg>
+  </rule>
+
+  <rule name="TabChange">
+    <msg type="&WM_LBUTTONDOWN;">
+      <equals>
+        <constValue value="SysTabControl32"/>
+        <winInfoValue obj="this" winParam="class"/>
+      </equals>
+      <store var="clicked"/>
+    </msg>
+    <msg type="&WM_LBUTTONUP;">
+      <equals>
+        <paramValue obj="this" param="window.hwnd"/>
+        <paramValue obj="clicked" param="window.hwnd"/>
+      </equals>
+      <store var="up"/>
+    </msg>
+    <!-- tab change message for Tab Controls-->
+    <genMsg delay="100">
+      <type>
+        <constValue value="&TCM_SETCURSEL;"/>
+      </type>
+      <target>
+        <msgInfoValue obj="up" msgParam="target"/>
+      </target>
+      <WPARAM>
+        <paramValue obj="up" param="scrollPos"/>
+      </WPARAM>
+    </genMsg>
+    <!-- tab change message for Property Pages-->
+    <genMsg delay="500">
+      <type>
+        <constValue value="1125"/>
+      </type>
+      <target>
+        <winInfoValue obj="up" winParam="parentTarget"/>
+      </target>
+      <WPARAM>
+        <paramValue obj="up" param="scrollPos"/>
+      </WPARAM>
+    </genMsg>
+  </rule>
+
+<!--
+  <rule name="ComboBox">
+    <msg type="&WM_LBUTTONDOWN;">
+      <equals>
+        <winInfoValue obj="this" winParam="class"/>
+        <constValue value="ComboBox"/>
+      </equals>
+      <store var="clicked"/>
+    </msg>
+    <msg type="&WM_COMMAND;">
+      <equals>
+        <paramValue obj="this" param="window.hwnd"/>
+        <paramValue obj="clicked" param="window.hwnd"/>
+      </equals>
+      <store var="cmd1">
+        <resolveHwnd param="source" storeParam="sourceDesc"/>
+      </store>
+    </msg>
+    <msg type="&WM_COMMAND;" multiple="true">
+      <equals>
+        <paramValue obj="this" param="source"/>
+        <paramValue obj="clicked" param="window.hwnd"/>
+      </equals>
+      <storeSeq varSeq="cmds">
+        <resolveHwnd param="window.hwnd" storeParam="msgTarget"/>
+        <resolveHwnd param="source" storeParam="sourceDesc"/>
+      </storeSeq>
+    </msg>
+    <msg type="&WM_LBUTTONUP;">
+      <equals>
+        <paramValue obj="this" param="window.hwnd"/>
+        <paramValue obj="clicked" param="window.hwnd"/>
+      </equals>
+    </msg>
+    <genMsg delay="100">
+      <type>
+        <constValue value="&WM_SETFOCUS;"/>
+      </type>
+      <target>
+        <msgInfoValue obj="clicked" msgParam="target"/>
+      </target>
+    </genMsg>
+    <genMsg delay="500">
+      <type>
+        <constValue value="&CB_SHOWDROPDOWN;"/>
+      </type>
+      <target>
+        <msgInfoValue obj="clicked" msgParam="target"/>
+      </target>
+      <WPARAM>
+        <constValue value="1"/>
+      </WPARAM>
+    </genMsg>
+    <!-
+    <genMsg delay="100">
+      <type>
+        <constValue value="273"/>
+      </type>
+      <target>
+        <msgInfoValue obj="cmd1" msgParam="target"/>
+      </target>
+      <LPARAM>
+        <paramValue obj="cmd1" param="sourceDesc"/>
+      </LPARAM>
+      <WPARAM>
+        <paramValue obj="cmd1" param="WPARAM"/>
+      </WPARAM>
+    </genMsg>
+    <genMsgSeq delay="50">
+      <type>
+        <constValue value="273"/>
+      </type>
+      <target>
+        <seqValue seqObj="cmds" param="msgTarget"/>
+      </target>
+      <LPARAM>
+        <seqValue seqObj="cmds" param ="sourceDesc"/>
+      </LPARAM>
+      <WPARAM>
+        <seqValue seqObj="cmds" param="WPARAM"/>
+      </WPARAM>
+    </genMsgSeq>->
+  </rule>
+  <rule name="ComboLBox">
+    <msg type="&WM_LBUTTONDOWN;">
+      <equals>
+        <winInfoValue obj="this" winParam="class"/>
+        <constValue value="ComboLBox"/>
+      </equals>
+      <store var="clicked"/>
+    </msg>
+    <msg type="&WM_COMMAND;">
+      <equals>
+        <paramValue obj="this" param="window.hwnd"/>
+        <paramValue obj="clicked" param="window.hwnd"/>
+      </equals>
+      <store var="cmd1">
+        <resolveHwnd param="source" storeParam="sourceDesc"/>
+      </store>
+    </msg>
+    <msg type="&WM_COMMAND;" multiple="true">
+      <equals>
+        <paramValue obj="this" param="source"/>
+        <paramValue obj="clicked" param="window.hwnd"/>
+      </equals>
+      <storeSeq varSeq="cmds">
+        <resolveHwnd param="window.hwnd" storeParam="msgTarget"/>
+        <resolveHwnd param="source" storeParam="sourceDesc"/>
+      </storeSeq>
+    </msg>
+    <msg type="&WM_LBUTTONUP;">
+      <equals>
+        <paramValue obj="this" param="window.hwnd"/>
+        <paramValue obj="clicked" param="window.hwnd"/>
+      </equals>
+    </msg>
+    <genMsg delay="100">
+      <type>
+        <constValue value="&WM_SETFOCUS;"/>
+      </type>
+      <target>
+        <msgInfoValue obj="clicked" msgParam="target"/>
+      </target>
+    </genMsg>
+    <genMsg delay="500">
+      <type>
+        <constValue value="&CB_SHOWDROPDOWN;"/>
+      </type>
+      <target>
+        <msgInfoValue obj="clicked" msgParam="target"/>
+      </target>
+      <WPARAM>
+        <constValue value="1"/>
+      </WPARAM>
+    </genMsg>
+  </rule>
+  
+  <rule name="LeftClickCommandComboLBox">
+    <msg type="&WM_LBUTTONDOWN;">
+      <equals>
+        <constValue value="ComboLBox"/>
+        <winInfoValue obj="this" winParam="class"/>
+      </equals>
+      <store var="clicked"/>
+    </msg>
+    <msg type="&WM_LBUTTONUP;">
+      <equals>
+        <paramValue obj="clicked" param="window.hwnd"/>
+        <paramValue obj="this" param="window.hwnd"/>
+      </equals>
+      <store var="up"/>
+    </msg>
+    <msg type="&WM_COMMAND;">
+      <equals>
+        <paramValue obj="clicked" param="window.hwnd"/>
+        <paramValue obj="this" param="source"/>
+      </equals>
+      <store var="cmd1">
+        <resolveHwnd param="source" storeParam="sourceDesc"/>
+      </store>
+    </msg>
+    <msg type="&WM_COMMAND;" multiple="true">
+      <equals>
+        <paramValue obj="this" param="source"/>
+        <paramValue obj="cmd1" param="window.hwnd"/>
+      </equals>
+      <storeSeq varSeq="cmds">
+        <resolveHwnd param="window.hwnd" storeParam="target"/>
+        <resolveHwnd param="source" storeParam="sourceDesc"/>
+      </storeSeq>
+    </msg>
+    <genMsg delay="100">
+      <type>
+        <constValue value="&CB_SETCURSEL;"/>
+      </type>
+      <target>
+        <msgInfoValue obj="up" msgParam="target"/>
+      </target>
+      <WPARAM>
+        <constValue value="1"/>
+        <!-<paramValue obj="up" param="scrollPos"/>->
+      </WPARAM>
+    </genMsg>
+    <genMsg delay="100">
+      <type>
+        <constValue value="&CB_SHOWDROPDOWN;"/>
+      </type>
+      <target>
+        <winInfoValue obj="clicked" winParam="parentTarget"/>
+      </target>
+      <WPARAM>
+        <constValue value="0"/>
+      </WPARAM>
+    </genMsg>
+    <genMsg delay="100">
+      <type>
+        <constValue value="&WM_COMMAND;"/>
+      </type>
+      <target>
+        <winInfoValue obj="cmd1" winParam="parentTarget"/>
+      </target>
+      <LPARAM>
+        <paramValue obj="cmd1" param="sourceDesc"/>
+      </LPARAM>
+      <WPARAM>
+        <paramValue obj="cmd1" param="WPARAM"/>
+      </WPARAM>
+    </genMsg>
+    <genMsgSeq delay="100">
+      <type>
+        <constValue value="&WM_COMMAND;"/>
+      </type>
+      <target>
+        <seqValue seqObj="cmds" param="target"/>
+      </target>
+      <LPARAM>
+        <seqValue seqObj="cmds" param="sourceDesc"/>
+      </LPARAM>
+      <WPARAM>
+        <seqValue seqObj="cmds" param="WPARAM"/>
+      </WPARAM>
+    </genMsgSeq>
+  </rule>-->
+
+  <rule name="LeftClickCommand">
+    <msg type="&WM_LBUTTONDOWN;">
+      <store var="clicked"/>
+    </msg>
+    <msg type="&WM_LBUTTONUP;">
+      <equals>
+        <paramValue obj="clicked" param="window.hwnd"/>
+        <paramValue obj="this" param="window.hwnd"/>
+      </equals>
+    </msg>
+    <msg type="&WM_COMMAND;">
+      <equals>
+        <paramValue obj="clicked" param="window.hwnd"/>
+        <paramValue obj="this" param="source"/>
+      </equals>
+      <store var="cmd">
+        <resolveHwnd param="source" storeParam="sourceDesc"/>
+      </store>
+    </msg>
+    <genMsg delay="500">
+      <type>
+        <msgInfoValue obj="cmd" msgParam="type"/>
+      </type>
+      <target>
+        <msgInfoValue obj="cmd" msgParam="target"/>
+      </target>
+      <LPARAM>
+        <paramValue obj="cmd" param="sourceDesc"/>
+      </LPARAM>
+      <WPARAM>
+        <paramValue obj="cmd" param="WPARAM"/>
+      </WPARAM>
+    </genMsg>
+  </rule>
+
+  <rule name="LeftClickSysCommand">
+    <msg type="&WM_LBUTTONDOWN;">
+      <store var="clicked"/>
+    </msg>
+    <msg type="&WM_LBUTTONUP;">
+      <equals>
+        <paramValue obj="clicked" param="window.hwnd"/>
+        <paramValue obj="this" param="window.hwnd"/>
+      </equals>
+    </msg>
+    <msg type="&WM_SYSCOMMAND;">
+      <store var="cmd"/>
+    </msg>
+    <genMsg delay="500">
+      <storedVar obj="cmd"/>
+    </genMsg>
+  </rule>
+
+  <rule name="NCLeftClickSysCommand">
+    <msg type="&WM_NCLBUTTONDOWN;">
+      <store var="clicked"/>
+    </msg>
+    <msg type="&WM_LBUTTONUP;">
+      <equals>
+        <paramValue obj="clicked" param="window.hwnd"/>
+        <paramValue obj="this" param="window.hwnd"/>
+      </equals>
+    </msg>
+    <msg type="&WM_SYSCOMMAND;">
+      <equals>
+        <paramValue obj="clicked" param="window.hwnd"/>
+        <paramValue obj="this" param="window.hwnd"/>
+      </equals>
+      <store var="cmd"/>
+    </msg>
+    <genMsg delay="500">
+      <storedVar obj="cmd"/>
+    </genMsg>
+  </rule>
+
+  <rule name="LeftClickMenuItemCmd">
+    <msg type="&WM_LBUTTONDOWN;">
+      <store var="clicked"/>
+    </msg>
+    <msg type="&WM_LBUTTONUP;">
+      <equals>
+        <paramValue obj="clicked" param="window.hwnd"/>
+        <paramValue obj="this" param="window.hwnd"/>
+      </equals>
+    </msg>
+    <msg type="&WM_MENUSELECT;">
+      <equals>
+        <paramValue obj="clicked" param="window.hwnd"/>
+        <paramValue obj="this" param="window.hwnd"/>
+      </equals>
+    </msg>
+    <msg type="&WM_COMMAND;">
+      <equals>
+        <paramValue obj="this" param="sourceType"/>
+        <constValue value="0"/>
+      </equals>
+      <store var="cmd"/>
+    </msg>
+    <genMsg delay="500">
+      <storedVar obj="cmd"/>
+    </genMsg>
+  </rule>
+
+ 
+  <!-- rules involving mouse movement -->
+  <rule name="HScroll_TrackBar">
+    <msg type="&WM_LBUTTONDOWN;">
+      <equals>
+        <winInfoValue obj="this" winParam="class"/>
+        <constValue value="msctls_trackbar32"/>
+      </equals>
+      <store var="clicked"/>
+    </msg>
+    <msg type="&WM_HSCROLL;" multiple="true">
+      <equals>
+        <paramValue obj="this" param="scrollBarHandle"/>
+        <paramValue obj="clicked" param="window.hwnd"/>
+      </equals>
+      <storeSeq varSeq="scrolls">
+        <resolveHwnd param="scrollBarHandle" storeParam="scrollBarTarget"/>
+      </storeSeq>
+    </msg>    
+    <msg type="&WM_LBUTTONUP;">
+      <equals>
+        <paramValue obj="this" param="window.hwnd"/>
+        <paramValue obj="clicked" param="window.hwnd"/>
+      </equals>
+    </msg>
+    <genMsgSeq delay="50">
+      <type>
+        <constValue value="&TBM_SETPOS;"/>
+      </type>
+      <target>
+        <seqValue seqObj="scrolls" param="scrollBarTarget"/>
+      </target>
+      <LPARAM>
+        <seqValue seqObj="scrolls" param="scrollPos"/>
+      </LPARAM>
+      <WPARAM>
+        <constValue value="1"/>
+      </WPARAM>
+    </genMsgSeq>
+  </rule>
+
+
+  <rule name="VScroll_TrackBar">
+    <msg type="&WM_LBUTTONDOWN;">
+      <equals>
+        <winInfoValue obj="this" winParam="class"/>
+        <constValue value="msctls_trackbar32"/>
+      </equals>
+      <store var="clicked"/>
+    </msg>
+    <msg type="&WM_VSCROLL;" multiple="true">
+      <equals>
+        <paramValue obj="this" param="scrollBarHandle"/>
+        <paramValue obj="clicked" param="window.hwnd"/>
+      </equals>
+      <storeSeq varSeq="scrolls">
+        <resolveHwnd param="scrollBarHandle" storeParam="scrollBarTarget"/>
+      </storeSeq>
+    </msg>
+    <msg type="&WM_LBUTTONUP;">
+      <equals>
+        <paramValue obj="this" param="window.hwnd"/>
+        <paramValue obj="clicked" param="window.hwnd"/>
+      </equals>
+    </msg>
+    <genMsgSeq delay="50">
+      <type>
+        <constValue value="&TBM_SETPOS;"/>
+      </type>
+      <target>
+        <seqValue seqObj="scrolls" param="scrollBarTarget"/>
+      </target>
+      <LPARAM>
+        <seqValue seqObj="scrolls" param="scrollPos"/>
+      </LPARAM>
+      <WPARAM>
+        <constValue value="1"/>
+      </WPARAM>
+    </genMsgSeq>
+  </rule>
+
+
+  <rule name="HScroll_ScrollBar">
+    <msg type="&WM_LBUTTONDOWN;">
+      <equals>
+        <winInfoValue obj="this" winParam="class"/>
+        <constValue value="ScrollBar"/>
+      </equals>
+      <store var="clicked"/>
+    </msg>
+    <msg type="&WM_HSCROLL;" multiple="true">
+      <equals>
+        <paramValue obj="this" param="scrollBarHandle"/>
+        <paramValue obj="clicked" param="window.hwnd"/>
+      </equals>
+      <storeSeq varSeq="scrolls">
+        <resolveHwnd param="scrollBarHandle" storeParam="scrollBarTarget"/>
+      </storeSeq>
+    </msg>
+    <msg type="&WM_LBUTTONUP;">
+      <equals>
+        <paramValue obj="this" param="window.hwnd"/>
+        <paramValue obj="clicked" param="window.hwnd"/>
+      </equals>
+    </msg>
+    <genMsgSeq delay="50">
+      <type>
+        <constValue value="&SBM_SETPOS;"/>
+      </type>
+      <target>
+        <seqValue seqObj="scrolls" param="scrollBarTarget"/>
+      </target>
+      <LPARAM>
+        <constValue value="1"/>
+      </LPARAM>
+      <WPARAM>
+        <seqValue seqObj="scrolls" param="scrollPos"/>
+      </WPARAM>
+    </genMsgSeq>
+  </rule>
+
+
+  <rule name="VScroll_ScrollBar">
+    <msg type="&WM_LBUTTONDOWN;">
+      <equals>
+        <winInfoValue obj="this" winParam="class"/>
+        <constValue value="ScrollBar"/>
+      </equals>
+      <store var="clicked"/>
+    </msg>
+    <msg type="&WM_VSCROLL;" multiple="true">
+      <equals>
+        <paramValue obj="this" param="scrollBarHandle"/>
+        <paramValue obj="clicked" param="window.hwnd"/>
+      </equals>
+      <storeSeq varSeq="scrolls">
+        <resolveHwnd param="scrollBarHandle" storeParam="scrollBarTarget"/>
+      </storeSeq>
+    </msg>
+    <msg type="&WM_LBUTTONUP;">
+      <equals>
+        <paramValue obj="this" param="window.hwnd"/>
+        <paramValue obj="clicked" param="window.hwnd"/>
+      </equals>
+    </msg>
+    <genMsgSeq delay="50">
+      <type>
+        <constValue value="&SBM_SETPOS;"/>
+      </type>
+      <target>
+        <seqValue seqObj="scrolls" param="scrollBarTarget"/>
+      </target>
+      <LPARAM>
+        <constValue value="1"/>
+      </LPARAM>
+      <WPARAM>
+        <seqValue seqObj="scrolls" param="scrollPos"/>
+      </WPARAM>
+    </genMsgSeq>
+  </rule>
+  
+  <!-- Does not work correctly, if a scrollbar has no handle of its own, e.g., a standard scrollbar of a listbox -->
+  <rule name="VScrollNC">
+    <msg type="&WM_NCLBUTTONDOWN;">
+      <store var="clicked"/>
+    </msg>
+    <msg type="&WM_VSCROLL;">
+      <equals>
+        <paramValue obj="this" param="window.hwnd"/>
+        <paramValue obj="clicked" param="window.hwnd"/>
+      </equals>
+      <store var="scrolls"/>
+    </msg>
+    <genMsg delay="50">
+      <type>
+        <constValue value="&WM_VSCROLL;"/>
+      </type>
+      <target>
+        <msgInfoValue obj="clicked" msgParam="target"/>
+      </target>
+      <WPARAM>
+        <LOWORD>
+          <constValue value="4"/>
+        </LOWORD>
+        <HIWORD>
+          <paramValue obj="scrolls" param="scrollPos"/>
+        </HIWORD>
+      </WPARAM>
+    </genMsg>
+  </rule>
+
+
+  <!--<rule name="VScrollNC">
+    <msg type="&WM_NCLBUTTONDOWN;">
+      <store var="clicked"/>
+    </msg>
+    <msg type="&WM_VSCROLL;" multiple="true">
+      <equals>
+        <paramValue obj="this" param="window.hwnd"/>
+        <paramValue obj="clicked" param="window.hwnd"/>
+      </equals>
+      <storeSeq varSeq="scrolls">
+        <resolveHwnd param="window.hwnd" storeParam="scrollBarTarget"/>
+      </storeSeq>
+    </msg>
+    <genMsgSeq delay="20">
+      <type>
+        <constValue value="&WM_VSCROLL;"/>
+      </type>
+      <target>
+        <seqValue seqObj="scrolls" param="scrollBarTarget"/>
+      </target>
+      <WPARAM>
+        <LOWORD>
+          <constValue value="4"/>
+        </LOWORD>
+        <HIWORD>
+          <paramValue obj="scrolls" param="scrollPos"/>
+        </HIWORD>
+      </WPARAM>
+    </genMsgSeq>
+  </rule>-->
+
+  <!-- Copy of set focus without kill-focus -->
+  <rule name="LeftClickSetFocus">
+    <msg type="&WM_LBUTTONDOWN;">
+      <equals>
+        <winInfoValue obj="this" winParam="class"/>
+        <constValue value="Edit"/>
+      </equals>
+      <store var="clicked"/>
+    </msg>
+    <msg type="&WM_SETFOCUS;">
+      <store var="setfocus"/>
+    </msg>
+    <msg type="&WM_COMMAND;">
+      <equals>
+        <paramValue obj="this" param="source"/>
+        <paramValue obj="clicked" param="window.hwnd"/>
+      </equals>
+      <equals>
+        <paramValue obj="this" param="sourceType"/>
+        <constValue value="256"/>
+      </equals>
+      <store var="cmd"/>
+    </msg>
+    <msg type="&WM_LBUTTONUP;">
+      <equals>
+        <paramValue obj="this" param="window.hwnd"/>
+        <paramValue obj="clicked" param="window.hwnd"/>
+      </equals>
+    </msg>
+    <genMsg delay="20">
+      <type>
+        <constValue value="&WM_SETFOCUS;"/>
+      </type>
+      <target>
+        <msgInfoValue obj="setfocus" msgParam="target"/>
+      </target>
+      <WPARAM>
+        <constValue value="0"/>
+      </WPARAM>
+    </genMsg>
+    <genMsg delay="500">
+      <type>
+        <constValue value="&WM_COMMAND;"/>
+      </type>
+      <target>
+        <msgInfoValue obj="cmd" msgParam="target"/>
+      </target>
+      <LPARAM>
+        <msgInfoValue obj="setfocus" msgParam="target"/>
+      </LPARAM>
+      <WPARAM>
+        <paramValue obj="cmd" param="WPARAM"/>
+      </WPARAM>
+    </genMsg>
+  </rule>
+  
+  <!-- Works only partially! -->
+  <rule name="LeftClickChangeFocus">
+    <msg type="&WM_LBUTTONDOWN;">
+      <equals>
+        <winInfoValue obj="this" winParam="class"/>
+        <constValue value="Edit"/>
+      </equals>
+      <store var="clicked"/>
+    </msg>
+    <msg type="&WM_KILLFOCUS;">
+      <store var="killfocus"/>
+    </msg>
+    <msg type="&WM_SETFOCUS;">
+      <equals>
+        <paramValue obj="this" param="WPARAM"/>
+        <paramValue obj="killfocus" param="window.hwnd"/>
+      </equals>
+      <store var="setfocus"/>
+    </msg>
+    <msg type="&WM_COMMAND;">
+      <equals>
+        <paramValue obj="this" param="source"/>
+        <paramValue obj="clicked" param="window.hwnd"/>
+      </equals>
+      <equals>
+        <paramValue obj="this" param="sourceType"/>
+        <constValue value="256"/>
+      </equals>
+      <store var="cmd"/>
+    </msg>
+    <msg type="&WM_LBUTTONUP;">
+      <equals>
+        <paramValue obj="this" param="window.hwnd"/>
+        <paramValue obj="clicked" param="window.hwnd"/>
+      </equals>
+    </msg>
+    <genMsg delay="100">
+      <type>
+        <constValue value="&WM_KILLFOCUS;"/>
+      </type>
+      <target>
+        <msgInfoValue obj="killfocus" msgParam="target"/>
+      </target>
+      <WPARAM>
+        <msgInfoValue obj="setfocus" msgParam="target"/>
+      </WPARAM>
+    </genMsg>
+    <genMsg delay="100">
+      <type>
+        <constValue value="&WM_SETFOCUS;"/>
+      </type>
+      <target>
+        <msgInfoValue obj="setfocus" msgParam="target"/>
+      </target>
+      <WPARAM>
+        <msgInfoValue obj="killfocus" msgParam="target"/>
+      </WPARAM>
+    </genMsg>
+    <genMsg delay="500">
+      <type>
+        <constValue value="&WM_COMMAND;"/>
+      </type>
+      <target>
+        <msgInfoValue obj="cmd" msgParam="target"/>
+      </target>
+      <LPARAM>
+        <msgInfoValue obj="setfocus" msgParam="target"/>
+      </LPARAM>
+      <WPARAM>
+        <paramValue obj="cmd" param="WPARAM"/>
+      </WPARAM>
+    </genMsg>
+  </rule>
+
+
+  <!-- Rules for keyboard input -->
+  <rule name="KeyDown">
+    <msg type="&WM_KEYDOWN;">
+      <store var="keydown"/>
+    </msg>
+    <genMsg delay="100">
+      <storedVar obj="keydown"/>
+    </genMsg>
+    <!--<idinfo>
+      <paramValue obj="keydown" param="key"/>
+    </idinfo>-->
+  </rule>
+
+  <rule name="KeyUp">
+    <msg type="&WM_KEYUP;">
+      <store var="keyup"/>
+    </msg>
+    <genMsg delay="500">
+      <storedVar obj="keyup"/>
+    </genMsg>
+    <!--<idinfo>
+      <paramValue obj="keyup" param="key"/>
+    </idinfo>-->
+  </rule>
+
+  <rule name="SysKeyDown">
+    <msg type="&WM_SYSKEYDOWN;">
+      <store var="keydown"/>
+    </msg>
+    <genMsg delay="100">
+      <storedVar obj="keydown"/>
+    </genMsg>
+    <idinfo>
+      <paramValue obj="keydown" param="key"/>
+    </idinfo>
+  </rule>
+
+  <rule name="SysKeyUp">
+    <msg type="&WM_SYSKEYUP;">
+      <store var="keyup"/>
+    </msg>
+    <genMsg delay="500">
+      <storedVar obj="keyup"/>
+    </genMsg>
+    <idinfo>
+      <paramValue obj="keyup" param="key"/>
+    </idinfo>
+  </rule>
+
+
+  <!-- What follows are coordinate-based rules. They are "hail mary" rules that try to salvage events that cannot be matched or replayed in a coordinate independent way (yet). -->
+  <rule name ="LeftClickCoordinates">
+    <msg type="&WM_LBUTTONDOWN;">
+      <store var="clicked"/>
+    </msg>
+    <msg type="&WM_LBUTTONUP;">
+      <equals>
+        <paramValue obj="clicked" param="window.hwnd"/>
+        <paramValue obj="this" param="window.hwnd"/>
+      </equals>
+      <store var="up"/>
+    </msg>
+    <genMsg delay="100">
+      <type>
+        <constValue value="&WM_LBUTTONDOWN;"/>
+      </type>
+      <target>
+        <msgInfoValue obj="clicked" msgParam="target"/>
+      </target>
+      <LPARAM>
+        <LOWORD>
+          <paramValue obj="clicked" param="point.x"/>
+        </LOWORD>
+        <HIWORD>
+          <paramValue obj="clicked" param="point.y"/>
+        </HIWORD>
+      </LPARAM>
+      <WPARAM>
+        <paramValue obj="clicked" param="WPARAM"/>
+      </WPARAM>
+    </genMsg>
+    <genMsg delay="500">
+      <type>
+        <constValue value="&WM_LBUTTONUP;"/>
+      </type>
+      <target>
+        <msgInfoValue obj="up" msgParam="target"/>
+      </target>
+      <LPARAM>
+        <LOWORD>
+          <paramValue obj="up" param="point.x"/>
+        </LOWORD>
+        <HIWORD>
+          <paramValue obj="up" param="point.y"/>
+        </HIWORD>
+      </LPARAM>
+      <WPARAM>
+        <paramValue obj="up" param="WPARAM"/>
+      </WPARAM>
+    </genMsg>
+  </rule>
+  
+  <rule name ="NCLeftClickCoordinates">
+    <msg type="&WM_NCLBUTTONDOWN;">
+      <store var="clicked"/>
+    </msg>
+    <msg type="&WM_LBUTTONUP;">
+      <equals>
+        <paramValue obj="clicked" param="window.hwnd"/>
+        <paramValue obj="this" param="window.hwnd"/>
+      </equals>
+      <store var="up"/>
+    </msg>
+    <genMsg delay="100">
+      <type>
+        <constValue value="&WM_NCLBUTTONDOWN;"/>
+      </type>
+      <target>
+        <msgInfoValue obj="clicked" msgParam="target"/>
+      </target>
+      <LPARAM>
+        <LOWORD>
+          <paramValue obj="clicked" param="point.x"/>
+        </LOWORD>
+        <HIWORD>
+          <paramValue obj="clicked" param="point.y"/>
+        </HIWORD>
+      </LPARAM>
+      <WPARAM>
+        <paramValue obj="clicked" param="WPARAM"/>
+      </WPARAM>
+    </genMsg>
+    <genMsg delay="500">
+      <type>
+        <constValue value="&WM_LBUTTONUP;"/>
+      </type>
+      <target>
+        <msgInfoValue obj="up" msgParam="target"/>
+      </target>
+      <LPARAM>
+        <LOWORD>
+          <paramValue obj="up" param="point.x"/>
+        </LOWORD>
+        <HIWORD>
+          <paramValue obj="up" param="point.y"/>
+        </HIWORD>
+      </LPARAM>
+      <WPARAM>
+        <paramValue obj="up" param="WPARAM"/>
+      </WPARAM>
+    </genMsg>
+  </rule>
+
+  <rule name ="NCLeftClickCoordinates2">
+    <msg type="&WM_NCLBUTTONDOWN;">
+      <store var="clicked"/>
+    </msg>
+    <msg type="&WM_NCLBUTTONUP;">
+      <equals>
+        <paramValue obj="clicked" param="window.hwnd"/>
+        <paramValue obj="this" param="window.hwnd"/>
+      </equals>
+      <store var="up"/>
+    </msg>
+    <genMsg delay="100">
+      <type>
+        <constValue value="&WM_NCLBUTTONDOWN;"/>
+      </type>
+      <target>
+        <msgInfoValue obj="clicked" msgParam="target"/>
+      </target>
+      <LPARAM>
+        <LOWORD>
+          <paramValue obj="clicked" param="point.x"/>
+        </LOWORD>
+        <HIWORD>
+          <paramValue obj="clicked" param="point.y"/>
+        </HIWORD>
+      </LPARAM>
+      <WPARAM>
+        <paramValue obj="clicked" param="WPARAM"/>
+      </WPARAM>
+    </genMsg>
+    <genMsg delay="500">
+      <type>
+        <constValue value="&WM_NCLBUTTONUP;"/>
+      </type>
+      <target>
+        <msgInfoValue obj="up" msgParam="target"/>
+      </target>
+      <LPARAM>
+        <LOWORD>
+          <paramValue obj="up" param="point.x"/>
+        </LOWORD>
+        <HIWORD>
+          <paramValue obj="up" param="point.y"/>
+        </HIWORD>
+      </LPARAM>
+      <WPARAM>
+        <paramValue obj="up" param="WPARAM"/>
+      </WPARAM>
+    </genMsg>
+  </rule>
+
+  <rule name ="LeftClickCoordinatesTargetChanged">
+    <msg type="&WM_LBUTTONDOWN;">
+      <store var="clicked"/>
+    </msg>
+    <msg type="&WM_LBUTTONUP;">
+      <store var="up"/>
+    </msg>
+    <genMsg delay="100">
+      <type>
+        <constValue value="&WM_LBUTTONDOWN;"/>
+      </type>
+      <target>
+        <msgInfoValue obj="clicked" msgParam="target"/>
+      </target>
+      <LPARAM>
+        <LOWORD>
+          <paramValue obj="clicked" param="point.x"/>
+        </LOWORD>
+        <HIWORD>
+          <paramValue obj="clicked" param="point.y"/>
+        </HIWORD>
+      </LPARAM>
+      <WPARAM>
+        <paramValue obj="clicked" param="WPARAM"/>
+      </WPARAM>
+    </genMsg>
+    <genMsg delay="500">
+      <type>
+        <constValue value="&WM_LBUTTONUP;"/>
+      </type>
+      <target>
+        <msgInfoValue obj="up" msgParam="target"/>
+      </target>
+      <LPARAM>
+        <LOWORD>
+          <paramValue obj="up" param="point.x"/>
+        </LOWORD>
+        <HIWORD>
+          <paramValue obj="up" param="point.y"/>
+        </HIWORD>
+      </LPARAM>
+      <WPARAM>
+        <paramValue obj="up" param="WPARAM"/>
+      </WPARAM>
+    </genMsg>
+  </rule>
+  
+  <rule name ="LeftClickCoordinatesTargetChanged2">
+    <msg type="&WM_LBUTTONDOWN;">
+      <store var="clicked"/>
+    </msg>
+    <msg type="&WM_NCLBUTTONUP;">
+      <store var="up"/>
+    </msg>
+    <genMsg delay="100">
+      <type>
+        <constValue value="&WM_LBUTTONDOWN;"/>
+      </type>
+      <target>
+        <msgInfoValue obj="clicked" msgParam="target"/>
+      </target>
+      <LPARAM>
+        <LOWORD>
+          <paramValue obj="clicked" param="point.x"/>
+        </LOWORD>
+        <HIWORD>
+          <paramValue obj="clicked" param="point.y"/>
+        </HIWORD>
+      </LPARAM>
+      <WPARAM>
+        <paramValue obj="clicked" param="WPARAM"/>
+      </WPARAM>
+    </genMsg>
+    <genMsg delay="500">
+      <type>
+        <constValue value="&WM_NCLBUTTONUP;"/>
+      </type>
+      <target>
+        <msgInfoValue obj="up" msgParam="target"/>
+      </target>
+      <LPARAM>
+        <LOWORD>
+          <paramValue obj="up" param="point.x"/>
+        </LOWORD>
+        <HIWORD>
+          <paramValue obj="up" param="point.y"/>
+        </HIWORD>
+      </LPARAM>
+      <WPARAM>
+        <paramValue obj="up" param="WPARAM"/>
+      </WPARAM>
+    </genMsg>
+  </rule>
+
+
+</rules>
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/CommandHelpers.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/CommandHelpers.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/CommandHelpers.java	(revision 540)
@@ -0,0 +1,54 @@
+package de.ugoe.cs.quest;
+
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Helper class that collects methods that are often used by the commands.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CommandHelpers {
+
+	/**
+	 * <p>
+	 * Prints a message to error stream of the {@link Console} that an object
+	 * has not been found in the storage.
+	 * </p>
+	 * 
+	 * @param objectName
+	 *            name of the object
+	 */
+	public static void objectNotFoundMessage(String objectName) {
+		Console.printerrln("Object " + objectName + " not found in storage.");
+	}
+
+	/**
+	 * <p>
+	 * Prints a message to the error stream of the {@link Console} that an
+	 * object is not of an expected type.
+	 * </p>
+	 * 
+	 * @param objectName
+	 *            name of the object
+	 * @param type
+	 *            expected type
+	 */
+	public static void objectNotType(String objectName, String type) {
+		Console.printerrln("Object " + objectName + "not of type " + type + ".");
+	}
+
+	/**
+	 * <p>
+	 * Prints a message to the trace stream of the {@link Console} that an
+	 * object in the storage has been overwritten.
+	 * </p>
+	 * 
+	 * @param objectName
+	 */
+	public static void dataOverwritten(String objectName) {
+		Console.traceln("Existing object " + objectName + " overwritten.");
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ReplayGenerator.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ReplayGenerator.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ReplayGenerator.java	(revision 540)
@@ -0,0 +1,174 @@
+package de.ugoe.cs.quest;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.util.Collection;
+import java.util.List;
+
+import de.ugoe.cs.quest.IReplayDecorator;
+import de.ugoe.cs.quest.eventcore.IReplayable;
+import de.ugoe.cs.quest.eventcore.ReplayableEvent;
+import de.ugoe.cs.util.StringTools;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * This class provides the functionality to generate replay files from sequences
+ * if {@link ReplayableEvent}s.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class ReplayGenerator {
+
+	/**
+	 * <p>
+	 * {@link IReplayDecorator} to be used. If this field is {@code null}, no
+	 * decorator is used. Default: {@code null}
+	 * </p>
+	 */
+	private IReplayDecorator decorator = null;
+
+	/**
+	 * <p>
+	 * Id of the current session. The starting id is 1.
+	 * </p>
+	 */
+	int sessionId = 1;
+
+	/**
+	 * <p>
+	 * Creates a replay file that contains multiple event sequences.
+	 * </p>
+	 * 
+	 * @param sequences
+	 *            collection of event sequences from which the sessions are
+	 *            generated
+	 * @param filename
+	 *            name and path of the replay file
+	 */
+	public void createLogfileMultipleSessions(
+			Collection<List<ReplayableEvent<?>>> sequences, String filename) {
+		OutputStreamWriter writer = openReplayFile(filename);
+		if (writer != null) {
+			try {
+				decorator = sequences.iterator().next().get(0).getReplayDecorator();
+				if (decorator != null) {
+					writer.write(decorator.getHeader());
+				}
+				for (List<ReplayableEvent<?>> actions : sequences) {
+					writeSession(actions, writer);
+				}
+				if (decorator != null) {
+					writer.write(decorator.getFooter());
+				}
+				decorator = null;
+				writer.close();
+			} catch (IOException e) {
+				Console.printerrln("Unable to write replay file " + filename);
+			}
+		}
+	}
+
+	/**
+	 * <p>
+	 * Creates a replay file that from a single event sequence.
+	 * </p>
+	 * 
+	 * @param actions
+	 *            event sequence from which the sessions are generated
+	 * @param filename
+	 *            name and path of the replay file
+	 */
+	public void createLogfileSingleSession(List<ReplayableEvent<?>> actions,
+			String filename) {
+		OutputStreamWriter writer = openReplayFile(filename);
+		if (writer != null) {
+			try {
+				actions.get(0).getReplayDecorator();
+				if (decorator != null) {
+					writer.write(decorator.getHeader());
+				}
+				writeSession(actions, writer);
+				if (decorator != null) {
+					writer.write(decorator.getFooter());
+				}
+				decorator = null;
+				writer.close();
+			} catch (IOException e) {
+				Console.printerrln("Unable to write replay file " + filename);
+			}
+		}
+	}
+
+	/**
+	 * <p>
+	 * Helper function that opens the replay file for writing.
+	 * </p>
+	 * 
+	 * @param filename
+	 *            name and path of the replay file
+	 * @return {@link OutputStreamWriter} that writes to the replay file
+	 */
+	private OutputStreamWriter openReplayFile(String filename) {
+		File file = new File(filename);
+		boolean fileCreated;
+		try {
+			fileCreated = file.createNewFile();
+			if (!fileCreated) {
+				Console.traceln("Created logfile " + filename);
+			} else {
+				Console.traceln("Overwrote existing logfile " + filename);
+			}
+		} catch (IOException e) {
+			Console.printerrln("Unable to create file " + filename);
+			Console.logException(e);
+		}
+		OutputStreamWriter writer = null;
+		try {
+			writer = new OutputStreamWriter(new FileOutputStream(file),
+					"UTF-16");
+		} catch (IOException e) {
+			Console.printerrln("Unable to open file for writing (read-only file):"
+					+ filename);
+			Console.logException(e);
+		}
+		return writer;
+	}
+
+	/**
+	 * <p>
+	 * Helper function that adds an event sequence to the replay.
+	 * </p>
+	 * 
+	 * @param actions
+	 *            event sequences to be added
+	 * @param writer
+	 *            {@link OutputStreamWriter} to which the replay is added
+	 * @throws IOException
+	 *             thrown if there is a problem writing to writer
+	 */
+	private void writeSession(List<ReplayableEvent<?>> actions,
+			OutputStreamWriter writer) throws IOException {
+		if (decorator != null) {
+			writer.write(decorator.getSessionHeader(sessionId));
+		}
+		for (ReplayableEvent<?> currentAction : actions) {
+
+			List<? extends IReplayable> replayables = currentAction
+					.getReplayMessages();
+			for (IReplayable replayble : replayables) {
+				writer.write(replayble.getReplay() + StringTools.ENDLINE);
+				writer.flush();
+			}
+		}
+		if (decorator != null) {
+			writer.write(decorator.getSessionFooter(sessionId));
+		}
+		sessionId++;
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/log4j/Log4JLogger.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/log4j/Log4JLogger.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/log4j/Log4JLogger.java	(revision 540)
@@ -0,0 +1,92 @@
+package de.ugoe.cs.quest.log4j;
+
+import org.apache.log4j.Logger;
+import org.apache.log4j.PropertyConfigurator;
+
+import de.ugoe.cs.util.console.Console;
+import de.ugoe.cs.util.console.listener.ICommandListener;
+import de.ugoe.cs.util.console.listener.IErrorListener;
+import de.ugoe.cs.util.console.listener.IExceptionListener;
+import de.ugoe.cs.util.console.listener.ITraceListener;
+
+/**
+ * <p>
+ * Implements logging based on the log4j API.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class Log4JLogger implements IErrorListener, ITraceListener,
+		IExceptionListener, ICommandListener {
+
+	/**
+	 * <p>
+	 * Reference to the logger.
+	 * </p>
+	 */
+	Logger logger;
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new Log4JLogger and registers the implemented
+	 * listener with the {@link Console}.
+	 * </p>
+	 */
+	public Log4JLogger() {
+		PropertyConfigurator.configure("misc/log4j.properties");
+		logger = Logger.getLogger("de.ugoe.cs.quest");
+		Console.getInstance().registerErrorListener(this);
+		Console.getInstance().registerTraceListener(this);
+		Console.getInstance().registerExceptionListener(this);
+		Console.getInstance().registerCommandListener(this);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * de.ugoe.cs.util.console.listener.ICommandListener#commandNotification
+	 * (java.lang.String)
+	 */
+	@Override
+	public void commandNotification(String command) {
+		logger.info("Command executed: " + command);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * de.ugoe.cs.util.console.listener.IExceptionListener#printStacktrace(java
+	 * .lang.Exception)
+	 */
+	@Override
+	public void logException(Exception e) {
+		logger.error("", e);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * de.ugoe.cs.util.console.listener.ITraceListener#traceMsg(java.lang.String
+	 * )
+	 */
+	@Override
+	public void traceMsg(String traceMessage) {
+		logger.trace(traceMessage);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * de.ugoe.cs.util.console.listener.IErrorListener#errorMsg(java.lang.String
+	 * )
+	 */
+	@Override
+	public void errorMsg(String errMessage) {
+		logger.error(errMessage);
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/guitar/EFGModelGenerator.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/guitar/EFGModelGenerator.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/guitar/EFGModelGenerator.java	(revision 540)
@@ -0,0 +1,132 @@
+package de.ugoe.cs.quest.plugin.guitar;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Random;
+
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.plugin.guitar.eventcore.EFGEvent;
+import de.ugoe.cs.quest.ui.commands.CMDupdateModel;
+import de.ugoe.cs.quest.usageprofiles.DeterministicFiniteAutomaton;
+import de.ugoe.cs.quest.usageprofiles.FirstOrderMarkovModel;
+import edu.umd.cs.guitar.model.GUITARConstants;
+import edu.umd.cs.guitar.model.IO;
+import edu.umd.cs.guitar.model.data.EFG;
+import edu.umd.cs.guitar.model.data.EventGraphType;
+import edu.umd.cs.guitar.model.data.EventType;
+
+/**
+ * <p>
+ * Provides functionality to generates models defined in the package
+ * de.ugoe.cs.quest.usageprofiles from EFGs.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class EFGModelGenerator {
+
+	/**
+	 * <p>
+	 * Generates a {@link FirstOrderMarkovModel} from an EFG. In the generated
+	 * model, all following events are equally possible, i.e., the model is
+	 * equal to a {@link DeterministicFiniteAutomaton}. However, through further
+	 * training (e.g., {@link CMDupdateModel}) this can be changed.
+	 * </p>
+	 * 
+	 * @param efgFileName
+	 *            name of the EFG file
+	 * @return model generated from the EFG
+	 */
+	public FirstOrderMarkovModel efgToFirstOrderMarkovModel(String efgFileName) {
+		EFG efg = (EFG) IO.readObjFromFile(efgFileName, EFG.class);
+
+		Collection<List<? extends Event<?>>> subsequences = generateEdgeSequences(efg);
+		FirstOrderMarkovModel model = new FirstOrderMarkovModel(new Random());
+		model.train(subsequences);
+		return model;
+	}
+
+	/**
+	 * <p>
+	 * Generates a {@link DeterministicFiniteAutomaton} from an EFG.
+	 * </p>
+	 * 
+	 * @param efgFileName
+	 *            name of the EFG file
+	 * @return model generated from the EFG
+	 */
+	public DeterministicFiniteAutomaton efgToDeterministicFiniteAutomaton(
+			String efgFileName) {
+		EFG efg = (EFG) IO.readObjFromFile(efgFileName, EFG.class);
+
+		Collection<List<? extends Event<?>>> subsequences = generateEdgeSequences(efg);
+		DeterministicFiniteAutomaton model = new DeterministicFiniteAutomaton(
+				new Random());
+		model.train(subsequences);
+		return model;
+	}
+
+	/**
+	 * <p>
+	 * Extracts the graph structure from the EFG. The result is a set of
+	 * sequences, where each sequence has length two and represents an edge in
+	 * the EFG.
+	 * </p>
+	 * 
+	 * @param efg
+	 *            EFG for which the edge sequence set is generated
+	 * @return edge sequence set
+	 */
+	private Collection<List<? extends Event<?>>> generateEdgeSequences(EFG efg) {
+		List<Event<?>> events = createEvents(efg);
+		/*
+		 * getEventGraph returns an adjacency matrix, i.e., a square matrix of
+		 * efgEvents.size(), where a 1 in row i, column j means an edge
+		 * efgEvents.get(i)->efgEvents.get(j) exists.
+		 */
+		EventGraphType efgGraph = efg.getEventGraph();
+		Collection<List<? extends Event<?>>> subsequences = new LinkedList<List<? extends Event<?>>>();
+
+		int efgSize = events.size();
+		for (int row = 0; row < efgSize; row++) {
+			for (int col = 0; col < efgSize; col++) {
+				int relation = efgGraph.getRow().get(row).getE().get(col);
+				// otherEvent is followed by currentEvent
+				if (relation != GUITARConstants.NO_EDGE) {
+					List<Event<?>> edge = new LinkedList<Event<?>>();
+					edge.add(events.get(row));
+					edge.add(events.get(col));
+					subsequences.add(edge);
+				}
+			}
+		}
+		return subsequences;
+	}
+
+	/**
+	 * <p>
+	 * Extracts creates {@link EFGEvent} for every event contained in the EFG.
+	 * </p>
+	 * 
+	 * @param efg
+	 *            EFG for which the events are created
+	 * @return list of events
+	 */
+	private List<Event<?>> createEvents(EFG efg) {
+		List<EventType> efgEvents = efg.getEvents().getEvent();
+		List<Event<?>> myEvents = new ArrayList<Event<?>>(efgEvents.size());
+		for (EventType event : efgEvents) {
+			/*
+			 * the widgetId and eventId are only hash values, the
+			 * "interpretation" is found in the GUI file.
+			 */
+			Event<?> myEvent = new EFGEvent(event.getEventId());
+			myEvent.setTarget(event.getWidgetId());
+			myEvents.add(myEvent);
+		}
+		return myEvents;
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/guitar/EFGReplayDecorator.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/guitar/EFGReplayDecorator.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/guitar/EFGReplayDecorator.java	(revision 540)
@@ -0,0 +1,95 @@
+package de.ugoe.cs.quest.plugin.guitar;
+
+import de.ugoe.cs.quest.IReplayDecorator;
+import de.ugoe.cs.util.StringTools;
+
+/**
+ * <p>
+ * {@link IReplayDecorator} for replays generated for the GUITAR suite.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class EFGReplayDecorator implements IReplayDecorator {
+
+	/**
+	 * <p>
+	 * Id for object serialization.
+	 * </p>
+	 */
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * <p>
+	 * The instance of the {@link EFGReplayDecorator} (implemented as
+	 * singleton).
+	 * </p>
+	 */
+	transient private static EFGReplayDecorator theInstance;
+
+	/**
+	 * <p>
+	 * Constructor. Private to guarantee that only one instance of the replay
+	 * generator exists.
+	 * </p>
+	 */
+	private EFGReplayDecorator() {
+	};
+
+	/**
+	 * <p>
+	 * Returns the instance of the MFCReplayDecorator.
+	 * </p>
+	 * 
+	 * @return instance of the MFCReplayDecorator.
+	 */
+	public static EFGReplayDecorator getInstance() {
+		if (theInstance == null) {
+			theInstance = new EFGReplayDecorator();
+		}
+		return theInstance;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.IReplayDecorator#getHeader()
+	 */
+	@Override
+	public String getHeader() {
+		return "<?xml version=\"1.0\" encoding=\"UTF-16\"?>"
+				+ StringTools.ENDLINE + "<TestCase>" + StringTools.ENDLINE;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.IReplayDecorator#getFooter()
+	 */
+	@Override
+	public String getFooter() {
+		return "</TestCase>";
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.IReplayDecorator#getSessionHeader(int)
+	 */
+	@Override
+	public String getSessionHeader(int sessionId) {
+		return "";
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.IReplayDecorator#getSessionFooter(int)
+	 */
+	@Override
+	public String getSessionFooter(int sessionId) {
+		return "";
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/guitar/GUITARTestCaseParser.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/guitar/GUITARTestCaseParser.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/guitar/GUITARTestCaseParser.java	(revision 540)
@@ -0,0 +1,109 @@
+package de.ugoe.cs.quest.plugin.guitar;
+
+import java.io.File;
+import java.util.LinkedList;
+import java.util.List;
+
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.plugin.guitar.eventcore.EFGEvent;
+import edu.umd.cs.guitar.model.IO;
+import edu.umd.cs.guitar.model.data.EFG;
+import edu.umd.cs.guitar.model.data.EventType;
+import edu.umd.cs.guitar.model.data.StepType;
+import edu.umd.cs.guitar.model.data.TestCase;
+
+/**
+ * <p>
+ * Parser for GUITAR test case files.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class GUITARTestCaseParser {
+
+	/**
+	 * <p>
+	 * Name of the EFG file for the application the test cases that are parsed
+	 * are generated for.
+	 * </p>
+	 */
+	private String efgFileName = null;
+
+	/**
+	 * <p>
+	 * Internal handle to the parsed EFG.
+	 * </p>
+	 */
+	private EFG efg = null;
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new GUITARTestCaseParser. No EFG file is
+	 * associated with this parser.
+	 * </p>
+	 */
+	public GUITARTestCaseParser() {
+
+	}
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new GUITARTestCaseParser.
+	 * </p>
+	 * 
+	 * @param efgFileName
+	 *            EFG file associated with the test cases that are parsed.
+	 */
+	public GUITARTestCaseParser(String efgFileName) {
+		this.efgFileName = efgFileName;
+	}
+
+	/**
+	 * <p>
+	 * Parses a GUITAR test case file and returns its contents as an event
+	 * sequence.
+	 * </p>
+	 * 
+	 * @param testcaseFile
+	 *            file that is parsed
+	 * @return event sequence describing the test case
+	 */
+	public List<Event<?>> parseTestCaseFile(File testcaseFile) {
+		TestCase testcase = (TestCase) IO.readObjFromFile(
+				testcaseFile.getAbsolutePath(), TestCase.class);
+		List<StepType> steps = testcase.getStep();
+		List<Event<?>> sequence = new LinkedList<Event<?>>();
+		for (StepType step : steps) {
+			String eventId = step.getEventId();
+			EFGEvent event = new EFGEvent(eventId);
+			event.setTarget(getWidgetId(eventId));
+			sequence.add(event);
+		}
+		return sequence;
+	}
+
+	/**
+	 * <p>
+	 * If {@link #efgFileName} is specified, this function retrieves the
+	 * widgetId of the widget the event with id eventId belongs to from the EFG.
+	 * </p>
+	 * 
+	 * @param eventId
+	 * @return widgetId of the associated widget; null if {@link #efgFileName}
+	 *         ==null or no widgetId for the event is found in the EFG
+	 */
+	private String getWidgetId(String eventId) {
+		if (eventId != null && efgFileName != null) {
+			if (efg == null) {
+				efg = (EFG) IO.readObjFromFile(efgFileName, EFG.class);
+			}
+			for (EventType event : efg.getEvents().getEvent()) {
+				if (eventId.equals(event.getEventId())) {
+					return event.getWidgetId();
+				}
+			}
+		}
+		return null;
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/guitar/commands/CMDefgTestCasesToSequences.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/guitar/commands/CMDefgTestCasesToSequences.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/guitar/commands/CMDefgTestCasesToSequences.java	(revision 540)
@@ -0,0 +1,83 @@
+package de.ugoe.cs.quest.plugin.guitar.commands;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.security.InvalidParameterException;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+
+import de.ugoe.cs.quest.CommandHelpers;
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.plugin.guitar.GUITARTestCaseParser;
+import de.ugoe.cs.quest.ui.GlobalDataContainer;
+import de.ugoe.cs.util.console.Command;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Command to load a set of sequences from a set of GUITAR test cases.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CMDefgTestCasesToSequences implements Command {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#run(java.util.List)
+	 */
+	@Override
+	public void run(List<Object> parameters) {
+		String foldername;
+		String sequencesName;
+		String efgFileName = null;
+		try {
+			foldername = (String) parameters.get(0);
+			sequencesName = (String) parameters.get(1);
+			if (parameters.size() >= 3) {
+				efgFileName = (String) parameters.get(2);
+			}
+		} catch (Exception e) {
+			throw new InvalidParameterException();
+		}
+
+		File folder = new File(foldername);
+		
+		File[] testcaseFiles = folder.listFiles( new FilenameFilter() {
+			@Override
+			public boolean accept(File dir, String name) {
+				return name.endsWith(".tst");
+			}
+		});
+		Collection<List<Event<?>>> sequences = new LinkedList<List<Event<?>>>();
+		GUITARTestCaseParser parser;
+		if (efgFileName == null) {
+			parser = new GUITARTestCaseParser();
+		} else {
+			parser = new GUITARTestCaseParser(efgFileName);
+		}
+		for (File testcaseFile : testcaseFiles) {
+			Console.traceln("Loading from file "
+					+ testcaseFile.getAbsolutePath());
+			sequences.add(parser.parseTestCaseFile(testcaseFile));
+		}
+		if (GlobalDataContainer.getInstance().addData(sequencesName, sequences)) {
+			CommandHelpers.dataOverwritten(sequencesName);
+		}
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#help()
+	 */
+	@Override
+	public void help() {
+		Console.println("Usage: efgTestCasesToSequences <folder> <sequencesName> {<efgFileName>}");
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/guitar/commands/CMDefgToDFA.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/guitar/commands/CMDefgToDFA.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/guitar/commands/CMDefgToDFA.java	(revision 540)
@@ -0,0 +1,55 @@
+package de.ugoe.cs.quest.plugin.guitar.commands;
+
+import java.security.InvalidParameterException;
+import java.util.List;
+
+import de.ugoe.cs.quest.plugin.guitar.EFGModelGenerator;
+import de.ugoe.cs.quest.ui.GlobalDataContainer;
+import de.ugoe.cs.quest.usageprofiles.DeterministicFiniteAutomaton;
+import de.ugoe.cs.util.console.Command;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Command to that loads an EFG and creates Deterministic Finite Automaton (DFA)
+ * with the same structure.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CMDefgToDFA implements Command {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#run(java.util.List)
+	 */
+	@Override
+	public void run(List<Object> parameters) {
+		String filename;
+		String modelname;
+		try {
+			filename = (String) parameters.get(0);
+			modelname = (String) parameters.get(1);
+		} catch (Exception e) {
+			throw new InvalidParameterException();
+		}
+
+		EFGModelGenerator modelGenerator = new EFGModelGenerator();
+		DeterministicFiniteAutomaton model = modelGenerator
+				.efgToDeterministicFiniteAutomaton(filename);
+		GlobalDataContainer.getInstance().addData(modelname, model);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#help()
+	 */
+	@Override
+	public void help() {
+		Console.println("Usage: efgToDFA <filename> <modelname>");
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/guitar/commands/CMDefgToMM.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/guitar/commands/CMDefgToMM.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/guitar/commands/CMDefgToMM.java	(revision 540)
@@ -0,0 +1,55 @@
+package de.ugoe.cs.quest.plugin.guitar.commands;
+
+import java.security.InvalidParameterException;
+import java.util.List;
+
+import de.ugoe.cs.quest.plugin.guitar.EFGModelGenerator;
+import de.ugoe.cs.quest.ui.GlobalDataContainer;
+import de.ugoe.cs.quest.usageprofiles.FirstOrderMarkovModel;
+import de.ugoe.cs.util.console.Command;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Command to that loads an EFG and creates a first-order Markov model with the
+ * same structure.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CMDefgToMM implements Command {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#run(java.util.List)
+	 */
+	@Override
+	public void run(List<Object> parameters) {
+		String filename;
+		String modelname;
+		try {
+			filename = (String) parameters.get(0);
+			modelname = (String) parameters.get(1);
+		} catch (Exception e) {
+			throw new InvalidParameterException();
+		}
+
+		EFGModelGenerator modelGenerator = new EFGModelGenerator();
+		FirstOrderMarkovModel model = modelGenerator
+				.efgToFirstOrderMarkovModel(filename);
+		GlobalDataContainer.getInstance().addData(modelname, model);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#help()
+	 */
+	@Override
+	public void help() {
+		Console.println("Usage: efgToMM <filename> <modelname>");
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/guitar/eventcore/EFGEvent.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/guitar/eventcore/EFGEvent.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/guitar/eventcore/EFGEvent.java	(revision 540)
@@ -0,0 +1,34 @@
+package de.ugoe.cs.quest.plugin.guitar.eventcore;
+
+import de.ugoe.cs.quest.eventcore.ReplayableEvent;
+
+/**
+ * <p>
+ * Convenience class for working with EFGEvents.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class EFGEvent extends ReplayableEvent<EFGReplayable> {
+
+	/**
+	 * <p>
+	 * Id for object serialization.
+	 * </p>
+	 */
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new EFGEvent.
+	 * </p>
+	 * 
+	 * @param eventId
+	 *            EventId of the event in the EFG and GUI files
+	 */
+	public EFGEvent(String eventId) {
+		super(eventId);
+		this.addReplayEvent(new EFGReplayable(eventId));
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/guitar/eventcore/EFGReplayable.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/guitar/eventcore/EFGReplayable.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/guitar/eventcore/EFGReplayable.java	(revision 540)
@@ -0,0 +1,66 @@
+package de.ugoe.cs.quest.plugin.guitar.eventcore;
+
+import de.ugoe.cs.quest.eventcore.IReplayable;
+import de.ugoe.cs.util.StringTools;
+
+/**
+ * <p>
+ * {@link IReplayable} used to generate test cases for the GUITAR suite.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class EFGReplayable implements IReplayable {
+
+	/**
+	 * <p>
+	 * EventId in the EFG and GUI files.
+	 * </p>
+	 */
+	String eventId;
+
+	/**
+	 * <p>
+	 * Id for object serialization.
+	 * </p>
+	 */
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new {@link EFGReplayable}.
+	 * </p>
+	 * 
+	 * @param eventId
+	 */
+	public EFGReplayable(String eventId) {
+		this.eventId = eventId;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.eventcore.IReplayable#getReplay()
+	 */
+	@Override
+	public String getReplay() {
+		StringBuilder replay = new StringBuilder();
+		replay.append("<Step>" + StringTools.ENDLINE);
+		replay.append("<EventId>" + eventId + "</EventId>" + StringTools.ENDLINE);
+		replay.append("<ReachingStep>false</ReachingStep>" + StringTools.ENDLINE);
+		replay.append("</Step>" + StringTools.ENDLINE);
+		return replay.toString();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.eventcore.IReplayable#getTarget()
+	 */
+	@Override
+	public String getTarget() {
+		return null; // target indirectly included in replay through the eventId
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/jfc/JFCLogParser.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/jfc/JFCLogParser.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/jfc/JFCLogParser.java	(revision 540)
@@ -0,0 +1,281 @@
+package de.ugoe.cs.quest.plugin.jfc;
+
+import java.awt.event.FocusEvent;
+import java.awt.event.MouseEvent;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.security.InvalidParameterException;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.helpers.DefaultHandler;
+
+import de.ugoe.cs.quest.plugin.jfc.eventcore.JFCEvent;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * This class provides functionality to parse XML log files generated by the
+ * JFCMonitor of EventBench. The result of parsing a file is a collection of
+ * event sequences.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class JFCLogParser extends DefaultHandler {
+
+	/**
+	 * <p>
+	 * Collection of event sequences that is contained in the log file, which is
+	 * parsed.
+	 * </p>
+	 */
+	private Collection<List<JFCEvent>> sequences;
+
+	/**
+	 * <p>
+	 * Internal handle to the event that is currently being parsed.
+	 * </p>
+	 */
+	private JFCEvent currentEvent;
+
+	/**
+	 * <p>
+	 * Internal handle to the event sequence that is currently being parsed.
+	 * </p>
+	 */
+	private List<JFCEvent> currentSequence = null;
+
+	/**
+	 * <p>
+	 * Internally used string to build a string representing a component-node.
+	 * </p>
+	 */
+	private String componentString;
+
+	/**
+	 * <p>
+	 * Enumeration to differentiate if a parameter belongs to an event, a source
+	 * or the parent of a source.
+	 * </p>
+	 * 
+	 * @author Steffen Herbold
+	 * @version 1.0
+	 */
+	private enum ParamSource {
+		EVENT, SOURCE, PARENT, COMPONENT
+	};
+
+	/**
+	 * <p>
+	 * Specifies whether the parameters that are currently being read belong the
+	 * the event, the source or the parent.
+	 * </p>
+	 */
+	ParamSource paramSource = null;
+
+	private Collection<Integer> eventFilter;
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new JFCLogParser with a default event filter.
+	 * This ignores focus events, mouse pressed, and mouse released events.
+	 * </p>
+	 */
+	public JFCLogParser() {
+		sequences = new LinkedList<List<JFCEvent>>();
+		currentSequence = new LinkedList<JFCEvent>();
+		setupDefaultEventFilter();
+	}
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new JFCLogParser with a specific event filter.
+	 * The events in the provided collection are ignored by the parser.
+	 * As events, the constants of the different event classes must be used.
+	 * E.g. creating a collection and putting
+	 * <code>MouseEvent.MOUSE_PRESSED</code> will cause the parser to ignore
+	 * all mouse pressed events. If the provided collection is null, no event
+	 * is ignored.
+	 * </p>
+	 * 
+	 * @param ignoredEvents the events to be ignored by the parser, can be null
+	 */
+	public JFCLogParser(Collection<Integer> ignoredEvents) {
+		sequences = new LinkedList<List<JFCEvent>>();
+		currentSequence = new LinkedList<JFCEvent>();
+		eventFilter = ignoredEvents;
+	}
+
+	/**
+	 * <p>
+	 * creates a default event filter that ignores focus changes, mouse pressed
+	 * and mouse released events.
+	 * </p>
+	 */
+	private void setupDefaultEventFilter() {
+		eventFilter = new HashSet<Integer>();
+		eventFilter.add(MouseEvent.MOUSE_PRESSED);
+		eventFilter.add(MouseEvent.MOUSE_RELEASED);
+		eventFilter.add(FocusEvent.FOCUS_GAINED);
+	}
+
+	/**
+	 * <p>
+	 * Returns the collection of event sequences that is obtained from parsing
+	 * log files.
+	 * </p>
+	 * 
+	 * @return collection of event sequences
+	 */
+	public Collection<List<JFCEvent>> getSequences() {
+		return sequences;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String,
+	 * java.lang.String, java.lang.String, org.xml.sax.Attributes)
+	 */
+	public void startElement(String uri, String localName, String qName,
+			Attributes atts) throws SAXException {
+		if (qName.equals("sessions")) {
+			currentSequence = new LinkedList<JFCEvent>();
+		}
+		if (qName.equals("newsession")) {
+			Console.traceln("start of session");
+			if (currentSequence != null && !currentSequence.isEmpty()) {
+				sequences.add(currentSequence);
+			}
+			currentSequence = new LinkedList<JFCEvent>();
+		} else if (qName.equals("event")) {
+			int eventId = Integer.parseInt(atts.getValue("id"));
+			if ((eventFilter == null) || (!eventFilter.contains(eventId))) {
+				currentEvent = new JFCEvent(atts.getValue("id"));
+				paramSource = ParamSource.EVENT;
+			}
+		} else if (currentEvent != null) {
+			if (qName.equals("param")) {
+				if (paramSource == ParamSource.EVENT) {
+					currentEvent.addParameter(atts.getValue("name"),
+							atts.getValue("value"));
+				} else if (paramSource == ParamSource.SOURCE) {
+					currentEvent.addSourceInformation(atts.getValue("name"),
+							atts.getValue("value"));
+				} else if (paramSource == ParamSource.PARENT) {
+					currentEvent.addParentInformation(atts.getValue("name"),
+							atts.getValue("value"));
+				} else if (paramSource == ParamSource.COMPONENT) {
+					componentString += "'" + atts.getValue("value") + "',";
+				}
+			} else if (qName.equals("source")) {
+				paramSource = ParamSource.SOURCE;
+			} else if (qName.equals("parent")) {
+				paramSource = ParamSource.PARENT;
+			} else if (qName.equals("component")) {
+				paramSource = ParamSource.COMPONENT;
+				componentString = "[";
+			}
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String,
+	 * java.lang.String, java.lang.String)
+	 */
+	@Override
+	public void endElement(String uri, String localName, String qName)
+			throws SAXException {
+		if (qName.equals("sessions")) {
+			if (currentSequence != null && !currentSequence.isEmpty()) {
+				sequences.add(currentSequence);
+			}
+			currentSequence = null;
+		} else if (currentEvent != null) {
+			if (qName.equals("event")) {
+				currentSequence.add(currentEvent);
+				currentEvent = null;
+			} else if (qName.equals("source")) {
+				paramSource = ParamSource.EVENT;
+			} else if (qName.equals("parent")) {
+				paramSource = ParamSource.SOURCE;
+			} else if (qName.equals("component")) {
+				paramSource.equals(ParamSource.SOURCE);
+				currentEvent.extendTarget(componentString.substring(0,
+						componentString.length() - 1) + "]");
+			}
+		}
+	}
+
+	/**
+	 * <p>
+	 * Parses a log file written by the JFCMonitor and creates a collection of
+	 * event sequences.
+	 * </p>
+	 * 
+	 * @param filename
+	 *            name and path of the log file
+	 */
+	public void parseFile(String filename) {
+		if (filename == null) {
+			throw new InvalidParameterException("filename must not be null");
+		}
+
+		SAXParserFactory spf = SAXParserFactory.newInstance();
+		spf.setValidating(true);
+
+		SAXParser saxParser = null;
+		InputSource inputSource = null;
+		try {
+			saxParser = spf.newSAXParser();
+			inputSource = new InputSource(new InputStreamReader(
+					new FileInputStream(filename), "UTF-8"));
+		} catch (UnsupportedEncodingException e) {
+			e.printStackTrace();
+		} catch (ParserConfigurationException e) {
+			e.printStackTrace();
+		} catch (SAXException e) {
+			e.printStackTrace();
+		} catch (FileNotFoundException e) {
+			e.printStackTrace();
+		}
+		if (inputSource != null) {
+			inputSource.setSystemId("file://"
+					+ new File(filename).getAbsolutePath());
+			try {
+				if (saxParser == null) {
+					throw new RuntimeException("SAXParser creation failed");
+				}
+				saxParser.parse(inputSource, this);
+			} catch (SAXParseException e) {
+				Console.printerrln("Failure parsing file in line "
+						+ e.getLineNumber() + ", column " + e.getColumnNumber()
+						+ ".");
+				e.printStackTrace();
+			} catch (SAXException e) {
+				e.printStackTrace();
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+		}
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/jfc/JFCReplayIDCalculator.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/jfc/JFCReplayIDCalculator.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/jfc/JFCReplayIDCalculator.java	(revision 540)
@@ -0,0 +1,208 @@
+package de.ugoe.cs.quest.plugin.jfc;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import de.ugoe.cs.quest.plugin.jfc.eventcore.JFCEvent;
+
+/**
+ * <p>
+ * This class provides the functionality to calculate the unique GUITAR replayIDs
+ * for {@link JFCEvent}s. This code is mainly based on guitar source code: edu.umd.cs.guitar.
+ * model.JFCDefaultIDGeneratorSimple
+ *    
+ * </p>
+ * @author fabian.glaser
+ *
+ */
+
+public class JFCReplayIDCalculator {
+	
+	final int prime = 31;
+	
+	/**
+	 * Properties that are used to identify widgets
+	 */
+	private static List<String> ID_PROPERTIES = Arrays.asList(
+			"Class","Title","Icon");
+	
+	private static Map<String, Integer> ID_PROPERTIES_MAP;
+	static{
+		Map<String, Integer> idmap = new HashMap<String, Integer>(4);
+		idmap.put("Class", 1);
+		idmap.put("Title", 0);
+		idmap.put("Icon", 2);
+		idmap.put("Index", 3);
+		ID_PROPERTIES_MAP = Collections.unmodifiableMap(idmap);
+	}
+		
+	
+   /**
+    * Those classes are invisible widgets but cause false-positive when
+    * calculating ID (compare guitar source code: edu.umd.cs.guitar.
+    * model.JFCDefaultIDGeneratorSimple)
+    */
+   private static List<String> IGNORED_CLASSES = Arrays.asList("javax.swing.JPanel",
+         "javax.swing.JTabbedPane", "javax.swing.JScrollPane",
+         "javax.swing.JSplitPane", "javax.swing.Box",
+         "javax.swing.JViewport", "javax.swing.JScrollBar",
+         "javax.swing.JLayeredPane",
+         "javax.swing.JList$AccessibleJList$AccessibleJListChild",
+         "javax.swing.JList$AccessibleJList", "javax.swing.JList",
+         "javax.swing.JScrollPane$ScrollBar",
+         "javax.swing.plaf.metal.MetalScrollButton");
+	
+	
+	/**
+	 * Calculates the replayID needed for compatibility with Guitar suite of a JFCEvent
+	 * @param event for which the ID should be calculated
+	 * @return replayID
+	 */
+	public String calculateReplayID(JFCEvent event){
+		String replayID = "";
+		long hashCode = 1;
+		
+		// extract target string information
+		String target = event.getTarget();
+		String[] targetParts = target.split("\\]\\.\\[");
+		
+		// we assume that first component corresponds to the notion of a 
+		// window in GUITAR suite
+		
+		// calculate window hashcode
+		String[] windowInfo = targetParts[0].split("','");
+		String title = windowInfo[0];
+		String fuzzyTitle = getFuzzyTitle(title);
+		long windowHashCode = fuzzyTitle.hashCode();
+		windowHashCode = (windowHashCode * 2) & 0xffffffffL;
+		
+		long propagatedHashCode = windowHashCode;
+		
+		for (int i = 1; i < targetParts.length; i++){
+			long localHashCode = getLocalHashCode(targetParts[i]);
+			hashCode = propagatedHashCode * prime + localHashCode;
+	        hashCode = (hashCode * 2) & 0xffffffffL;
+			
+	        if (i < targetParts.length - 1){
+	        	Integer index = getIndex(targetParts[i+1]);
+				propagatedHashCode = prime * propagatedHashCode
+				+ index.hashCode();
+	        }
+		}
+		
+		replayID = "e" + hashCode;
+		
+		return replayID;
+	}
+	
+	/**
+	 * Calculates the hashcode part of one component.
+	 * @param targetPart A string that represents a compontent
+	 * @return the local hashcode
+	 */
+	
+	private long getLocalHashCode(String targetPart){
+		long hashcode = 1;
+		String[] widgetInfo = targetPart.split("','");
+		widgetInfo[0] = widgetInfo[0].substring(1);
+		int length = widgetInfo.length - 1;
+		widgetInfo[length] = widgetInfo[length].substring(0,widgetInfo[length].length()-1);
+		String wClass = widgetInfo[ID_PROPERTIES_MAP.get("Class")];
+		if (IGNORED_CLASSES.contains(wClass)) {
+		    hashcode = (prime * hashcode + (wClass.equals("null") ? 0 : (wClass
+		               .hashCode())));
+		    return hashcode;
+		}
+		else{
+			for (String property: ID_PROPERTIES){
+				String value = widgetInfo[ID_PROPERTIES_MAP.get(property)];
+				if (!value.equals("null")){
+					hashcode = prime * hashcode + property.hashCode();
+					hashcode = prime * hashcode + value.hashCode();
+				}
+			}
+		}
+		
+		hashcode = (hashcode * 2) & 0xffffffffL;
+		
+		return hashcode;
+	}
+	
+	/**
+	 * Guitar has a special way to deal with window titles when
+	 * calculating unique widget IDs. This method mimics Guitar's
+	 * behavior (compare guitar source code: edu.umd.cs.guitar.
+	 * model.JFCDefaultIDGeneratorSimple).
+	 * @param title
+	 * @return
+	 */
+
+	private String getFuzzyTitle(String title){
+		final List<String> PATTERNS = 
+				Arrays.asList("Rachota .*",
+						"OmegaT-.*",
+						"Buddi.*",
+						"Open:.*",
+						"JabRef.*",
+						"GanttProject.*",
+						".*Pauker.*",
+						".*FreeMind.*",
+						".* - ArgoUML.*",
+						"Save Project .*");
+
+
+		for (String sPattern : PATTERNS) {
+			if (matchRegex(title, sPattern)) {
+				return sPattern;
+			}
+		}
+
+		return title;
+	}
+
+	/**
+	 * Determine if the input string matches the input regex pattern.
+	 * This method mimics Guitars behavior.
+	 * Attempt to match the pattern 'sPattern' with the string 'sInputString'.
+
+	 * @param sInputString    Input string to match with pattern
+	 * @param sPattern        Regex pattern to match with string
+	 * @return                True if match, false otherwise
+	 */
+	private static boolean
+	matchRegex(String sInputString,
+			String sPattern)
+	{
+		Pattern pattern;
+		Matcher matcher;
+
+		pattern = Pattern.compile(sPattern);
+		matcher = pattern.matcher(sInputString);
+		if (matcher.matches()) {
+			return true;
+		}
+
+		return false;
+	}
+	
+	/**
+	 * Extracts the index from a component string
+	 * @param targetPart String that represents the component
+	 * @return Index of the component
+	 */
+	
+	private Integer getIndex(String targetPart){
+		String[] widgetInfo = targetPart.split("','");
+		String index = widgetInfo[ID_PROPERTIES_MAP.get("Index")];
+		if (index.equals("-1"))
+				throw new AssertionError("Index should only be -1 for components" +
+						"that have no parent.");
+		
+		return Integer.parseInt(index);
+	}
+};
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/jfc/commands/CMDparseDirJFC.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/jfc/commands/CMDparseDirJFC.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/jfc/commands/CMDparseDirJFC.java	(revision 540)
@@ -0,0 +1,92 @@
+package de.ugoe.cs.quest.plugin.jfc.commands;
+
+import java.io.File;
+import java.security.InvalidParameterException;
+import java.util.Collection;
+import java.util.List;
+
+import de.ugoe.cs.quest.CommandHelpers;
+import de.ugoe.cs.quest.plugin.jfc.JFCLogParser;
+import de.ugoe.cs.quest.plugin.jfc.eventcore.JFCEvent;
+import de.ugoe.cs.quest.plugin.jfc.eventcore.JFCTargetComparator;
+import de.ugoe.cs.quest.ui.GlobalDataContainer;
+import de.ugoe.cs.util.console.Command;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Command that tries to parse all files in a folder as if they were log files
+ * generated by the JFCMonitor. The result is one set of sequences for all files
+ * (not one set of sequences for each file!).
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CMDparseDirJFC implements Command {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#run(java.util.List)
+	 */
+	@Override
+	public void run(List<Object> parameters) {
+		String path;
+		String sequencesName = "sequences";
+
+		try {
+			path = (String) parameters.get(0);
+			if (parameters.size() >= 2) {
+				sequencesName = (String) parameters.get(1);
+			}
+		} catch (Exception e) {
+			throw new InvalidParameterException();
+		}
+
+		File folder = new File(path);
+		if (!folder.isDirectory()) {
+			Console.printerrln(path + " is not a directory");
+			return;
+		}
+
+		JFCTargetComparator.setMutable(true);
+		JFCLogParser parser = new JFCLogParser();
+
+		String absolutPath = folder.getAbsolutePath();
+		for (String filename : folder.list()) {
+			String source = absolutPath + "/" + filename;
+			Console.traceln("Processing file: " + source);
+
+			parser.parseFile(source);
+		}
+
+		Collection<List<JFCEvent>> sequences = parser.getSequences();
+		Console.traceln("Pre-computing event target equalities.");
+		// compare all Events to a dummy event to make sure they are known by
+		// the JFCTargetComparator
+		JFCEvent dummyEvent = new JFCEvent("dummy");
+		for (List<JFCEvent> sequence : sequences) {
+			for (JFCEvent event : sequence) {
+				event.equals(dummyEvent);
+			}
+		}
+		JFCTargetComparator.setMutable(false);
+
+		if (GlobalDataContainer.getInstance().addData(sequencesName, sequences)) {
+			CommandHelpers.dataOverwritten(sequencesName);
+		}
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#help()
+	 */
+	@Override
+	public void help() {
+		Console.println("Usage: parseDirJFC <path> {<sequencesName>}");
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/jfc/commands/CMDparseJFC.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/jfc/commands/CMDparseJFC.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/jfc/commands/CMDparseJFC.java	(revision 540)
@@ -0,0 +1,76 @@
+package de.ugoe.cs.quest.plugin.jfc.commands;
+
+import java.security.InvalidParameterException;
+import java.util.Collection;
+import java.util.List;
+
+import de.ugoe.cs.quest.CommandHelpers;
+import de.ugoe.cs.quest.plugin.jfc.JFCLogParser;
+import de.ugoe.cs.quest.plugin.jfc.eventcore.JFCEvent;
+import de.ugoe.cs.quest.plugin.jfc.eventcore.JFCTargetComparator;
+import de.ugoe.cs.quest.ui.GlobalDataContainer;
+import de.ugoe.cs.util.console.Command;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Command to parse an XML file with sessions monitored by EventBench's
+ * JFCMonitor.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CMDparseJFC implements Command {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#run(java.util.List)
+	 */
+	@Override
+	public void run(List<Object> parameters) {
+		String filename;
+		String sequencesName = "sequences";
+
+		try {
+			filename = (String) parameters.get(0);
+			if (parameters.size() >= 2) {
+				sequencesName = (String) parameters.get(1);
+			}
+		} catch (Exception e) {
+			throw new InvalidParameterException();
+		}
+		JFCTargetComparator.setMutable(true);
+		JFCLogParser parser = new JFCLogParser();
+
+		parser.parseFile(filename);
+		Collection<List<JFCEvent>> sequences = parser.getSequences();
+
+		Console.traceln("Pre-computing event target equalities.");
+		// compare all Events to a dummy event to make sure they are known by
+		// the JFCTargetComparator
+		JFCEvent dummyEvent = new JFCEvent("dummy");
+		for (List<JFCEvent> sequence : sequences) {
+			for (JFCEvent event : sequence) {
+				event.equals(dummyEvent);
+			}
+		}
+		JFCTargetComparator.setMutable(false);
+
+		if (GlobalDataContainer.getInstance().addData(sequencesName, sequences)) {
+			CommandHelpers.dataOverwritten(sequencesName);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#help()
+	 */
+	@Override
+	public void help() {
+		Console.println("Usage: parseJFC <filename> {<sequencesName>}");
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/jfc/commands/CMDpreprocessDirJFC.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/jfc/commands/CMDpreprocessDirJFC.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/jfc/commands/CMDpreprocessDirJFC.java	(revision 540)
@@ -0,0 +1,119 @@
+package de.ugoe.cs.quest.plugin.jfc.commands;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+import java.security.InvalidParameterException;
+import java.util.List;
+
+import de.ugoe.cs.util.console.Command;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Command to pre-process files written by EventBench's JFCMonitor located in a
+ * directory. The only task of the pre-processing is checking if the session was
+ * closed properly, i.e., if the XML file ends with a {@code </sessions>} tag.
+ * If this is not the case, the tag will be appended to the file.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CMDpreprocessDirJFC implements Command {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#run(java.util.List)
+	 */
+	@Override
+	public void run(List<Object> parameters) {
+		String sourcePath;
+		String targetPath;
+		try {
+			sourcePath = (String) parameters.get(0);
+			targetPath = (String) parameters.get(1);
+		} catch (Exception e) {
+			throw new InvalidParameterException();
+		}
+
+		File sourceFolder = new File(sourcePath);
+		if (!sourceFolder.isDirectory()) {
+			Console.printerrln(sourcePath + " is not a directory");
+		}
+		String absolutPathSource = sourceFolder.getAbsolutePath();
+		File targetFolder = new File(targetPath);
+		if (!targetFolder.isDirectory()) {
+			Console.printerrln(targetPath + " is not a directory");
+		}
+		String absolutPathTarget = targetFolder.getAbsolutePath();
+
+		for (String filename : sourceFolder.list()) {
+			String source = absolutPathSource + "/" + filename;
+			Console.traceln("Preprocessing file: " + source);
+			File file = new File(source);
+			InputStreamReader reader;
+			try {
+				FileInputStream fis = new FileInputStream(file);
+				reader = new InputStreamReader(fis, "UTF-16");
+			} catch (FileNotFoundException e) {
+				Console.printerrln(e.getMessage());
+				return;
+			} catch (UnsupportedEncodingException e) {
+				Console.printerrln(e.getMessage());
+				return;
+			}
+			char[] buffer = new char[(int) file.length()];
+			try {
+				reader.read(buffer);
+				reader.close();
+			} catch (IOException e) {
+				Console.printerrln(e.getMessage());
+				return;
+			}
+
+			String content = new String(buffer).trim();
+
+			int index = filename.lastIndexOf('.');
+			String target = absolutPathTarget + "/"
+					+ filename.substring(0, index) + ".xml";
+
+			Console.traceln("   Saving as: " + target);
+
+			OutputStreamWriter writer;
+			try {
+				FileOutputStream fos = new FileOutputStream(target);
+				writer = new OutputStreamWriter(fos, "UTF-8");
+			} catch (IOException e) {
+				Console.printerrln(e.getMessage());
+				return;
+			}
+			try {
+				writer.write(content);
+				if (!content.endsWith("</sessions>")) {
+					writer.write("</sessions>");
+				}
+				writer.close();
+			} catch (IOException e) {
+				Console.printerrln(e.getMessage());
+			}
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#help()
+	 */
+	@Override
+	public void help() {
+		Console.println("Usage: preprocessDirJFC <sourcePath> <targetPath>");
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/jfc/commands/CMDpreprocessJFC.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/jfc/commands/CMDpreprocessJFC.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/jfc/commands/CMDpreprocessJFC.java	(revision 540)
@@ -0,0 +1,98 @@
+package de.ugoe.cs.quest.plugin.jfc.commands;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+import java.security.InvalidParameterException;
+import java.util.List;
+
+import de.ugoe.cs.util.console.Command;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Command to pre-process files written by EventBench's JFCMonitor. The only
+ * task of the pre-processing is checking if the session was closed properly,
+ * i.e., if the XML file ends with a {@code </sessions>} tag. If this is not the
+ * case, the tag will be appended to the file.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CMDpreprocessJFC implements Command {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#run(java.util.List)
+	 */
+	@Override
+	public void run(List<Object> parameters) {
+		String source;
+		String target;
+		try {
+			source = (String) parameters.get(0);
+			target = (String) parameters.get(1);
+		} catch (Exception e) {
+			throw new InvalidParameterException();
+		}
+
+		File file = new File(source);
+		InputStreamReader reader;
+		try {
+			FileInputStream fis = new FileInputStream(file);
+			reader = new InputStreamReader(fis, "UTF-16");
+		} catch (FileNotFoundException e) {
+			Console.printerrln(e.getMessage());
+			return;
+		} catch (UnsupportedEncodingException e) {
+			Console.printerrln(e.getMessage());
+			return;
+		}
+		char[] buffer = new char[(int) file.length()];
+		try {
+			reader.read(buffer);
+			reader.close();
+		} catch (IOException e) {
+			Console.printerrln(e.getMessage());
+			return;
+		}
+
+		String content = new String(buffer).trim();
+
+		OutputStreamWriter writer;
+		try {
+			FileOutputStream fos = new FileOutputStream(target);
+			writer = new OutputStreamWriter(fos, "UTF-8");
+		} catch (IOException e) {
+			Console.printerrln(e.getMessage());
+			return;
+		}
+		try {
+			writer.write(content);
+			if (!content.endsWith("</sessions>")) {
+				writer.write("</sessions>");
+			}
+			writer.close();
+		} catch (IOException e) {
+			Console.printerrln(e.getMessage());
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#help()
+	 */
+	@Override
+	public void help() {
+		Console.println("Usage: preprocessJFC <sourceFile> <targetFile>");
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/jfc/eventcore/JFCEvent.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/jfc/eventcore/JFCEvent.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/jfc/eventcore/JFCEvent.java	(revision 540)
@@ -0,0 +1,235 @@
+package de.ugoe.cs.quest.plugin.jfc.eventcore;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import de.ugoe.cs.quest.eventcore.IReplayable;
+import de.ugoe.cs.quest.eventcore.ReplayableEvent;
+import de.ugoe.cs.quest.plugin.jfc.JFCLogParser;
+
+/**
+ * <p>
+ * This class defines JFC events.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class JFCEvent extends ReplayableEvent<IReplayable> {
+
+	/**
+	 * <p>
+	 * Id for object serialization.
+	 * </p>
+	 */
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * <p>
+	 * Internal map of parameters associated with the event.
+	 * </p>
+	 */
+	private Map<String, String> parameters;
+
+	/**
+	 * <p>
+	 * Information about the event source.
+	 * </p>
+	 */
+	private Map<String, String> sourceParameters;
+
+	/**
+	 * <p>
+	 * Information about the parent of the event source.
+	 * </p>
+	 */
+	private Map<String, String> parentParameters;
+	
+	private boolean targetChanged = false;
+	
+	private int targetHash = -1;
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new JFCEvent.
+	 * </p>
+	 * 
+	 * @param type
+	 *            type of the event
+	 */
+	public JFCEvent(String type) {
+		super(type);
+		parameters = new HashMap<String, String>();
+		sourceParameters = new HashMap<String, String>();
+		parentParameters = new HashMap<String, String>();
+	}
+
+	/**
+	 * <p>
+	 * Adds a new parameter to the event.
+	 * </p>
+	 * 
+	 * @param name
+	 *            name of the parameter
+	 * @param value
+	 *            value of the parameter
+	 */
+	public void addParameter(String name, String value) {
+		parameters.put(name, value);
+	}
+
+	/**
+	 * <p>
+	 * Retrieves the value of a parameter.
+	 * </p>
+	 * 
+	 * @param name
+	 *            name of the parameter
+	 * @return value of the parameter
+	 */
+	public String getParameter(String name) {
+		return parameters.get(name);
+	}
+
+	/**
+	 * <p>
+	 * Adds new information about the source of the event.
+	 * </p>
+	 * 
+	 * @param name
+	 *            name of the information
+	 * @param value
+	 *            value of the information
+	 */
+	public void addSourceInformation(String name, String value) {
+		sourceParameters.put(name, value);
+	}
+
+	/**
+	 * <p>
+	 * Retrieves information about the source of the event.
+	 * </p>
+	 * 
+	 * @param name
+	 *            name of the information
+	 * @return value of the information
+	 */
+	public String getSourceInformation(String name) {
+		return sourceParameters.get(name);
+	}
+
+	/**
+	 * <p>
+	 * Adds new information about the parent of the source of the event.
+	 * </p>
+	 * 
+	 * @param name
+	 *            name of the information
+	 * @param value
+	 *            value of the information
+	 */
+	public void addParentInformation(String name, String value) {
+		parentParameters.put(name, value);
+	}
+
+	/**
+	 * <p>
+	 * Used by the {@link JFCLogParser} to extend the target string of the
+	 * current event with a further ancestor. The resulting target string will
+	 * have the structure {@code etc.grandparent.parent.eventtarget}.
+	 * </p>
+	 * 
+	 * @param extension
+	 *            extension for the target.
+	 */
+	public void extendTarget(String extension) {
+		if (target == null || "".equals(target)) {
+			target = extension;
+		} else {
+			target += "." + extension;
+		}
+		targetChanged = true;
+	}
+
+	/**
+	 * <p>
+	 * Retrieves information about the parent of the source of the event.
+	 * </p>
+	 * 
+	 * @param name
+	 *            name of the information
+	 * @return value of the information
+	 */
+	public String getParentInformation(String name) {
+		return parentParameters.get(name);
+	}
+
+	/**
+	 * <p>
+	 * This method implements the comparison between two targets of JFCEvents.
+	 * The targets are equal, if they have the same placement in the widget
+	 * hierarchy, i.e., the target strings describe the same widgets, according
+	 * to the implementation of widget equality provided by
+	 * {@link #compareWidgets(String, String)}.
+	 * </p>
+	 * 
+	 * @see de.ugoe.cs.quest.eventcore.Event#targetEquals(java.lang.String)
+	 */
+	@Override
+	protected boolean targetEquals(String otherTarget) {
+		return JFCTargetComparator.compare(target, otherTarget);
+	}
+
+	/**
+	 * <p>
+	 * The targetHashCode ignores the parts of the target that describe the
+	 * title and hash of a widget, to ensure that the equals/hashCode contract
+	 * is fulfilled.
+	 * </p>
+	 * 
+	 * @see de.ugoe.cs.quest.eventcore.Event#targetHashCode()
+	 */
+	@Override
+	protected int targetHashCode() {
+		if( targetChanged || targetHash==-1 ) {
+			targetHash = 0;
+			int multiplier = 29;
+			if (target != null) {
+				String[] targetParts = target.split("\\]\\.\\[");
+				if (targetParts.length == 0) {
+					targetHash = widgetHashCode(target);
+				} else {
+					for (String widgetString : targetParts) {
+						targetHash = targetHash * multiplier
+								+ widgetHashCode(widgetString);
+					}
+				}
+			}
+			targetChanged = false;
+		}
+		return targetHash;
+	}
+
+	/**
+	 * <p>
+	 * This method calculates the hashCode for a a widget. If is used by
+	 * {@link #targetHashCode()} to build the complete hashCode.
+	 * </p>
+	 * 
+	 * @param widget
+	 *            string describing the widget
+	 * @return hashCode of the widget
+	 */
+	private int widgetHashCode(String widget) {
+		int hashCode = 0;
+		int multiplier = 37;
+		String[] widgetInfo = widget.split("','");
+		if (widgetInfo.length == 5) {
+			hashCode = hashCode * multiplier + widgetInfo[1].hashCode();
+			hashCode = hashCode * multiplier + widgetInfo[2].hashCode();
+			//hashCode = hashCode * multiplier + widgetInfo[3].hashCode();
+		}
+		return hashCode;
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/jfc/eventcore/JFCTargetComparator.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/jfc/eventcore/JFCTargetComparator.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/jfc/eventcore/JFCTargetComparator.java	(revision 540)
@@ -0,0 +1,429 @@
+package de.ugoe.cs.quest.plugin.jfc.eventcore;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.collections15.CollectionUtils;
+
+/**
+ * <p>
+ * This class implements a comparator for target string for JFC GUIs. It
+ * internally maintains a collection of all targets that have been compared, to
+ * ensure transitivity of the equals relation. This memory can always be deleted
+ * by calling {@link #reset()}.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class JFCTargetComparator {
+
+	/**
+	 * <p>
+	 * If mutable is true, new target strings can be added to the internal
+	 * memory. This leads to a very expensive {@link #compare(String, String)}
+	 * operation.
+	 * </p>
+	 * <p>
+	 * if mutable is set to false, currently possible equal targets are
+	 * pre-computed. This pre-computation is expensive and might take a while.
+	 * In turn, the {@link #compare(String, String)} operation becomes very
+	 * cheap.
+	 * </p>
+	 */
+	private static boolean mutable = true;
+
+	/**
+	 * <p>
+	 * Set of all currently known targets.
+	 * </p>
+	 */
+	private static Set<String> knownTargets = new LinkedHashSet<String>();
+
+	/**
+	 * <p>
+	 * Map that contains for all known target strings all equal target strings.
+	 * Pre-computed when {@link #mutable} is set to false.
+	 * </p>
+	 */
+	private static Map<String, Set<String>> equalTargets;
+
+	/**
+	 * <p>
+	 * Changes the mutability of the comparator. If the mutability is changed
+	 * from true to false, the map {@link #equalTargets} is computed.
+	 * </p>
+	 * 
+	 * @param mutable
+	 *            new mutability of the comparator
+	 */
+	public static void setMutable(boolean mutable) {
+		if (JFCTargetComparator.mutable == true && mutable == false) {
+			equalTargets = new HashMap<String, Set<String>>();
+			for (String target1 : knownTargets) {
+				Set<String> curEqualTargets = new HashSet<String>();
+				for (String target2 : knownTargets) {
+					if (compare(target1, target2)) {
+						curEqualTargets.add(target2);
+					}
+				}
+				equalTargets.put(target1, curEqualTargets);
+			}
+		}
+		JFCTargetComparator.mutable = mutable;
+	}
+
+	/**
+	 * <p>
+	 * Compares to target strings. The strings are equal, if
+	 * <ul>
+	 * <li>the class, index, and text of all widgets are equal</li>
+	 * <li>either the title or the hashCode of all widgets are equal</li>
+	 * <li>either the title or the hashCode has been observed in one equal
+	 * instance of a widget, for all widgets.</li>
+	 * </ul>
+	 * </p>
+	 * <p>
+	 * All target strings are remembered internally, to be able to test for the
+	 * third property.
+	 * </p>
+	 * 
+	 * @param target1
+	 *            first target string
+	 * @param target2
+	 *            second target string
+	 * @return true, if both targets are equal; false otherwise
+	 */
+	public static boolean compare(String target1, String target2) {
+		boolean result = false;
+		if (mutable) {
+			instance.addTarget(target1);
+			instance.addTarget(target2);
+			knownTargets.add(target1);
+			knownTargets.add(target2);
+			JFCWidget widget1 = instance.find(target1);
+			JFCWidget widget2 = instance.find(target2);
+			result = (widget1 == widget2);
+		}
+
+		if (!mutable) {
+			Set<String> curEquals = equalTargets.get(target1);
+			if (curEquals != null) {
+				result = curEquals.contains(target2);
+			}
+		}
+
+		return result;
+	}
+
+	/**
+	 * <p>
+	 * Resets the internal memory of targets.
+	 * </p>
+	 */
+	public static void reset() {
+		instance = new JFCTargetComparator();
+	}
+
+	/**
+	 * <p>
+	 * Internal handle to the instance of this class (implemented as
+	 * Singleton!).
+	 * </p>
+	 */
+	private static JFCTargetComparator instance = new JFCTargetComparator();
+
+	/**
+	 * <p>
+	 * Private Constructor. Creates a new instance of the class and prevents
+	 * instantiation from outside of this class.
+	 * </p>
+	 */
+	private JFCTargetComparator() {
+	}
+
+	/**
+	 * <p>
+	 * List of the root widgets found in the target string.
+	 * </p>
+	 */
+	private List<JFCWidget> rootWidgets = new ArrayList<JFCTargetComparator.JFCWidget>();
+
+	/**
+	 * <p>
+	 * Adds a target to the memory.
+	 * </p>
+	 * 
+	 * @param target
+	 *            target to be added
+	 */
+	private void addTarget(String target) {
+		if (target != null) {
+			String[] targetParts = target.split("\\]\\.\\[");
+			if (targetParts.length == 1) {
+				addWidget(target.substring(1, target.length() - 1), null);
+			} else {
+				JFCWidget parent = null;
+				for (int i = 0; i < targetParts.length; i++) {
+					if (i == 0) {
+						parent = addWidget(targetParts[i].substring(1), parent);
+					} else if (i == targetParts.length - 1) {
+						parent = addWidget(
+								targetParts[i].substring(0,
+										targetParts[i].length() - 1), parent);
+					} else {
+						parent = addWidget(targetParts[i], parent);
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * <p>
+	 * Adds a widget extracted from a target to the memory. The widget is placed
+	 * as a child/parent of other widget according to the GUI hierarchy of the
+	 * application.
+	 * </p>
+	 * <p>
+	 * In case the widget already exists, the existing widget is returned and
+	 * the known targets and hashCodes of the existing widget are updated.
+	 * </p>
+	 * 
+	 * @param widgetString
+	 *            string identifying the widget
+	 * @param parent
+	 *            parent widget; if null, it is a root widget and added to
+	 *            {@link #rootWidgets}
+	 * @return the created widget.
+	 */
+	private JFCWidget addWidget(String widgetString, JFCWidget parent) {
+		String[] widgetInfo = widgetString.split("','");
+		JFCWidget widget = generateWidget(widgetString);
+
+		if (parent == null) {
+			int index = rootWidgets.indexOf(widget);
+			if (index >= 0) {
+				widget = rootWidgets.get(index);
+				widget.titles.add(widgetInfo[0]);
+				widget.hashCodes.add(widgetInfo[4]);
+			} else {
+				rootWidgets.add(widget);
+			}
+		} else {
+			int index = parent.children.indexOf(widget);
+			if (index >= 0) {
+				widget = parent.children.get(index);
+				widget.titles.add(widgetInfo[0]);
+				widget.hashCodes.add(widgetInfo[4]);
+			} else {
+				parent.children.add(widget);
+			}
+		}
+
+		return widget;
+	}
+
+	/**
+	 * <p>
+	 * Creates a new {@link JFCWidget} from a widget string.
+	 * </p>
+	 * 
+	 * @param widgetString
+	 *            string describing the widget
+	 * @return created {@link JFCWidget}
+	 */
+	private JFCWidget generateWidget(String widgetString) {
+		String[] widgetInfo = widgetString.split("','");
+		JFCWidget widget = new JFCWidget();
+		if (widgetInfo[0].startsWith("'Pos(")) {
+			widget.titles.add("Pos");
+		} else {
+			widget.titles.add(widgetInfo[0]);
+		}
+		widget.widgetClass = widgetInfo[1];
+		widget.text = widgetInfo[2];
+		widget.index = widgetInfo[3];
+		widget.hashCodes.add(widgetInfo[4]);
+		return widget;
+	}
+
+	/**
+	 * <p>
+	 * Tries to find the {@link JFCWidget} that the target string identifies in
+	 * the known GUI hierarchy, by traversing the known widgets starting with
+	 * the {@link #rootWidgets}.
+	 * </p>
+	 * 
+	 * @param target
+	 *            target string whose widget is searched for
+	 * @return respective {@link JFCWidget} instance if it is found; null
+	 *         otherwise
+	 */
+	private JFCWidget find(String target) {
+		JFCWidget widget = null;
+		if (target != null) {
+			String[] targetParts = target.split("\\]\\.\\[");
+			if (targetParts.length == 1) {
+				JFCWidget generatedWidget = generateWidget(target.substring(1,
+						target.length() - 1));
+				int index = rootWidgets.indexOf(generatedWidget);
+				if (index >= 0) {
+					widget = rootWidgets.get(index);
+				} else {
+					return null;
+				}
+			} else {
+				JFCWidget parent = null;
+				for (int i = 0; i < targetParts.length; i++) {
+					if (i == 0) {
+						JFCWidget generatedWidget = generateWidget(targetParts[i]
+								.substring(1));
+						int index = rootWidgets.indexOf(generatedWidget);
+						if (index >= 0) {
+							parent = rootWidgets.get(index);
+						} else {
+							return null;
+						}
+					} else if (i == targetParts.length - 1) {
+						JFCWidget generatedWidget = generateWidget(targetParts[i]
+								.substring(0, targetParts[i].length() - 1));
+						int index = parent.children.indexOf(generatedWidget);
+						if (index >= 0) {
+							widget = parent.children.get(index);
+						} else {
+							return null;
+						}
+					} else {
+						JFCWidget generatedWidget = generateWidget(targetParts[i]);
+						int index = parent.children.indexOf(generatedWidget);
+						if (index >= 0) {
+							parent = parent.children.get(index);
+						} else {
+							return null;
+						}
+					}
+				}
+			}
+		}
+		return widget;
+	}
+
+	/**
+	 * <p>
+	 * Internal class used to store JFCWidgets. The implementation is more like
+	 * a C-style structure, than a actual class.
+	 * </p>
+	 * 
+	 * @author Steffen Herbold
+	 * @version 1.0
+	 */
+	private static class JFCWidget {
+
+		/**
+		 * <p>
+		 * Set of all known title strings of the widget.
+		 * </p>
+		 */
+		Set<String> titles = new LinkedHashSet<String>();
+
+		/**
+		 * <p>
+		 * Set of all known hashCodes of the widget.
+		 * </p>
+		 */
+		Set<String> hashCodes = new LinkedHashSet<String>();
+
+		/**
+		 * <p>
+		 * Class of the widget.
+		 * </p>
+		 */
+		String widgetClass;
+
+		/**
+		 * <p>
+		 * Index of the widget.
+		 * </p>
+		 */
+		String index;
+
+		/**
+		 * <p>
+		 * Text of the widget.
+		 * </p>
+		 */
+		String text;
+
+		/**
+		 * <p>
+		 * Pre-computed hash code of the widget.
+		 * </p>
+		 */
+		int hashCode = 0;
+
+		/**
+		 * <p>
+		 * List of children of the widget.
+		 * </p>
+		 */
+		List<JFCWidget> children = new ArrayList<JFCTargetComparator.JFCWidget>();
+
+		/**
+		 * <p>
+		 * Two widgets are equal, if {@link #widgetClass}, {@link #index}, and
+		 * {@link #text} are equal and the intersection of either the
+		 * {@link #hashCodes}, the {@link #titles}, or both of them is not
+		 * empty.
+		 * </p>
+		 * 
+		 * @see java.lang.Object#equals(java.lang.Object)
+		 */
+		@Override
+		public boolean equals(Object obj) {
+			if (obj instanceof JFCWidget) {
+				JFCWidget other = (JFCWidget) obj;
+				boolean titleEqual = CollectionUtils.containsAny(titles,
+						other.titles);
+				boolean hashEqual = CollectionUtils.containsAny(hashCodes,
+						other.hashCodes);
+
+				boolean retVal;
+
+				if (widgetClass.equals("Class")) {
+					retVal = (widgetClass.equals(other.widgetClass)
+							&& text.equals(other.text) && (titleEqual || hashEqual));
+				} else {
+					retVal = (widgetClass.equals(other.widgetClass)
+							&& index.equals(other.index)
+							&& text.equals(other.text) && (titleEqual || hashEqual));
+				}
+				return retVal;
+			}
+			return false;
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see java.lang.Object#hashCode()
+		 */
+		@Override
+		public int hashCode() {
+			if (hashCode == 0) {
+				int multiplier = 7;
+				hashCode = multiplier * hashCode + widgetClass.hashCode();
+				if (!widgetClass.equals("Class")) {
+					hashCode = multiplier * hashCode + index.hashCode();
+				}
+				hashCode = multiplier * hashCode + text.hashCode();
+			}
+			return hashCode;
+		}
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/EventGenerator.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/EventGenerator.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/EventGenerator.java	(revision 540)
@@ -0,0 +1,995 @@
+package de.ugoe.cs.quest.plugin.mfc;
+
+import java.io.IOException;
+import java.security.InvalidParameterException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jdom.JDOMException;
+import org.jdom.Namespace;
+import org.jdom.input.SAXBuilder;
+
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.plugin.mfc.eventcore.WindowTree;
+import de.ugoe.cs.quest.plugin.mfc.eventcore.WindowTreeNode;
+import de.ugoe.cs.quest.plugin.mfc.eventcore.WindowsEvent;
+import de.ugoe.cs.quest.plugin.mfc.eventcore.WindowsMessage;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Translates sequences of windows messages into {@link WindowsEvent}s that can
+ * be used by the EventBench core libraries.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class EventGenerator {
+
+	/**
+	 * <p>
+	 * Helper method that fetches the document node of an XML file.
+	 * </p>
+	 * 
+	 * @param filename
+	 *            name of the XML file
+	 * @return the document node
+	 */
+	private static Document getDocument(String filename) {
+		SAXBuilder builder = new SAXBuilder();
+		Document doc = null;
+
+		try {
+			doc = builder.build(filename);
+			rulesNamespace = Namespace.getNamespace("ul:rules");
+		} catch (JDOMException e) {
+			Console.printerrln("Invalid rules file.");
+			e.printStackTrace();
+		} catch (IOException e) {
+			Console.printerrln("Invalid rules file.");
+			e.printStackTrace();
+		}
+
+		return doc;
+	}
+
+	/**
+	 * <p>
+	 * Name and path of the XML files containing the rules.
+	 * </p>
+	 */
+	private String rulesFile;
+
+	/**
+	 * <p>
+	 * Iterator used for the current sequence.
+	 * </p>
+	 */
+	private ListIterator<WindowsMessage> sequenceIterator;
+
+	/**
+	 * <p>
+	 * Token that is currently being generated.
+	 * </p>
+	 */
+	private WindowsEvent currentToken;
+
+	/**
+	 * <p>
+	 * Reference to the ul:rules namespace.
+	 * </p>
+	 */
+	private static Namespace rulesNamespace;
+
+	/**
+	 * <p>
+	 * The name of the rule that is currently being evaluated.
+	 * </p>
+	 */
+	private String currentRuleName;
+
+	/**
+	 * <p>
+	 * Internal message storage. Used to implement the
+	 * <code>{@literal <store>}</code> and <code>{@literal <storeSeq>}</code>
+	 * tags.
+	 * </p>
+	 */
+	private Map<String, Object> messageStorage;
+
+	/**
+	 * <p>
+	 * Creates a new EventGenerator. Sets "rules/rules.xml" as default file for
+	 * the rules.
+	 * </p>
+	 */
+	public EventGenerator() {
+		rulesFile = "rules/rules.xml";
+	}
+
+	/**
+	 * <p>
+	 * Tries to match the rules to the given sequence to generate an
+	 * {@link WindowsEvent}.
+	 * </p>
+	 * <p>
+	 * The rules are matched the order, in which they are defined in the XML
+	 * file. Therefore, the order of the rules in the file defines priorities,
+	 * when multiple rules could be matched to the same sequence.
+	 * </p>
+	 * 
+	 * @param sequence
+	 *            sequence of message for which an event will be generated
+	 * @return event that matches the messages; null, if no rule can be matched
+	 */
+	@SuppressWarnings("unchecked")
+	public WindowsEvent generateEvent(List<WindowsMessage> sequence) {
+		Document rulesDoc = getDocument(rulesFile);
+		Element rulesRoot = rulesDoc.getRootElement();
+
+		List<Element> ruleElements = rulesRoot.getChildren("rule",
+				rulesNamespace);
+
+		boolean isMatch = false;
+
+		for (int ruleIndex = 0; ruleIndex < ruleElements.size() && !isMatch; ruleIndex++) {
+			Element currentRule = ruleElements.get(ruleIndex);
+			currentRuleName = currentRule.getAttributeValue("name");
+			currentToken = new WindowsEvent(currentRuleName);
+			currentToken.setDecorator(MFCReplayDecorator.getInstance());
+			isMatch = true;
+			messageStorage = new HashMap<String, Object>();
+			sequenceIterator = sequence.listIterator();
+			List<Element> ruleChildrenMsg = currentRule.getChildren("msg",
+					rulesNamespace);
+
+			int i = 0;
+			while (isMatch && i < ruleChildrenMsg.size()) {
+				Element messageElement = ruleChildrenMsg.get(i);
+				if ("true".equals(messageElement.getAttributeValue("multiple"))) {
+					Element nextMessageElement = null;
+					if (i + 1 < ruleChildrenMsg.size()) {
+						nextMessageElement = ruleChildrenMsg.get(i + 1);
+					}
+					try {
+						isMatch = matchMultipleMessages(messageElement,
+								nextMessageElement);
+					} catch (InvalidParameterException e) {
+						Console.printerrln(e.getMessage());
+					}
+				} else {
+					try {
+						isMatch = matchSingleMessage(messageElement);
+					} catch (InvalidParameterException e) {
+						Console.printerrln(e.getMessage());
+					}
+				}
+				i++;
+			}
+			if (isMatch) {
+				List<Element> ruleChildren = currentRule.getChildren();
+				for (Element genMsgElement : ruleChildren) {
+					if (genMsgElement.getName().equals("genMsg")) {
+						try {
+							generateReplayMessage(genMsgElement);
+						} catch (InvalidParameterException e) {
+							Console.printerrln(e.getMessage());
+							currentToken.invalidateReplay();
+						}
+					} else if (genMsgElement.getName().equals("genMsgSeq")) {
+						try {
+							generateReplaySequence(genMsgElement);
+							currentToken.invalidateReplay();
+						} catch (InvalidParameterException e) {
+							Console.printerrln(e.getMessage());
+							currentToken.invalidateReplay();
+						}
+					}
+				}
+				Element idinfoElement = currentRule.getChild("idinfo",
+						rulesNamespace);
+				if (idinfoElement != null) {
+					// cannot be empty if document is valid
+					List<Element> valueElements = idinfoElement.getChildren();
+					currentToken.setIdInfo(getTermValue(null,
+							valueElements.get(0)));
+				}
+				Console.traceln(currentRule.getAttributeValue("name")
+						+ currentToken.getIdInfo() + " matched");
+			} else {
+				currentToken = null;
+			}
+		}
+		if (!isMatch) {
+			Console.traceln("no match found for sequence: "
+					+ sequence.toString());
+		}
+		return currentToken;
+	}
+
+	// ////////////////////////////////////////////////////////////
+	// Helper functions for matching of events, i.e., msg-nodes //
+	// ////////////////////////////////////////////////////////////
+
+	/**
+	 * <p>
+	 * Handles msg-nodes where multiple is not true, i.e., not a sequences.
+	 * </p>
+	 * 
+	 * @param messageElement
+	 *            {@link Element} representing the msg-node
+	 * @return true, if a match is found; false otherwise
+	 */
+	private boolean matchSingleMessage(Element messageElement) {
+		boolean isMatch = false;
+		WindowsMessage currentMessage = null;
+
+		int type = Integer.parseInt(messageElement.getAttributeValue("type"));
+
+		while (!isMatch && sequenceIterator.hasNext()) {
+			/*
+			 * traverses the messages from the current position forward till a
+			 * message with the correct type is found
+			 */
+			currentMessage = sequenceIterator.next();
+			if (type == currentMessage.getType()) {
+				// message with the correct type found
+				// eval child nodes for further matching/storing
+				isMatch = evalEqualRestrictions(currentMessage, messageElement);
+
+				// in case the message is a match, eval storage children
+				if (isMatch) {
+					handleStorage(messageElement, currentMessage);
+					currentToken.setTarget(currentMessage
+							.getXmlWindowDescription());
+					currentToken
+							.setTargetShort(currentMessage.getParentNames());
+				}
+			}
+		}
+
+		return isMatch;
+	}
+
+	/**
+	 * <p>
+	 * Handles msg-nodes where multiple is true, i.e., sequences. Requires
+	 * knowledge about the next msg-node to determine the end of the sequence.
+	 * </p>
+	 * 
+	 * @param messageElement
+	 *            {@link Element} representing the msg-node
+	 * @param nextMessageElement
+	 *            {@link Element} representing the next msg-node; {@code null}
+	 *            if the current node is the last one
+	 * @return true, if a sequence is matched; false otherwise
+	 */
+	private boolean matchMultipleMessages(Element messageElement,
+			Element nextMessageElement) {
+		boolean isMatch = false;
+		boolean isCurrentMatch = false;
+		boolean nextMatchFound = false;
+		WindowsMessage currentMessage = null;
+		WindowsMessage nextMessage = null;
+
+		int type = Integer.parseInt(messageElement.getAttributeValue("type"));
+
+		int nextType = -1;
+		if (nextMessageElement != null) {
+			nextType = Integer.parseInt(nextMessageElement
+					.getAttributeValue("type"));
+		}
+
+		while (!nextMatchFound && sequenceIterator.hasNext()) {
+			currentMessage = sequenceIterator.next();
+			if (type == currentMessage.getType()) {
+				isCurrentMatch = evalEqualRestrictions(currentMessage,
+						messageElement);
+				isMatch = isMatch || isCurrentMatch;
+
+				if (isCurrentMatch) {
+					handleStorage(messageElement, currentMessage);
+					currentToken.setTarget(currentMessage
+							.getXmlWindowDescription());
+					currentToken
+							.setTargetShort(currentMessage.getParentNames());
+				}
+			}
+			if (nextMessageElement != null && isMatch) {
+				// peek next message to check if the sequence ends and the next
+				// match is found
+				if (!sequenceIterator.hasNext()) {
+					return false; // sequence is over, but not all messages are
+									// found
+				}
+				nextMessage = sequenceIterator.next();
+				sequenceIterator.previous();
+
+				if (nextType == nextMessage.getType()) {
+					nextMatchFound = evalEqualRestrictions(nextMessage,
+							nextMessageElement);
+				}
+
+			}
+		}
+
+		return isMatch;
+	}
+
+	/**
+	 * <p>
+	 * Handles equals-nodes.
+	 * </p>
+	 * 
+	 * @param currentMessage
+	 *            {@link Element} representing the msg-node the equals-node
+	 *            belongs to
+	 * @param messageElement
+	 *            {@link Element} representing the equals-node to be evaluated
+	 * @return true, if constraint is fulfilled; false otherwise
+	 */
+	@SuppressWarnings("unchecked")
+	private boolean evalEqualRestrictions(WindowsMessage currentMessage,
+			Element messageElement) {
+		boolean isMatch = true;
+		for (Element childElement : (List<Element>) messageElement.getChildren(
+				"equals", rulesNamespace)) {
+			List<Element> termElements = childElement.getChildren();
+			// the size 2 of termElements is guaranteed by the XML schema
+			String value1 = getTermValue(currentMessage, termElements.get(0));
+			String value2 = getTermValue(currentMessage, termElements.get(1));
+			if (value1 == null || value2 == null) {
+				isMatch = false;
+			} else {
+				isMatch = isMatch && value1.equals(value2);
+			}
+		}
+		for (Element childElement : (List<Element>) messageElement.getChildren(
+				"equalsSeq", rulesNamespace)) {
+			List<Element> termElements = childElement.getChildren();
+			List<String> values1 = getTermValueSeq(termElements.get(0));
+			List<String> values2 = getTermValueSeq(termElements.get(0));
+			if (values1 == null || values2 == null) {
+				isMatch = false;
+			} else {
+				isMatch = isMatch && values1.equals(values2);
+			}
+		}
+		return isMatch;
+	}
+
+	/**
+	 * <p>
+	 * Handles store-nodes and storeSeq-nodes.
+	 * </p>
+	 * 
+	 * @param messageElement
+	 *            {@link Element} representing the msg-node that is currently
+	 *            being evaluated
+	 * @param currentMessage
+	 *            current message in the message sequence that is matched; this
+	 *            is the message that is stored
+	 */
+	@SuppressWarnings("unchecked")
+	private void handleStorage(Element messageElement,
+			WindowsMessage currentMessage) {
+		for (Element childElement : (List<Element>) messageElement.getChildren(
+				"store", rulesNamespace)) {
+			String identifier = childElement.getAttributeValue("var");
+			messageStorage.put(identifier, currentMessage);
+			resolveHwnd(currentMessage, childElement);
+		}
+		for (Element childElement : (List<Element>) messageElement.getChildren(
+				"storeSeq", rulesNamespace)) {
+			String identifier = childElement.getAttributeValue("varSeq");
+			Object tmp = messageStorage.get(identifier);
+			List<WindowsMessage> storedSequence;
+			if (tmp == null || tmp instanceof WindowsMessage) {
+				storedSequence = new LinkedList<WindowsMessage>();
+				storedSequence.add(currentMessage);
+				messageStorage.put(identifier, storedSequence);
+			} else if (tmp instanceof List<?>) {
+				storedSequence = (List<WindowsMessage>) tmp;
+				storedSequence.add(currentMessage);
+				messageStorage.put(identifier, storedSequence);
+			}
+			resolveHwnd(currentMessage, childElement);
+		}
+	}
+
+	/**
+	 * <p>
+	 * Resolves a parameter that contains a HWND of a message to the target
+	 * string of the HWND and stores it.
+	 * </p>
+	 * 
+	 * @param currentMessage
+	 *            message whose HWND is resolved
+	 * @param childElement
+	 *            child element of the store node that represents the resolve
+	 */
+	@SuppressWarnings("unchecked")
+	private void resolveHwnd(WindowsMessage currentMessage, Element childElement) {
+		List<Element> resolveElements = childElement.getChildren("resolveHwnd",
+				rulesNamespace);
+		for (Element resolveElement : resolveElements) {
+			String param = resolveElement.getAttributeValue("param");
+			String storeParam = resolveElement.getAttributeValue("storeParam");
+			int paramHwnd = Integer
+					.parseInt(currentMessage.getParameter(param));
+			WindowTreeNode node = WindowTree.getInstance().find(paramHwnd);
+			if (node != null) {
+				currentMessage.addParameter(storeParam,
+						node.xmlRepresentation());
+			}
+		}
+	}
+
+	// /////////////////////////////////////////////////////
+	// Helper functions for generating the replay, i.e.,
+	// parsing of genMsg und genMsgSeq-nodes
+	// /////////////////////////////////////////////////////
+
+	/**
+	 * <p>
+	 * Handles genMsg-nodes and adds the replay to the {@link Event} that is
+	 * generated.
+	 * </p>
+	 * 
+	 * @param genMsgElement
+	 *            {@link Element} representing the genMsg-node
+	 */
+	@SuppressWarnings("unchecked")
+	private void generateReplayMessage(Element genMsgElement) {
+		List<Element> genMsgChildren = genMsgElement.getChildren();
+		WindowsMessage generatedMessage = null;
+		if (genMsgChildren.size() == 1) { // replay stored message without
+											// change
+			String obj = genMsgChildren.get(0).getAttributeValue("obj");
+			generatedMessage = getStoredMessageVariable(null, obj);
+		} else { // generate message according to the rule
+			for (Element genMsgChild : genMsgChildren) {
+				Element termElement = (Element) genMsgChild.getChildren()
+						.get(0);
+				if (genMsgChild.getName().equals("type")) {
+					try {
+						int msgType = Integer.parseInt(getTermValue(null,
+								termElement));
+						generatedMessage = new WindowsMessage(msgType);
+					} catch (NumberFormatException e) {
+						throw new InvalidParameterException(
+								"Failure generating replay sequence for rule "
+										+ currentRuleName
+										+ ": Defined type is not an integer.");
+					}
+				} else if (genMsgChild.getName().equals("target")) {
+					String targetString = getTermValue(null, termElement);
+					generatedMessage.setXmlWindowDescription(targetString);
+				} else if (genMsgChild.getName().equals("LPARAM")) {
+					String paramValueStr = getTermValue(null, termElement);
+					long paramValue = 0;
+					Element loword = genMsgChild.getChild("LOWORD",
+							rulesNamespace);
+					if (loword != null) {
+						paramValue = loHiWord(genMsgChild);
+						generatedMessage.setLPARAM(paramValue);
+					} else {
+						try {
+							paramValue = Integer.parseInt(paramValueStr);
+							generatedMessage.setLPARAM(paramValue);
+						} catch (NumberFormatException e) {
+							generatedMessage
+									.setLPARAMasWindowDesc(paramValueStr);
+						}
+					}
+				} else if (genMsgChild.getName().equals("WPARAM")) {
+					String paramValueStr = getTermValue(null, termElement);
+					long paramValue = 0;
+					Element loword = genMsgChild.getChild("LOWORD",
+							rulesNamespace);
+					if (loword != null) {
+						paramValue = loHiWord(genMsgChild);
+						generatedMessage.setWPARAM(paramValue);
+					} else {
+						try {
+							paramValue = Integer.parseInt(paramValueStr);
+							generatedMessage.setWPARAM(paramValue);
+						} catch (NumberFormatException e) {
+							generatedMessage
+									.setWPARAMasWindowDesc(paramValueStr);
+						}
+					}
+				}
+			}
+		}
+		if (generatedMessage != null) {
+			int delay = Integer.parseInt(genMsgElement
+					.getAttributeValue("delay"));
+			generatedMessage.setDelay(delay);
+		} else {
+			currentToken.invalidateReplay();
+		}
+		currentToken.addReplayEvent(generatedMessage);
+	}
+
+	/**
+	 * Handles genMsgSeq-nodes and adds the replay to the {@link Event} that is
+	 * generated.</p>
+	 * 
+	 * @param genMsgElement
+	 *            {@link Element} representing the genMsgSeq-node.
+	 */
+	@SuppressWarnings("unchecked")
+	private void generateReplaySequence(Element genMsgElement) {
+		List<Element> genMsgSeqChildren = genMsgElement.getChildren();
+		List<WindowsMessage> generatedMessageSeq = new LinkedList<WindowsMessage>();
+		if (genMsgSeqChildren.size() == 1) {
+			String obj = genMsgSeqChildren.get(0).getAttributeValue("seqObj");
+			generatedMessageSeq = getStoredSeqVariable(obj);
+		} else {
+			boolean msgsGenerated = false;
+			int constMsgType = 0;
+			for (Element genMsgSeqChild : genMsgSeqChildren) {
+				Element termElement = (Element) genMsgSeqChild.getChildren()
+						.get(0);
+				if (genMsgSeqChild.getName().equals("type")) {
+					// note: cannot easily be extracted because of mulitple
+					// return values
+					if (termElement.getName().equals("seqValue")) {
+						String obj = termElement.getAttributeValue("seqObj");
+						List<WindowsMessage> seqVar = getStoredSeqVariable(obj);
+						for (WindowsMessage msg : seqVar) {
+							generatedMessageSeq.add(new WindowsMessage(msg
+									.getType()));
+						}
+						msgsGenerated = true;
+					} else { // constValue type
+						constMsgType = Integer.parseInt(getTermValue(null,
+								termElement));
+					}
+				} else if (genMsgSeqChild.getName().equals("target")) {
+					msgsGenerated = createSequenceTarget(generatedMessageSeq,
+							msgsGenerated, constMsgType, termElement);
+				} else if (genMsgSeqChild.getName().equals("LPARAM")) {
+					msgsGenerated = createSequenceLParam(generatedMessageSeq,
+							msgsGenerated, constMsgType, termElement);
+				} else if (genMsgSeqChild.getName().equals("WPARAM")) {
+					msgsGenerated = createSequenceWParam(generatedMessageSeq,
+							msgsGenerated, constMsgType, termElement);
+				}
+			}
+		}
+		currentToken.addReplaySequence(generatedMessageSeq);
+	}
+
+	/**
+	 * <p>
+	 * Creates the targets for replay sequences generated with genMsgSeq-nodes.
+	 * </p>
+	 * 
+	 * @param generatedMessageSeq
+	 *            list of the messages that is being generated
+	 * @param msgsGenerated
+	 *            boolean stating if the list of messages is already generated
+	 *            or if the generation has to be handles by this method
+	 * @param constMsgType
+	 *            a constant message type that is used for message generation,
+	 *            in case the list of message is generated by this method
+	 * @param termElement
+	 *            {@link Element} representing the term-node describing the
+	 *            target
+	 * @return true, if the list of message is generated after calling this
+	 *         method; false otherwise
+	 * @throws NoSuchElementException
+	 *             thrown if the seqVar referred to in the termElement contains
+	 *             a different number of messages than is contained in
+	 *             messageSeq
+	 */
+	private boolean createSequenceTarget(
+			List<WindowsMessage> generatedMessageSeq, boolean msgsGenerated,
+			int constMsgType, Element termElement)
+			throws NoSuchElementException {
+		Iterator<WindowsMessage> seqIterator = generatedMessageSeq.iterator();
+		if (termElement.getName().equals("seqValue")) {
+			String obj = termElement.getAttributeValue("seqObj");
+			List<WindowsMessage> seqVar = getStoredSeqVariable(obj);
+			if (msgsGenerated && seqVar.size() != generatedMessageSeq.size()) {
+				throw new InvalidParameterException(
+						"Failure generating replay sequence for rule "
+								+ currentRuleName
+								+ ": One or more of the sequence variables used to generate a sequence have different lenghts.");
+			}
+			for (WindowsMessage msg : seqVar) {
+				WindowsMessage currentSeqMsg = getCurrentSeqMsg(
+						generatedMessageSeq, msgsGenerated, constMsgType,
+						seqIterator);
+				String targetString = msg.getParameter(termElement
+						.getAttributeValue("param"));
+				currentSeqMsg.setXmlWindowDescription(targetString);
+			}
+			msgsGenerated = true;
+		} else { // const value
+			throw new AssertionError("target must be a sequence variable!");
+			/*
+			 * If target would not be a variable, the message-elements could not
+			 * yet be created and the whole sequence might be broken. If this is
+			 * to be changed, createSequenceLParam and createSequenceWParam need
+			 * to be addepted, too.
+			 */
+		}
+		return msgsGenerated;
+	}
+
+	/**
+	 * <p>
+	 * Creates the LPARAMs for replay sequences generated with genMsgSeq-nodes.
+	 * </p>
+	 * 
+	 * @param generatedMessageSeq
+	 *            list of the messages that is being generated
+	 * @param msgsGenerated
+	 *            boolean stating if the list of messages is already generated
+	 *            or if the generation has to be handles by this method
+	 * @param constMsgType
+	 *            a constant message type that is used for message generation,
+	 *            in case the list of message is generated by this method
+	 * @param termElement
+	 *            {@link Element} representing the term-node describing the
+	 *            LPARAM
+	 * @return true, if the list of message is generated after calling this
+	 *         method; false otherwise
+	 * @throws NoSuchElementException
+	 *             thrown if the seqVar referred to in the termElement contains
+	 *             a different number of messages than is contained in
+	 *             messageSeq
+	 */
+	private boolean createSequenceLParam(
+			List<WindowsMessage> generatedMessageSeq, boolean msgsGenerated,
+			int constMsgType, Element termElement)
+			throws NoSuchElementException {
+		Iterator<WindowsMessage> seqIterator = generatedMessageSeq.iterator();
+		if (termElement.getName().equals("seqValue")) {
+			String obj = termElement.getAttributeValue("seqObj");
+			List<WindowsMessage> seqVar = getStoredSeqVariable(obj);
+			if (msgsGenerated && seqVar.size() != generatedMessageSeq.size()) {
+				throw new InvalidParameterException(
+						"Failure generating replay sequence for rule "
+								+ currentRuleName
+								+ ": One or more of the sequence variables used to generate a sequence have different lenghts.");
+			}
+			for (WindowsMessage msg : seqVar) {
+				WindowsMessage currentSeqMsg = getCurrentSeqMsg(
+						generatedMessageSeq, msgsGenerated, constMsgType,
+						seqIterator);
+				String paramValueStr = msg.getParameter(termElement
+						.getAttributeValue("param"));
+				int paramValue = 0;
+				try {
+					paramValue = Integer.parseInt(paramValueStr);
+					currentSeqMsg.setLPARAM(paramValue);
+				} catch (NumberFormatException e) {
+					currentSeqMsg.setLPARAMasWindowDesc(paramValueStr);
+				}
+			}
+			if (seqIterator.hasNext()) {
+				// the first seq-var has a different number of elements than the
+				// current one
+				throw new NoSuchElementException();
+			}
+			msgsGenerated = true;
+		} else { // const value
+			int paramValue = Integer.parseInt(getTermValue(null, termElement));
+			while (seqIterator.hasNext()) {
+				seqIterator.next().setLPARAM(paramValue);
+			}
+		}
+		return msgsGenerated;
+	}
+
+	/**
+	 * <p>
+	 * Creates the WPARAMs for replay sequences generated with genMsgSeq-nodes.
+	 * </p>
+	 * 
+	 * @param generatedMessageSeq
+	 *            list of the messages that is being generated
+	 * @param msgsGenerated
+	 *            boolean stating if the list of messages is already generated
+	 *            or if the generation has to be handles by this method
+	 * @param constMsgType
+	 *            a constant message type that is used for message generation,
+	 *            in case the list of message is generated by this method
+	 * @param termElement
+	 *            {@link Element} representing the term-node describing the
+	 *            WPARAM
+	 * @return true, if the list of message is generated after calling this
+	 *         method; false otherwise
+	 * @throws NoSuchElementException
+	 *             thrown if the seqVar referred to in the termElement contains
+	 *             a different number of messages than is contained in
+	 *             messageSeq
+	 */
+	private boolean createSequenceWParam(
+			List<WindowsMessage> generatedMessageSeq, boolean msgsGenerated,
+			int constMsgType, Element termElement)
+			throws NoSuchElementException {
+		Iterator<WindowsMessage> seqIterator = generatedMessageSeq.iterator();
+		if (termElement.getName().equals("seqValue")) {
+			String obj = termElement.getAttributeValue("seqObj");
+			List<WindowsMessage> seqVar = getStoredSeqVariable(obj);
+			if (msgsGenerated && seqVar.size() != generatedMessageSeq.size()) {
+				throw new InvalidParameterException(
+						"Failure generating replay sequence for rule "
+								+ currentRuleName
+								+ ": One or more of the sequence variables used to generate a sequence have different lenghts.");
+			}
+			for (WindowsMessage msg : seqVar) {
+				WindowsMessage currentSeqMsg = getCurrentSeqMsg(
+						generatedMessageSeq, msgsGenerated, constMsgType,
+						seqIterator);
+				String paramValueStr = msg.getParameter(termElement
+						.getAttributeValue("param"));
+				int paramValue = 0;
+				try {
+					paramValue = Integer.parseInt(paramValueStr);
+					currentSeqMsg.setWPARAM(paramValue);
+				} catch (NumberFormatException e) {
+					currentSeqMsg.setWPARAMasWindowDesc(paramValueStr);
+				}
+			}
+			if (seqIterator.hasNext()) {
+				// the first seq-var has a different number of elements than the
+				// current one
+				throw new NoSuchElementException();
+			}
+			msgsGenerated = true;
+		} else { // const value
+			int paramValue = Integer.parseInt(getTermValue(null, termElement));
+			while (seqIterator.hasNext()) {
+				seqIterator.next().setWPARAM(paramValue);
+			}
+		}
+		return msgsGenerated;
+	}
+
+	/**
+	 * <p>
+	 * If a message sequence is already generated, i.e., msgsGenerated is true,
+	 * the seqIterator is used to iterate through these messages and return the
+	 * current one. If the message sequence is not yet generated, i.e.,
+	 * msgsGenerated is false, the message sequence is generated on the fly
+	 * during each call of this message and the newly generated messages are
+	 * returned.
+	 * </p>
+	 * 
+	 * @param generatedMessageSeq
+	 *            message sequence
+	 * @param msgsGenerated
+	 *            indicates if generatedMessageSeq is already generated or has
+	 *            to be generated on the fly by this method
+	 * @param constMsgType
+	 *            type of the message to be used for message generation
+	 * @param seqIterator
+	 *            iterates through an already generated message sequence; must
+	 *            not be {@code null}, if msgsGenerated is true
+	 * @return current message
+	 */
+	private WindowsMessage getCurrentSeqMsg(
+			List<WindowsMessage> generatedMessageSeq, boolean msgsGenerated,
+			int constMsgType, Iterator<WindowsMessage> seqIterator) {
+		WindowsMessage currentSeqMsg = null;
+		if (msgsGenerated) {
+			currentSeqMsg = seqIterator.next();
+		} else {
+			currentSeqMsg = new WindowsMessage(constMsgType);
+			generatedMessageSeq.add(currentSeqMsg);
+		}
+		return currentSeqMsg;
+	}
+
+	// ////////////////////////////
+	// General helper functions //
+	// ////////////////////////////
+
+	/**
+	 * <p>
+	 * Retrieves a message from the storage for, e.g., comparison or replay.
+	 * "this" is used to refer to the current message.
+	 * </p>
+	 * 
+	 * @param currentMessage
+	 *            current message during the parsing; passed to handle "this"
+	 * @param obj
+	 *            object identifier in the storage
+	 * @return message retrieved from the storage
+	 * @throws InvalidParameterException
+	 *             thrown in case of invalid uses of "this" or if no message
+	 *             with the identifier obj is found in the storage
+	 */
+	private WindowsMessage getStoredMessageVariable(
+			WindowsMessage currentMessage, String obj)
+			throws InvalidParameterException {
+		WindowsMessage varMessage = null;
+		if (obj.equals("this")) {
+			if (currentMessage == null) {
+				throw new InvalidParameterException(
+						"Failure obtaining term value for rule "
+								+ currentRuleName
+								+ ": \"this\" is not a valid name for generating runtime messages.");
+			}
+			varMessage = currentMessage;
+		} else {
+			Object tmp = messageStorage.get(obj);
+			if (tmp instanceof WindowsMessage) {
+				varMessage = (WindowsMessage) tmp;
+			} else {
+				throw new InvalidParameterException(
+						"Failure obtaining term value for rule "
+								+ currentRuleName + ": No message \"" + obj
+								+ "\" stored.");
+			}
+		}
+		return varMessage;
+	}
+
+	/**
+	 * <p>
+	 * Retrieves a stored message sequence from the storage.
+	 * </p>
+	 * 
+	 * @param obj
+	 *            object identifier in the storage
+	 * @return message sequence retrieved from the storage
+	 * @throws InvalidParameterException
+	 *             thrown if no message sequences with the identifier obj is
+	 *             found in the storage
+	 */
+	@SuppressWarnings("unchecked")
+	private List<WindowsMessage> getStoredSeqVariable(String obj)
+			throws InvalidParameterException {
+		List<WindowsMessage> varMsgSeq = null;
+		Object tmp = messageStorage.get(obj);
+		if (tmp instanceof List<?>) {
+			varMsgSeq = (List<WindowsMessage>) tmp;
+		} else {
+			throw new InvalidParameterException(
+					"Failure obtaining term value for rule " + currentRuleName
+							+ ": No sequence \"" + obj + "\" store.");
+		}
+		return varMsgSeq;
+	}
+
+	/**
+	 * <p>
+	 * Handles term-nodes and returns the value of the described term.
+	 * </p>
+	 * 
+	 * @param currentMessage
+	 *            current message during the parsing; required to resolve
+	 *            references to "this" in a term
+	 * @param termElement
+	 *            {@link Element} representing the term node
+	 * @return value of the term or {@code null} of the term node could not be
+	 *         evaluated
+	 */
+	private String getTermValue(WindowsMessage currentMessage,
+			Element termElement) {
+		String value = null;
+		WindowsMessage varMessage = null;
+		if (termElement.getName().equals("constValue")) {
+			value = termElement.getAttributeValue("value");
+		} else if (termElement.getName().equals("paramValue")) {
+			String objectName = termElement.getAttributeValue("obj");
+			varMessage = getStoredMessageVariable(currentMessage, objectName);
+			if (varMessage != null) {
+				String param = termElement.getAttributeValue("param");
+				value = varMessage.getParameter(param);
+			}
+		} else if (termElement.getName().equals("winInfoValue")) {
+			String objectName = termElement.getAttributeValue("obj");
+			varMessage = getStoredMessageVariable(currentMessage, objectName);
+			if (varMessage != null) {
+				String paramString = termElement.getAttributeValue("winParam");
+				if (paramString.equals("class")) {
+					value = varMessage.getWindowClass();
+				} else if (paramString.equals("resourceId")) {
+					value = "" + varMessage.getWindowResourceId();
+				} else if (paramString.equals("hwnd")) {
+					value = "" + varMessage.getHwnd();
+				} else if (paramString.equals("parentTarget")) {
+					String target = varMessage.getXmlWindowDescription();
+					int index = target.lastIndexOf("<");
+					if (index == 0) {
+						Console.traceln("Trying to adress parent of top-level window! Replay probably invalid!");
+					}
+					value = target.substring(0, index);
+				} else if (paramString.equals("parentClass")) {
+					value = varMessage.getParentClass();
+				}
+			}
+		} else if (termElement.getName().equals("msgInfoValue")) {
+			String objectName = termElement.getAttributeValue("obj");
+			varMessage = getStoredMessageVariable(currentMessage, objectName);
+			if (varMessage != null) {
+				String paramString = termElement.getAttributeValue("msgParam");
+				if (paramString.equals("type")) {
+					value = "" + varMessage.getType();
+				} else if (paramString.equals("target")) {
+					value = varMessage.getXmlWindowDescription();
+				}
+			}
+		}
+		return value;
+	}
+
+	/**
+	 * <p>
+	 * Handles term-nodes contained by equalSeq nodes.
+	 * </p>
+	 * 
+	 * @param termElement
+	 *            {@link Element} representing the term-node
+	 * @return list of values of the term
+	 */
+	private List<String> getTermValueSeq(Element termElement) {
+		List<String> values = new LinkedList<String>();
+		if (termElement.getName().equals("seqValue")) {
+			String obj = termElement.getAttributeValue("seqObj");
+			String param = termElement.getAttributeValue("param");
+			List<WindowsMessage> seqVar = getStoredSeqVariable(obj);
+
+			for (WindowsMessage msg : seqVar) {
+				// msg.getParameter returns null, if parameter is not found,
+				// therefore the List can contain null-values
+				values.add(msg.getParameter(param));
+			}
+		}
+		return values;
+	}
+
+	/**
+	 * <p>
+	 * Handles LOWORD and HIWORD child nodes of LPARAM and WPARAM nodes. The
+	 * returned value is the LPARAM/WPARAM value based on the LOWORD and HIWORD.
+	 * </p>
+	 * 
+	 * @param param
+	 *            {@link Element} representing the LPARAM/WPARAM node
+	 * @return value of the LPARAM/WPARAM
+	 */
+	private long loHiWord(Element param) {
+		Element loword = param.getChild("LOWORD", rulesNamespace);
+		Element hiword = param.getChild("HIWORD", rulesNamespace);
+		String lowordStr = getTermValue(null, (Element) loword.getChildren()
+				.get(0));
+		String hiwordStr = getTermValue(null, (Element) hiword.getChildren()
+				.get(0));
+		return MAKEPARAM(Short.parseShort(lowordStr),
+				Short.parseShort(hiwordStr));
+	}
+
+	/**
+	 * <p>
+	 * Takes to short integers and combines them into the high and low order
+	 * bits of an integer.
+	 * </p>
+	 * 
+	 * @param loword
+	 *            low word
+	 * @param hiword
+	 *            high word
+	 * @return combined integer
+	 */
+	private static int MAKEPARAM(short loword, short hiword) {
+		return loword | ((int) hiword) << Short.SIZE;
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/HandlerCreate.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/HandlerCreate.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/HandlerCreate.java	(revision 540)
@@ -0,0 +1,125 @@
+package de.ugoe.cs.quest.plugin.mfc;
+
+import de.ugoe.cs.quest.plugin.mfc.eventcore.WindowTree;
+
+/**
+ * <p>
+ * Message handler for {@code WM_CREATE} messages. The handler maintains the
+ * {@link WindowTree}.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class HandlerCreate extends MessageHandler {
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new HandlerCreate.
+	 * </p>
+	 */
+	public HandlerCreate() {
+		super();
+	}
+
+	/**
+	 * <p>
+	 * Name of the created window.
+	 * </p>
+	 */
+	private String windowName;
+
+	/**
+	 * <p>
+	 * HWND of the created window.
+	 * </p>
+	 */
+	private int hwnd;
+
+	/**
+	 * <p>
+	 * HWND of the created window's parent.
+	 * </p>
+	 */
+	private int parentHwnd;
+
+	/**
+	 * <p>
+	 * Resource Id of the created window.
+	 * </p>
+	 */
+	private int resourceId;
+
+	/**
+	 * <p>
+	 * Window class of the created window.
+	 * </p>
+	 */
+	private String className;
+
+	/**
+	 * <p>
+	 * Modality of the created window.
+	 * </p>
+	 */
+	private boolean isModal;
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.plugin.mfc.MessageHandler#onEndElement()
+	 */
+	@Override
+	public void onEndElement() {
+		if (hwnd != 0) {
+			WindowTree.getInstance().add(parentHwnd, hwnd, windowName,
+					resourceId, className, isModal);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * de.ugoe.cs.quest.plugin.mfc.MessageHandler#onParameter(java.lang.String
+	 * , java.lang.String)
+	 */
+	@Override
+	public void onParameter(String name, String value) {
+		if (name.equals("window.hwnd")) {
+			hwnd = Integer.parseInt(value);
+		} else if (name.equals("window.name")) {
+			windowName = value;
+		} else if (name.equals("window.parent.hwnd")) {
+			parentHwnd = Integer.parseInt(value);
+		} else if (name.equals("window.resourceId")) {
+			resourceId = Integer.parseInt(value);
+		} else if (name.equals("window.class")) {
+			if (value.startsWith("Afx:")) {
+				className = "Afx:";
+			} else {
+				className = value;
+			}
+		} else if (name.equals("window.ismodal")) {
+			if (value.equals("true") || value.equals("1")) {
+				isModal = true;
+			}
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.plugin.mfc.MessageHandler#onStartElement()
+	 */
+	@Override
+	public void onStartElement() {
+		windowName = "";
+		hwnd = 0;
+		parentHwnd = 0;
+		resourceId = 0;
+		className = "";
+		isModal = false;
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/HandlerDestroy.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/HandlerDestroy.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/HandlerDestroy.java	(revision 540)
@@ -0,0 +1,68 @@
+package de.ugoe.cs.quest.plugin.mfc;
+
+import de.ugoe.cs.quest.plugin.mfc.eventcore.WindowTree;
+
+/**
+ * <p>
+ * Handler for {@code WM_DESTROY} message. The handler maintains the
+ * {@link WindowTree}.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class HandlerDestroy extends MessageHandler {
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new HandlerDestroy.
+	 * </p>
+	 */
+	public HandlerDestroy() {
+		super();
+	}
+
+	/**
+	 * <p>
+	 * HWND of the window that is destroyed.
+	 * </p>
+	 */
+	private int hwnd;
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.plugin.mfc.MessageHandler#onEndElement()
+	 */
+	@Override
+	public void onEndElement() {
+		if (hwnd != 0) {
+			WindowTree.getInstance().remove(hwnd);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * de.ugoe.cs.quest.plugin.mfc.MessageHandler#onParameter(java.lang.String
+	 * , java.lang.String)
+	 */
+	@Override
+	public void onParameter(String name, String value) {
+		if (name.equals("window.hwnd")) {
+			hwnd = Integer.parseInt(value);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.plugin.mfc.MessageHandler#onStartElement()
+	 */
+	@Override
+	public void onStartElement() {
+		hwnd = 0;
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/HandlerSetText.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/HandlerSetText.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/HandlerSetText.java	(revision 540)
@@ -0,0 +1,78 @@
+package de.ugoe.cs.quest.plugin.mfc;
+
+import de.ugoe.cs.quest.plugin.mfc.eventcore.WindowTree;
+import de.ugoe.cs.quest.plugin.mfc.eventcore.WindowTreeNode;
+
+/**
+ * <p>
+ * Handles {@code WM_SETTEXT} messages. Handler maintains the {@link WindowTree}.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class HandlerSetText extends MessageHandler {
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new HanderSetText.
+	 * </p>
+	 */
+	public HandlerSetText() {
+		super();
+	}
+
+	/**
+	 * <p>
+	 * New name of the window.
+	 * </p>
+	 */
+	private String windowName;
+
+	/**
+	 * <p>
+	 * HWND of the window.
+	 * </p>
+	 */
+	private int hwnd;
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.plugin.mfc.MessageHandler#onEndElement()
+	 */
+	@Override
+	public void onEndElement() {
+		if (hwnd != 0) {
+			WindowTreeNode node = WindowTree.getInstance().find(hwnd);
+			node.setName(windowName);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * de.ugoe.cs.quest.plugin.mfc.MessageHandler#onParameter(java.lang.String
+	 * , java.lang.String)
+	 */
+	@Override
+	public void onParameter(String name, String value) {
+		if (name.equals("window.hwnd")) {
+			hwnd = Integer.parseInt(value);
+		} else if (name.equals("window.newText")) {
+			windowName = value;
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.plugin.mfc.MessageHandler#onStartElement()
+	 */
+	@Override
+	public void onStartElement() {
+		windowName = "";
+		hwnd = 0;
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/LogPreprocessor.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/LogPreprocessor.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/LogPreprocessor.java	(revision 540)
@@ -0,0 +1,219 @@
+package de.ugoe.cs.quest.plugin.mfc;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+
+import org.apache.commons.codec.binary.Base64;
+
+import de.ugoe.cs.util.FileTools;
+import de.ugoe.cs.util.StringTools;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Pre-processes log files generated by the EventBench's MFCUsageMonitor. It
+ * decodes Base64 encoding into UTF-16. It removes all lines of the log file,
+ * that do not start with the prefix "UL:", end everything before the prefix and
+ * the prefix itself.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class LogPreprocessor {
+
+	/**
+	 * <p>
+	 * Internal flag that monitors whether there is an open session-node in the
+	 * XML file to ensure that there is a closing session-node for each opening
+	 * session node and, thereby, ensure that the XML file is well formed.
+	 * </p>
+	 */
+	private boolean sessionOpen = false;
+
+	/**
+	 * <p>
+	 * Internal flag that monitors whether a message node is longer than one
+	 * line, as the prefix handling is different in this case.
+	 * </p>
+	 */
+	private boolean msgIncomplete = false;
+
+	/**
+	 * <p>
+	 * Flag that marks whether the log file is Base64 encoded.
+	 * </p>
+	 */
+	private boolean base64;
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new LogPreprocessor that does not decode Base64.
+	 * </p>
+	 */
+	public LogPreprocessor() {
+		this(false);
+	}
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new LogPreprocessor.
+	 * </p>
+	 * 
+	 * @param base64
+	 *            if true, Base64 will be decoded.
+	 */
+	public LogPreprocessor(boolean base64) {
+		this.base64 = base64;
+	}
+
+	/**
+	 * <p>
+	 * Pre-processes a single log file.
+	 * </p>
+	 * 
+	 * @param source
+	 *            name and path of the source file
+	 * @param target
+	 *            name and path of the target file
+	 * @throws IOException
+	 *             thrown if there is a problem with reading from or writing to
+	 *             the source, respectively target file
+	 * @throws FileNotFoundException
+	 *             thrown if the source file is not found
+	 */
+	public void convertToXml(String source, String target) throws IOException,
+			FileNotFoundException {
+		OutputStreamWriter targetFile = new OutputStreamWriter(
+				new FileOutputStream(target), "UTF-8");
+		targetFile.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+				+ StringTools.ENDLINE);
+		targetFile.write("<log>" + StringTools.ENDLINE);
+		processFile(source, targetFile);
+		if (sessionOpen) {
+			targetFile.write(" </session>" + StringTools.ENDLINE);
+		}
+		targetFile.write("</log>");
+		targetFile.close();
+	}
+
+	/**
+	 * <p>
+	 * Pre-processes all files in a given source folder.
+	 * </p>
+	 * 
+	 * @param path
+	 *            path of the source folder
+	 * @param target
+	 *            name and path of the target file
+	 * @throws IOException
+	 *             thrown if there is a problem with reading from or writing to
+	 *             the source, respectively target file
+	 * @throws FileNotFoundException
+	 *             thrown if the source file is not found
+	 */
+	public void convertDirToXml(String path, String target) throws IOException,
+			FileNotFoundException {
+		OutputStreamWriter targetFile = new OutputStreamWriter(
+				new FileOutputStream(target), "UTF-8");
+		targetFile.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+				+ StringTools.ENDLINE);
+		targetFile.write("<log>" + StringTools.ENDLINE);
+		File folder = new File(path);
+		if (!folder.isDirectory()) {
+			throw new IOException(path + " is not a directory");
+		}
+		String absolutPath = folder.getAbsolutePath();
+		for (String filename : folder.list()) {
+			String source = absolutPath + "/" + filename;
+			Console.traceln("Processing file: " + source);
+			processFile(source, targetFile);
+		}
+
+		if (sessionOpen) {
+			targetFile.write(" </session>" + StringTools.ENDLINE);
+		}
+		targetFile.write("</log>");
+		targetFile.close();
+	}
+
+	/**
+	 * <p>
+	 * Internal function that pre-processes a log file.
+	 * </p>
+	 * 
+	 * @param source
+	 *            name and path of the source file
+	 * @param target
+	 *            name and path of the target file
+	 * @throws IOException
+	 *             thrown if there is a problem with reading from or writing to
+	 *             the source, respectively target file
+	 * @throws FileNotFoundException
+	 *             thrown if the source file is not found
+	 */
+	private void processFile(String source, OutputStreamWriter targetFile)
+			throws FileNotFoundException, IOException {
+		String[] lines = FileTools.getLinesFromFile(source, false);
+		String incompleteLine = "";
+		for (String currentLine : lines) {
+			if (currentLine.contains("UL: <session>")) {
+				if (sessionOpen) {
+					targetFile.write(" </session>" + StringTools.ENDLINE);
+					targetFile.write(" <session>" + StringTools.ENDLINE);
+				} else {
+					targetFile.write(" <session>" + StringTools.ENDLINE);
+					sessionOpen = true;
+				}
+			} else if (currentLine.contains("UL: </session>")) {
+				if (sessionOpen) {
+					targetFile.write(" </session>" + StringTools.ENDLINE);
+					sessionOpen = false;
+				}
+			} else if (msgIncomplete || currentLine.contains("UL: ")) {
+
+				String currentContent;
+				String actualLine;
+				if (msgIncomplete) {
+					actualLine = currentLine;
+				} else {
+					String[] splitResult = currentLine.split("UL: ");
+					actualLine = splitResult[1];
+				}
+				if (base64) {
+					Base64 decoder = new Base64();
+					byte[] decoded = decoder.decode(actualLine);
+					currentContent = new String(decoded, "UTF-16LE");
+					if( currentContent.length()!=0 ) {
+						currentContent = currentContent.substring(0,
+								currentContent.length() - 1);
+					}
+				} else {
+					currentContent = actualLine;
+				}
+				if (msgIncomplete) {
+					incompleteLine += currentContent;
+					if (incompleteLine.contains("</msg>")) {
+						msgIncomplete = false;
+						targetFile.write(incompleteLine + StringTools.ENDLINE);
+						incompleteLine = "";
+					}
+				} else {
+					if (currentContent.contains("<msg") && sessionOpen) {
+						if (currentContent.contains("</msg>")) {
+							targetFile.write("  " + currentContent
+									+ StringTools.ENDLINE);
+						} else {
+							msgIncomplete = true;
+							incompleteLine += currentContent;
+						}
+					}
+				}
+			}
+		}
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/MFCLogParser.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/MFCLogParser.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/MFCLogParser.java	(revision 540)
@@ -0,0 +1,277 @@
+package de.ugoe.cs.quest.plugin.mfc;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.security.InvalidParameterException;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.helpers.DefaultHandler;
+
+import de.ugoe.cs.quest.plugin.mfc.eventcore.WindowTree;
+import de.ugoe.cs.quest.plugin.mfc.eventcore.WindowsEvent;
+import de.ugoe.cs.quest.plugin.mfc.eventcore.WindowsMessage;
+import de.ugoe.cs.util.StringTools;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * This class provides functionality to parse XML log files generated by the
+ * MFCUsageMonitor of EventBench. The result of parsing a file is a collection
+ * of event sequences. It uses the {@link SequenceSplitter} and the
+ * {@link EventGenerator} as well as custom defined {@link MessageHandler} for
+ * the parsing.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class MFCLogParser extends DefaultHandler {
+
+	/**
+	 * <p>
+	 * If a custom message handler is used, this field contains its handle.
+	 * Otherwise this field is {@code null}.
+	 * </p>
+	 */
+	private MessageHandler currentHandler;
+
+	/**
+	 * <p>
+	 * Handle to the message that is currently parsed.
+	 * </p>
+	 */
+	private WindowsMessage currentMessage;
+
+	/**
+	 * <p>
+	 * {@link SequenceSplitter} instance used by the {@link MFCLogParser}.
+	 * </p>
+	 */
+	private SequenceSplitter sequenceSplitter;
+
+	/**
+	 * <p>
+	 * Collection of event sequences that is contained in the log file, which is
+	 * parsed.
+	 * </p>
+	 */
+	private Collection<List<WindowsEvent>> sequences;
+
+	/**
+	 * <p>
+	 * Debugging variable that allows the analysis which message type occurs how
+	 * often in the log file. Can be used to enhance the message filter.
+	 * </p>
+	 */
+	private SortedMap<Integer, Integer> typeCounter;
+
+	/**
+	 * <p>
+	 * Debugging variable that enables the counting of the occurrences of each
+	 * message. Used in combination with {@link #typeCounter}.
+	 * </p>
+	 */
+	private boolean countMessageOccurences;
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new LogParser that does not count message
+	 * occurrences.
+	 * </p>
+	 */
+	public MFCLogParser() {
+		this(false);
+	}
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new LogParser.
+	 * </p>
+	 * 
+	 * @param countMessageOccurences
+	 *            if true, the occurrences of each message type in the log is
+	 *            counted.
+	 */
+	public MFCLogParser(boolean countMessageOccurences) {
+		sequenceSplitter = new SequenceSplitter();
+		sequences = new LinkedList<List<WindowsEvent>>();
+		currentHandler = null;
+		this.countMessageOccurences = countMessageOccurences;
+		if (countMessageOccurences) {
+			typeCounter = new TreeMap<Integer, Integer>();
+		}
+
+	}
+
+	/**
+	 * <p>
+	 * Returns the collection of event sequences that is obtained from parsing
+	 * log files.
+	 * </p>
+	 * 
+	 * @return collection of event sequences
+	 */
+	public Collection<List<WindowsEvent>> getSequences() {
+		return sequences;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String,
+	 * java.lang.String, java.lang.String, org.xml.sax.Attributes)
+	 */
+	@Override
+	public void startElement(String uri, String localName, String qName,
+			Attributes atts) throws SAXException {
+		if (qName.equals("session")) {
+			Console.traceln("start of session");
+			sequenceSplitter = new SequenceSplitter();
+		} else if (qName.equals("msg")) {
+			String msgType = atts.getValue("type");
+			int msgInt = -1;
+			try {
+				msgInt = Integer.parseInt(msgType);
+
+				if (countMessageOccurences) {
+					Integer currentCount = typeCounter.get(msgInt);
+					if (currentCount == null) {
+						typeCounter.put(msgInt, 1);
+					} else {
+						typeCounter.put(msgInt, currentCount + 1);
+					}
+				}
+
+				if (msgInt == MessageDefs.WM_CREATE) {
+					currentHandler = new HandlerCreate();
+					currentHandler.onStartElement();
+				} else if (msgInt == MessageDefs.WM_DESTROY) {
+					currentHandler = new HandlerDestroy();
+					currentHandler.onStartElement();
+				} else if (msgInt == MessageDefs.WM_SETTEXT) {
+					currentHandler = new HandlerSetText();
+					currentHandler.onStartElement();
+				} else {
+					currentMessage = new WindowsMessage(msgInt);
+				}
+			} catch (NumberFormatException e) {
+				Console.printerrln("Invalid message type: type not a number");
+				e.printStackTrace();
+			}
+		} else if (qName.equals("param")) {
+			if (currentHandler != null) {
+				currentHandler.onParameter(atts.getValue("name"),
+						atts.getValue("value"));
+			} else {
+				currentMessage.addParameter(atts.getValue("name"),
+						atts.getValue("value"));
+			}
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String,
+	 * java.lang.String, java.lang.String)
+	 */
+	@Override
+	public void endElement(String uri, String localName, String qName)
+			throws SAXException {
+		if (qName.equals("msg")) {
+			if (currentHandler != null) {
+				currentHandler.onEndElement();
+				currentHandler = null;
+			} else {
+				try {
+					currentMessage.setTarget(WindowTree.getInstance());
+					sequenceSplitter.addMessage(currentMessage);
+				} catch (InvalidParameterException e) {
+					Console.traceln(e.getMessage() + " WindowsMessage "
+							+ currentMessage + " ignored.");
+				}
+			}
+		} else if (qName.equals("session")) {
+			sequenceSplitter.endSession();
+			List<WindowsEvent> seq = sequenceSplitter.getSequence();
+			if( seq!=null && !seq.isEmpty() ) {
+				sequences.add(seq);
+			}
+			Console.traceln("end of session");
+		}
+	}
+
+	/**
+	 * <p>
+	 * Parses a given log file created by the MFCMonitor and adds its contents
+	 * to the collection of event sequences.
+	 * </p>
+	 * 
+	 * @param filename
+	 *            name and path of the log file
+	 */
+	public void parseFile(String filename) {
+		if (filename == null) {
+			throw new InvalidParameterException("filename must not be null");
+		}
+
+		SAXParserFactory spf = SAXParserFactory.newInstance();
+		spf.setValidating(true);
+
+		SAXParser saxParser = null;
+		InputSource inputSource = null;
+		try {
+			saxParser = spf.newSAXParser();
+			inputSource = new InputSource(new InputStreamReader(
+					new FileInputStream(filename)));//, "UTF-8"));
+		//} catch (UnsupportedEncodingException e) {
+		//	e.printStackTrace();
+		} catch (ParserConfigurationException e) {
+			e.printStackTrace();
+		} catch (SAXException e) {
+			e.printStackTrace();
+		} catch (FileNotFoundException e) {
+			e.printStackTrace();
+		}
+		if (inputSource != null) {
+			inputSource.setSystemId("file://"
+					+ new File(filename).getAbsolutePath());
+			try {
+				if (saxParser == null) {
+					throw new RuntimeException("SAXParser creation failed");
+				}
+				saxParser.parse(inputSource, this);
+			} catch (SAXParseException e) {
+				Console.printerrln("Failure parsing file in line "
+						+ e.getLineNumber() + ", column " + e.getColumnNumber()
+						+ ".");
+				e.printStackTrace();
+			} catch (SAXException e) {
+				e.printStackTrace();
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+		}
+		if (countMessageOccurences) {
+			Console.println("Message statistics:");
+			Console.println(typeCounter.toString()
+					.replace(" ", StringTools.ENDLINE)
+					.replaceAll("[\\{\\}]", ""));
+		}
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/MFCReplayDecorator.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/MFCReplayDecorator.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/MFCReplayDecorator.java	(revision 540)
@@ -0,0 +1,96 @@
+package de.ugoe.cs.quest.plugin.mfc;
+
+import de.ugoe.cs.quest.IReplayDecorator;
+import de.ugoe.cs.util.StringTools;
+
+/**
+ * <p>
+ * {@link IReplayDecorator} for replay generated for EventBench's MFCReplay tool.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class MFCReplayDecorator implements IReplayDecorator {
+
+	/**
+	 * <p>
+	 * Id for object serialization.
+	 * </p>
+	 */
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * <p>
+	 * The instance of the {@link MFCReplayDecorator} (implemented as
+	 * singleton).
+	 * </p>
+	 */
+	transient private static MFCReplayDecorator theInstance;
+
+	/**
+	 * <p>
+	 * Constructor. Private to guarantee that only one instance of the replay
+	 * generator exists.
+	 * </p>
+	 */
+	private MFCReplayDecorator() {
+	};
+
+	/**
+	 * <p>
+	 * Returns the instance of the MFCReplayDecorator.
+	 * </p>
+	 * 
+	 * @return instance of the MFCReplayDecorator.
+	 */
+	public static MFCReplayDecorator getInstance() {
+		if (theInstance == null) {
+			theInstance = new MFCReplayDecorator();
+		}
+		return theInstance;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.IReplayDecorator#getHeader()
+	 */
+	@Override
+	public String getHeader() {
+		return "<?xml version=\"1.0\" encoding=\"UTF-16\"?>"
+				+ StringTools.ENDLINE + "<log>" + StringTools.ENDLINE;
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.IReplayDecorator#getFooter()
+	 */
+	@Override
+	public String getFooter() {
+		return "</log>" + StringTools.ENDLINE;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.IReplayDecorator#getSessionHeader(int)
+	 */
+	@Override
+	public String getSessionHeader(int sessionId) {
+		return " <session id=\"" + sessionId + "\">" + StringTools.ENDLINE;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.IReplayDecorator#getSessionFooter(int)
+	 */
+	@Override
+	public String getSessionFooter(int sessionId) {
+		return " </session>" + StringTools.ENDLINE;
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/MessageDefs.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/MessageDefs.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/MessageDefs.java	(revision 540)
@@ -0,0 +1,167 @@
+package de.ugoe.cs.quest.plugin.mfc;
+
+/**
+ * <p>
+ * Contains definitions of windows message codes, such that they can be used
+ * internally by their name and not their integer value, to improve the
+ * readability of the source code.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public interface MessageDefs {
+
+	public static final int WM_NULL = 0;
+	public static final int WM_CREATE = 1;
+	public static final int WM_DESTROY = 2;
+	public static final int WM_MOVE = 3;
+	public static final int WM_SIZE = 5;
+	public static final int WM_ACTIVATE = 6;
+	public static final int WM_SETFOCUS = 7;
+	public static final int WM_KILLFOCUS = 8;
+	public static final int WM_ENABLE = 10;
+	public static final int WM_SETREDRAW = 11;
+	public static final int WM_SETTEXT = 12;
+	public static final int WM_GETTEXT = 13;
+	public static final int WM_GETTEXTLENGTH = 14;
+	public static final int WM_PAINT = 15;
+	public static final int WM_CLOSE = 16;
+	public static final int WM_QUERYENDSESSION = 17;
+	public static final int WM_QUIT = 18;
+	public static final int WM_QUERYOPEN = 19;
+	public static final int WM_ERASEBKGND = 20;
+	public static final int WM_SYSCOLORCHANGE = 21;
+	public static final int WM_ENDSESSION = 22;
+	public static final int WM_SHOWWINDOW = 24;
+	public static final int WM_CTLCOLOR = 25;
+	public static final int WM_WININICHANGE = 26;
+	public static final int WM_DEVMODECHANGE = 27;
+	public static final int WM_ACTIVATEAPP = 28;
+	public static final int WM_FONTCHANGE = 29;
+	public static final int WM_TIMECHANGE = 30;
+	public static final int WM_CANCELMODE = 31;
+	public static final int WM_SETCURSOR = 32;
+	public static final int WM_MOUSEACTIVATE = 33;
+	public static final int WM_CHILDACTIVATE = 34;
+	public static final int WM_QUEUESYNC = 35;
+	public static final int WM_GETMINMAXINFO = 36;
+	public static final int WM_PAINTICON = 38;
+	public static final int WM_ICONERASEBKGND = 39;
+	public static final int WM_NEXTDLGCTL = 40;
+	public static final int WM_SPOOLERSTATUS = 42;
+	public static final int WM_DRAWITEM = 43;
+	public static final int WM_MEASUREITEM = 44;
+	public static final int WM_DELETEITEM = 45;
+	public static final int WM_VKEYTOITEM = 46;
+	public static final int WM_CHARTOITEM = 47;
+	public static final int WM_SETFONT = 48;
+	public static final int WM_GETFONT = 49;
+	public static final int WM_SETHOTKEY = 50;
+	public static final int WM_GETHOTKEY = 51;
+	public static final int WM_QUERYDRAGICON = 55;
+	public static final int WM_COMPAREITEM = 57;
+	public static final int WM_GETOBJECT = 61;
+	public static final int WM_COMPACTING = 65;
+	public static final int WM_COMMNOTIFY = 68;
+	public static final int WM_WINDOWPOSCHANGING = 70;
+	public static final int WM_WINDOWPOSCHANGED = 71;
+	public static final int WM_POWER = 72;
+	public static final int WM_COPYDATA = 74;
+	public static final int WM_CANCELJOURNAL = 75;
+	public static final int WM_NOTIFY = 78;
+	public static final int WM_INPUTLANGCHANGEREQUEST = 80;
+	public static final int WM_INPUTLANGCHANGE = 81;
+	public static final int WM_TCARD = 82;
+	public static final int WM_HELP = 83;
+	public static final int WM_USERCHANGED = 84;
+	public static final int WM_NOTIFYFORMAT = 85;
+	public static final int WM_CONTEXTMENU = 123;
+	public static final int WM_STYLECHANGING = 124;
+	public static final int WM_STYLECHANGED = 125;
+	public static final int WM_DISPLAYCHANGE = 126;
+	public static final int WM_GETICON = 127;
+	public static final int WM_SETICON = 128;
+	public static final int WM_NCCREATE = 129;
+	public static final int WM_NCDESTROY = 130;
+	public static final int WM_NCCALCSIZE = 131;
+	public static final int WM_NCHITTEST = 132;
+	public static final int WM_NCPAINT = 133;
+	public static final int WM_NCACTIVATE = 134;
+	public static final int WM_GETDLGCODE = 135;
+	public static final int WM_SYNCPAINT = 136;
+	public static final int WM_NCMOUSEMOVE = 160;
+	public static final int WM_NCLBUTTONDOWN = 161;
+	public static final int WM_NCLBUTTONUP = 162;
+	public static final int WM_NCLBUTTONDBLCLK = 163;
+	public static final int WM_NCRBUTTONDOWN = 164;
+	public static final int WM_NCRBUTTONUP = 165;
+	public static final int WM_NCRBUTTONDBLCLK = 166;
+	public static final int WM_NCMBUTTONDOWN = 167;
+	public static final int WM_NCMBUTTONUP = 168;
+	public static final int WM_NCMBUTTONDBLCLK = 169;
+	public static final int WM_NCXBUTTONDOWN = 171;
+	public static final int WM_NCXBUTTONUP = 172;
+	public static final int WM_NCXBUTTONDBLCLK = 173;
+	public static final int WM_INPUT = 255;
+	public static final int WM_KEYDOWN = 256;
+	public static final int WM_KEYFIRST = 256;
+	public static final int WM_KEYUP = 257;
+	public static final int WM_CHAR = 258;
+	public static final int WM_DEADCHAR = 259;
+	public static final int WM_SYSKEYDOWN = 260;
+	public static final int WM_SYSKEYUP = 261;
+	public static final int WM_SYSCHAR = 262;
+	public static final int WM_SYSDEADCHAR = 263;
+	public static final int WM_KEYLAST = 264;
+	public static final int WM_WNT_CONVERTREQUESTEX = 265;
+	public static final int WM_CONVERTREQUEST = 266;
+	public static final int WM_CONVERTRESULT = 267;
+	public static final int WM_INTERIM = 268;
+	public static final int WM_IME_STARTCOMPOSITION = 269;
+	public static final int WM_IME_ENDCOMPOSITION = 270;
+	public static final int WM_IME_COMPOSITION = 271;
+	public static final int WM_IME_KEYLAST = 271;
+	public static final int WM_INITDIALOG = 272;
+	public static final int WM_COMMAND = 273;
+	public static final int WM_SYSCOMMAND = 274;
+	public static final int WM_TIMER = 275;
+	public static final int WM_HSCROLL = 276;
+	public static final int WM_VSCROLL = 277;
+	public static final int WM_INITMENU = 278;
+	public static final int WM_INITMENUPOPUP = 279;
+	public static final int WM_MENUSELECT = 287;
+	public static final int WM_MENUCHAR = 288;
+	public static final int WM_ENTERIDLE = 289;
+	public static final int WM_MENURBUTTONUP = 290;
+	public static final int WM_MENUDRAG = 291;
+	public static final int WM_MENUGETOBJECT = 292;
+	public static final int WM_UNINTMENUPOPUP = 293;
+	public static final int WM_MENUCOMMAND = 294;
+	public static final int WM_CHANGEUISTATE = 295;
+	public static final int WM_UPDATEUISTATE = 296;
+	public static final int WM_QUERYUISTATE = 297;
+	public static final int WM_CTLCOLORMSGBOX = 306;
+	public static final int WM_CTLCOLOREDIT = 307;
+	public static final int WM_CTLCOLORLISTBOX = 308;
+	public static final int WM_CTLCOLORBTN = 309;
+	public static final int WM_CTLCLOLORDLG = 310;
+	public static final int WM_CTLCOLORSCROLLBAR = 311;
+	public static final int WM_CTLCOLORSTATIC = 312;
+	public static final int WM_MOUSEFIRST = 512;
+	public static final int WM_MOUSEMOVE = 512;
+	public static final int WM_LBUTTONDOWN = 513;
+	public static final int WM_LBUTTONUP = 514;
+	public static final int WM_LBUTTONDBLCLK = 515;
+	public static final int WM_RBUTTONDOWN = 516;
+	public static final int WM_RBUTTONUP = 517;
+	public static final int WM_RBUTTONDBLCLK = 518;
+	public static final int WM_MBUTTONDOWN = 519;
+	public static final int WM_MBUTTONUP = 520;
+	public static final int WM_MBUTTONDBLCLK = 521;
+	public static final int WM_MOUSELAST = 521;
+	public static final int WM_MOUSEWHEEL = 522;
+	public static final int WM_XBUTTONDOWN = 523;
+	public static final int WM_XBUTTONUP = 524;
+	public static final int WM_XBUTTONDBLCLK = 525;
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/MessageHandler.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/MessageHandler.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/MessageHandler.java	(revision 540)
@@ -0,0 +1,55 @@
+package de.ugoe.cs.quest.plugin.mfc;
+
+/**
+ * <p>
+ * Base class to define custom message handlers, for messages that shall be
+ * handled differently during the parsing of usage logs. It provides dummy
+ * implementations for all required methods, such that implementations can only
+ * overwrite the parts they actually require and ignore the rest.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class MessageHandler {
+
+	/**
+	 * <p>
+	 * Constructor. Protected to prohibit initialization of the base class
+	 * itself.
+	 * </p>
+	 */
+	protected MessageHandler() {
+	}
+
+	/**
+	 * <p>
+	 * Called in the startElement() method of the {@link MFCLogParser} when a
+	 * msg-node begins.
+	 * </p>
+	 */
+	public void onStartElement() {
+	}
+
+	/**
+	 * <p>
+	 * Called by the {@link MFCLogParser} to handle param-nodes.
+	 * </p>
+	 * 
+	 * @param name
+	 *            name (type) of the parameter
+	 * @param value
+	 *            value of the parameter
+	 */
+	public void onParameter(String name, String value) {
+	}
+
+	/**
+	 * <p>
+	 * Called in the endElement() method of {@link MFCLogParser} when a msg-node
+	 * ends.
+	 * </p>
+	 */
+	public void onEndElement() {
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/SequenceSplitter.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/SequenceSplitter.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/SequenceSplitter.java	(revision 540)
@@ -0,0 +1,287 @@
+package de.ugoe.cs.quest.plugin.mfc;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.plugin.mfc.eventcore.WindowsEvent;
+import de.ugoe.cs.quest.plugin.mfc.eventcore.WindowsMessage;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Responsible to split sequences into subsequences, such that each subsequences
+ * contains exactly one event.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class SequenceSplitter {
+
+	/**
+	 * <p>
+	 * Contains the current subsequence.
+	 * </p>
+	 */
+	private List<WindowsMessage> currentSequence;
+
+	/**
+	 * <p>
+	 * Number of messages in the current sequences, that signal that a key or
+	 * mouse button has been pressed down to which not yet a message has been
+	 * found, that signals that the button has been released.
+	 * </p>
+	 */
+	private int openDowns;
+
+	/**
+	 * <p>
+	 * Internal flag that signals if {@link #currentSequence} needs to be
+	 * initialized.
+	 * </p>
+	 */
+	private boolean initMessages;
+
+	/**
+	 * <p>
+	 * The {@link EventGenerator} used to convert the subsequences into
+	 * {@link Event}s
+	 * </p>
+	 */
+	private EventGenerator tokenGenerator;
+
+	/**
+	 * <p>
+	 * The event sequence generated.
+	 * </p>
+	 */
+	private List<WindowsEvent> actionSequence;
+
+	/**
+	 * <p>
+	 * Type of the previous message.
+	 * </p>
+	 */
+	private int prevMsg = 0;
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new SequenceSplitter.
+	 * </p>
+	 */
+	public SequenceSplitter() {
+		currentSequence = new LinkedList<WindowsMessage>();
+		openDowns = 0;
+		initMessages = true;
+		tokenGenerator = new EventGenerator();
+		actionSequence = new LinkedList<WindowsEvent>();
+		prevMsg = 0;
+	}
+
+	/**
+	 * <p>
+	 * Called by the {@link MFCLogParser} every time a message is parsed.
+	 * </p>
+	 * 
+	 * @param msg
+	 *            message to be added
+	 */
+	public void addMessage(WindowsMessage msg) {
+		if (startOfSequence(msg)) {
+			if (!initMessages) {
+				WindowsEvent currentAction = tokenGenerator
+						.generateEvent(currentSequence);
+				if (currentAction != null) {
+					actionSequence.add(currentAction);
+				}
+				if (isKeyMessage(msg.getType()) && openDowns > 0) {
+					Console.traceln("Key message found with open down mouse messages - will probabably result in a faulty sequence.");
+				}
+			} else {
+				initMessages = false;
+			}
+			currentSequence = new LinkedList<WindowsMessage>();
+		}
+		if (isUpMessage(msg.getType())) {
+			if (openDowns > 0) {
+				openDowns--;
+			}
+		}
+
+		// this fix checks if there are two consecutive mouse-down messages.
+		// This sometimes occurs due to incorrect filtering in the monitoring
+		// dll.
+		if (!(prevMsg == MessageDefs.WM_LBUTTONDOWN && prevMsg == msg.getType())) {
+			currentSequence.add(msg);
+		} else {
+			openDowns--;
+		}
+		prevMsg = msg.getType();
+	}
+
+	/**
+	 * <p>
+	 * Returns the event sequence generated from the message that have been
+	 * added.
+	 * </p>
+	 * 
+	 * @return generated event sequence
+	 */
+	public List<WindowsEvent> getSequence() {
+		return actionSequence;
+	}
+
+	/**
+	 * <p>
+	 * Called when a session in the log file is finished, i.e., a closing
+	 * session-node is found.
+	 * </p>
+	 */
+	public void endSession() {
+		WindowsEvent currentAction = tokenGenerator
+				.generateEvent(currentSequence);
+		if (currentAction != null) {
+			actionSequence.add(currentAction);
+		}
+	}
+
+	/**
+	 * <p>
+	 * Checks if the message starts a new subsequence and returns the result.
+	 * </p>
+	 * 
+	 * @param msg
+	 *            message that is checked
+	 * @return true, if a new subsequence begins
+	 */
+	private boolean startOfSequence(WindowsMessage msg) {
+		boolean isStart = false;
+		int msgType = msg.getType();
+		if (isKeyMessage(msgType)) {
+			isStart = true;
+		}
+		if (isDownMessage(msgType)) {
+			openDowns++;
+			if (openDowns == 1) {
+				isStart = true;
+			}
+		}
+		if (isDblclkMessage(msgType)) {
+			openDowns++;
+		}
+		return isStart;
+	}
+
+	/**
+	 * <p>
+	 * Checks if the type of a message is generated is a keyboard interaction.
+	 * </p>
+	 * 
+	 * @param msgType
+	 *            type of the message
+	 * @return true if it is a keyboard interaction; false otherwise
+	 */
+	private boolean isKeyMessage(int msgType) {
+		boolean isKeyMsg = false;
+		switch (msgType) {
+		case MessageDefs.WM_KEYDOWN:
+		case MessageDefs.WM_KEYUP:
+		case MessageDefs.WM_SYSKEYDOWN:
+		case MessageDefs.WM_SYSKEYUP:
+			isKeyMsg = true;
+			break;
+		default:
+			break;
+		}
+		return isKeyMsg;
+	}
+
+	/**
+	 * <p>
+	 * Checks if the type of a message indicates that the mouse has been pressed
+	 * down.
+	 * </p>
+	 * 
+	 * @param msgType
+	 *            type of the message
+	 * @return true if it is mouse-down message; false otherwise
+	 */
+	private boolean isDownMessage(int msgType) {
+		boolean isDownMsg = false;
+		switch (msgType) {
+		case MessageDefs.WM_LBUTTONDOWN:
+		case MessageDefs.WM_RBUTTONDOWN:
+		case MessageDefs.WM_MBUTTONDOWN:
+		case MessageDefs.WM_XBUTTONDOWN:
+		case MessageDefs.WM_NCLBUTTONDOWN:
+		case MessageDefs.WM_NCRBUTTONDOWN:
+		case MessageDefs.WM_NCMBUTTONDOWN:
+		case MessageDefs.WM_NCXBUTTONDOWN:
+			isDownMsg = true;
+			break;
+		default:
+			break;
+		}
+		return isDownMsg;
+	}
+
+	/**
+	 * <p>
+	 * Checks if the type of a message indicates that a double click has been
+	 * performed.
+	 * </p>
+	 * 
+	 * @param msgType
+	 *            type of the message
+	 * @return true if it is a double click message; false otherwise
+	 */
+	private boolean isDblclkMessage(int msgType) {
+		boolean isDblclkMsg = false;
+		switch (msgType) {
+		case MessageDefs.WM_LBUTTONDBLCLK:
+		case MessageDefs.WM_RBUTTONDBLCLK:
+		case MessageDefs.WM_MBUTTONDBLCLK:
+		case MessageDefs.WM_XBUTTONDBLCLK:
+		case MessageDefs.WM_NCLBUTTONDBLCLK:
+		case MessageDefs.WM_NCRBUTTONDBLCLK:
+		case MessageDefs.WM_NCMBUTTONDBLCLK:
+		case MessageDefs.WM_NCXBUTTONDBLCLK:
+			isDblclkMsg = true;
+			break;
+		default:
+			break;
+		}
+		return isDblclkMsg;
+	}
+
+	/**
+	 * <p>
+	 * Checks if the type of a message indicates that the mouse has been
+	 * released.
+	 * </p>
+	 * 
+	 * @param msgType
+	 *            type of the message
+	 * @return true if it is mouse-up message; false otherwise
+	 */
+	private boolean isUpMessage(int msgType) {
+		boolean isUpMsg = false;
+		switch (msgType) {
+		case MessageDefs.WM_LBUTTONUP:
+		case MessageDefs.WM_RBUTTONUP:
+		case MessageDefs.WM_MBUTTONUP:
+		case MessageDefs.WM_XBUTTONUP:
+		case MessageDefs.WM_NCLBUTTONUP:
+		case MessageDefs.WM_NCRBUTTONUP:
+		case MessageDefs.WM_NCMBUTTONUP:
+		case MessageDefs.WM_NCXBUTTONUP:
+			isUpMsg = true;
+			break;
+		default:
+			break;
+		}
+		return isUpMsg;
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/commands/CMDconvertDirToXml.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/commands/CMDconvertDirToXml.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/commands/CMDconvertDirToXml.java	(revision 540)
@@ -0,0 +1,59 @@
+package de.ugoe.cs.quest.plugin.mfc.commands;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.security.InvalidParameterException;
+import java.util.List;
+
+import de.ugoe.cs.quest.plugin.mfc.LogPreprocessor;
+import de.ugoe.cs.util.console.Command;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Command to pre-process all files in a folder.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CMDconvertDirToXml implements Command {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#help()
+	 */
+	@Override
+	public void help() {
+		Console.println("Usage: convertToXml <sourceFolder> <targetFile> {<base64>}");
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#run(java.util.List)
+	 */
+	@Override
+	public void run(List<Object> parameters) {
+		if (parameters.size() < 2) {
+			throw new InvalidParameterException();
+		}
+		String path = (String) parameters.get(0);
+		String target = (String) parameters.get(1);
+		boolean base64 = false;
+		if (parameters.size() == 3) {
+			base64 = Boolean.parseBoolean((String) parameters.get(2));
+		}
+
+		try {
+			new LogPreprocessor(base64).convertDirToXml(path, target);
+		} catch (FileNotFoundException e) {
+			Console.printerrln(e.getMessage());
+		} catch (IOException e) {
+			Console.printerrln(e.getMessage());
+		}
+
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/commands/CMDconvertToXml.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/commands/CMDconvertToXml.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/commands/CMDconvertToXml.java	(revision 540)
@@ -0,0 +1,59 @@
+package de.ugoe.cs.quest.plugin.mfc.commands;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.security.InvalidParameterException;
+import java.util.List;
+
+import de.ugoe.cs.quest.plugin.mfc.LogPreprocessor;
+import de.ugoe.cs.util.console.Command;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Command to pre-process a single file.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CMDconvertToXml implements Command {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#help()
+	 */
+	@Override
+	public void help() {
+		Console.println("Usage: convertToXml <sourceFile> <targetFile> {<base64>}");
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#run(java.util.List)
+	 */
+	@Override
+	public void run(List<Object> parameters) {
+		if (parameters.size() < 2) {
+			throw new InvalidParameterException();
+		}
+		String source = (String) parameters.get(0);
+		String target = (String) parameters.get(1);
+		boolean base64 = false;
+		if (parameters.size() == 3) {
+			base64 = Boolean.parseBoolean((String) parameters.get(2));
+		}
+
+		try {
+			new LogPreprocessor(base64).convertToXml(source, target);
+		} catch (FileNotFoundException e) {
+			Console.printerrln(e.getMessage());
+		} catch (IOException e) {
+			Console.printerrln(e.getMessage());
+		}
+
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/commands/CMDparseXML.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/commands/CMDparseXML.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/commands/CMDparseXML.java	(revision 540)
@@ -0,0 +1,89 @@
+package de.ugoe.cs.quest.plugin.mfc.commands;
+
+import java.security.InvalidParameterException;
+import java.util.Collection;
+import java.util.List;
+import java.util.SortedSet;
+
+import de.ugoe.cs.quest.CommandHelpers;
+import de.ugoe.cs.quest.plugin.mfc.MFCLogParser;
+import de.ugoe.cs.quest.plugin.mfc.eventcore.MFCTargetComparator;
+import de.ugoe.cs.quest.plugin.mfc.eventcore.WindowTree;
+import de.ugoe.cs.quest.plugin.mfc.eventcore.WindowsEvent;
+import de.ugoe.cs.quest.ui.GlobalDataContainer;
+import de.ugoe.cs.util.console.Command;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Command to parse an XML file with sessions monitored by EventBench's
+ * MFCUsageMonitor.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CMDparseXML implements Command {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#help()
+	 */
+	@Override
+	public void help() {
+		Console.println("Usage: parseXML <filename> {<sequencesName>} {<countMessageOccurences>}");
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#run(java.util.List)
+	 */
+	@Override
+	public void run(List<Object> parameters) {
+		String filename;
+		String sequencesName = "sequences";
+		boolean countMessageOccurences = false;
+
+		try {
+			filename = (String) parameters.get(0);
+			if (parameters.size() >= 2) {
+				sequencesName = (String) parameters.get(1);
+			}
+			if (parameters.size() >= 3) {
+				countMessageOccurences = Boolean
+						.parseBoolean((String) parameters.get(2));
+			}
+		} catch (Exception e) {
+			throw new InvalidParameterException();
+		}
+
+		MFCLogParser parser = new MFCLogParser(countMessageOccurences);
+		parser.parseFile(filename);
+
+		Collection<List<WindowsEvent>> sequences = parser.getSequences();
+		
+		Console.traceln("Pre-computing event target equalities.");
+		// compare all Events to a dummy event to make sure they are known by
+		// the MFCTargetComparator
+		WindowsEvent dummyEvent = new WindowsEvent("dummy");
+		for (List<WindowsEvent> sequence : sequences) {
+			for (WindowsEvent event : sequence) {
+				event.equals(dummyEvent);
+			}
+		}
+		MFCTargetComparator.setMutable(false);
+		
+		SortedSet<String> targets = WindowTree.getInstance().getTargets();
+
+		if (GlobalDataContainer.getInstance().addData(sequencesName, sequences)) {
+			CommandHelpers.dataOverwritten(sequencesName);
+		}
+		if (GlobalDataContainer.getInstance().addData(
+				sequencesName + "_targets", targets)) {
+			CommandHelpers.dataOverwritten(sequencesName + "_targets");
+		}
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/eventcore/MFCTargetComparator.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/eventcore/MFCTargetComparator.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/eventcore/MFCTargetComparator.java	(revision 540)
@@ -0,0 +1,412 @@
+package de.ugoe.cs.quest.plugin.mfc.eventcore;
+
+import java.io.ByteArrayInputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.apache.commons.collections15.CollectionUtils;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+/**
+ * <p>
+ * This class implements a comparator for target strings of MFC GUIs. It
+ * internally maintains a collection of all targets that have been compared to
+ * ensure the transitivity of the equals relation. This memory can always be
+ * deleted by calling {@link #reset()}.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class MFCTargetComparator {
+
+	/**
+	 * <p>
+	 * If mutable is true, new target strings can be added to the internal
+	 * memory. This leads to a very expensive {@link #compare(String, String)}
+	 * operation.
+	 * </p>
+	 * <p>
+	 * if mutable is set to false, currently possible equal targets are
+	 * pre-computed. This pre-computation is expensive and might take a while.
+	 * In turn, the {@link #compare(String, String)} operation becomes very
+	 * cheap.
+	 * </p>
+	 */
+	private static boolean mutable = true;
+
+	/**
+	 * <p>
+	 * Set of all currently known targets.
+	 * </p>
+	 */
+	private static Set<String> knownTargets = new LinkedHashSet<String>();
+
+	/**
+	 * <p>
+	 * Map that contains for all known target strings all equal target strings.
+	 * Pre-computed when {@link #mutable} is set to false.
+	 * </p>
+	 */
+	private static Map<String, Set<String>> equalTargets;
+
+	/**
+	 * <p>
+	 * Changes the mutability of the comparator. If the mutability is changed
+	 * from true to false, the map {@link #equalTargets} is computed.
+	 * </p>
+	 * 
+	 * @param mutable
+	 *            new mutability of the comparator
+	 */
+	public static void setMutable(boolean mutable) {
+		if (MFCTargetComparator.mutable == true && mutable == false) {
+			equalTargets = new HashMap<String, Set<String>>();
+			for (String target1 : knownTargets) {
+				Set<String> curEqualTargets = new HashSet<String>();
+				for (String target2 : knownTargets) {
+					if (compare(target1, target2)) {
+						curEqualTargets.add(target2);
+					}
+				}
+				equalTargets.put(target1, curEqualTargets);
+			}
+		}
+		MFCTargetComparator.mutable = mutable;
+	}
+
+	/**
+	 * <p>
+	 * Compares to target strings. The strings are equal, if TODO
+	 * <ul>
+	 * <li>the class, resourceId, and modality of all widgets are equal</li>
+	 * <li>either the name or the hashCode of all widgets are equal</li>
+	 * <li>either the name or the hashCode has been observed in one equal
+	 * instance of a widget, for all widgets.</li>
+	 * </ul>
+	 * </p>
+	 * <p>
+	 * All target strings are remembered internally, to be able to test for the
+	 * third property.
+	 * </p>
+	 * 
+	 * @param target1
+	 *            first target string
+	 * @param target2
+	 *            second target string
+	 * @return true, if both targets are equal; false otherwise
+	 */
+	public static boolean compare(String target1, String target2) {
+		boolean result = false;
+		if (mutable) {
+			try {
+				MFCWidget widget1 = null;
+				MFCWidget widget2 = null;
+				if (!"dummy".equals(target1)) {
+					instance.addTarget(target1);
+					knownTargets.add(target1);
+					widget1 = instance.find(target1);
+				}
+				if (!"dummy".equals(target2)) {
+					instance.addTarget(target2);
+					knownTargets.add(target2);
+					widget2 = instance.find(target2);
+				}
+				if (widget1 == null) {
+					return false;
+				}
+				result = (widget1 == widget2);
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+		}
+
+		if (!mutable) {
+			Set<String> curEquals = equalTargets.get(target1);
+			if (curEquals != null) {
+				result = curEquals.contains(target2);
+			}
+		}
+
+		return result;
+	}
+
+	/**
+	 * <p>
+	 * Resets the internal memory of targets.
+	 * </p>
+	 */
+	public static void reset() {
+		instance = new MFCTargetComparator();
+	}
+
+	/**
+	 * <p>
+	 * Internal handle to the instance of this class (implemented as
+	 * Singleton!).
+	 * </p>
+	 */
+	private static MFCTargetComparator instance = new MFCTargetComparator();
+
+	/**
+	 * <p>
+	 * Private Constructor. Creates a new instance of the class and prevents
+	 * instantiation from outside of this class.
+	 * </p>
+	 */
+	private MFCTargetComparator() {
+	}
+
+	/**
+	 * <p>
+	 * List of the root widgets found in the target string.
+	 * </p>
+	 */
+	private List<MFCWidget> rootWidgets = new ArrayList<MFCTargetComparator.MFCWidget>();
+
+	/**
+	 * <p>
+	 * Adds a target to the memory.
+	 * </p>
+	 * 
+	 * @param target
+	 *            target to be added
+	 */
+	private void addTarget(String target) throws Exception {
+		if (target != null) {
+			DocumentBuilder documentBuilder = DocumentBuilderFactory
+					.newInstance().newDocumentBuilder();
+			Document doc = documentBuilder.parse(new ByteArrayInputStream(
+					("<dummy>" + target + "</dummy>").getBytes("UTF-8")));
+			doc.getDocumentElement().normalize();
+			NodeList widgets = doc.getElementsByTagName("window");
+
+			MFCWidget parent = null;
+			for (int i = 0; i < widgets.getLength(); i++) {
+				Element currentWidget = (Element) widgets.item(i);
+				parent = addWidget(currentWidget, parent);
+			}
+		}
+	}
+
+	/**
+	 * <p>
+	 * Adds a widget extracted from a target to the memory. The widget is placed
+	 * as a child/parent of other widget according to the GUI hierarchy of the
+	 * application.
+	 * </p>
+	 * <p>
+	 * In case the widget already exists, the existing widget is returned and
+	 * the known targets and hashCodes of the existing widget are updated.
+	 * </p>
+	 * 
+	 * @param widgetString
+	 *            string identifying the widget
+	 * @param parent
+	 *            parent widget; if null, it is a root widget and added to
+	 *            {@link #rootWidgets}
+	 * @return the created widget.
+	 */
+	private MFCWidget addWidget(Element widgetElement, MFCWidget parent) {
+		MFCWidget widget = generateWidget(widgetElement);
+
+		if (parent == null) {
+			int index = rootWidgets.indexOf(widget);
+			if (index >= 0) {
+				widget = rootWidgets.get(index);
+				widget.names.add(widgetElement.getAttribute("name"));
+				widget.hwnds.add(widgetElement.getAttribute("hwnd"));
+			} else {
+				rootWidgets.add(widget);
+			}
+		} else {
+			int index = parent.children.indexOf(widget);
+			if (index >= 0) {
+				widget = parent.children.get(index);
+				widget.names.add(widgetElement.getAttribute("name"));
+				widget.hwnds.add(widgetElement.getAttribute("hwnd"));
+			} else {
+				parent.children.add(widget);
+			}
+		}
+		return widget;
+	}
+
+	/**
+	 * <p>
+	 * Creates a new {@link MFCWidget} from a widget XML element.
+	 * </p>
+	 * 
+	 * @param widgetElement
+	 *            XML element containing information about the widget
+	 * @return created {@link MFCWidget}
+	 */
+	private MFCWidget generateWidget(Element widgetElement) {
+		MFCWidget widget = new MFCWidget();
+		widget.names.add(widgetElement.getAttribute("name"));
+		widget.hwnds.add(widgetElement.getAttribute("hwnd"));
+		widget.widgetClass = widgetElement.getAttribute("class");
+		widget.resourceId = widgetElement.getAttribute("resourceId");
+		widget.modality = widgetElement.getAttribute("isModal");
+		return widget;
+	}
+
+	/**
+	 * <p>
+	 * Tries to find the {@link MFCWidget} that the target string identifies in
+	 * the known GUI hierarchy, by traversing the known widgets starting with
+	 * the {@link #rootWidgets}.
+	 * 
+	 * @param target
+	 *            target string whose widget is searched for
+	 * @return respective {@link MFCWidget} instance if it is found; null
+	 *         otherwise
+	 */
+	private MFCWidget find(String target) throws Exception {
+		MFCWidget widget = null;
+		if (target != null) {
+			DocumentBuilder documentBuilder = DocumentBuilderFactory
+					.newInstance().newDocumentBuilder();
+			Document doc = documentBuilder.parse(new ByteArrayInputStream(
+					("<dummy>" + target + "</dummy>").getBytes("UTF-8")));
+			doc.getDocumentElement().normalize();
+			NodeList widgets = doc.getElementsByTagName("window");
+
+			MFCWidget parent = null;
+			for (int i = 0; i < widgets.getLength(); i++) {
+				Element currentWidget = (Element) widgets.item(i);
+				MFCWidget generatedWidget = generateWidget(currentWidget);
+				if (parent == null) {
+					int index = rootWidgets.indexOf(generatedWidget);
+					if (index >= 0) {
+						parent = rootWidgets.get(index);
+					} else {
+						return null;
+					}
+				} else {
+					int index = parent.children.indexOf(generatedWidget);
+					if (index >= 0) {
+						parent = parent.children.get(index);
+					} else {
+						return null;
+					}
+				}
+			}
+			widget = parent;
+		}
+		return widget;
+	}
+
+	/**
+	 * <p>
+	 * Internal class used to store MFCWidget. The implementation is more like a
+	 * C-style structure, than an actual class.
+	 * </p>
+	 * 
+	 * @author Steffen Herbold
+	 * @version 1.0
+	 */
+	private static class MFCWidget {
+
+		/**
+		 * <p>
+		 * Set of all known name strings of the widget.
+		 * </p>
+		 */
+		Set<String> names = new LinkedHashSet<String>();
+
+		/**
+		 * <p>
+		 * Set of all known hwnds of the widget.
+		 * </p>
+		 */
+		Set<String> hwnds = new LinkedHashSet<String>();
+
+		/**
+		 * <p>
+		 * Class of the widget.
+		 * </p>
+		 */
+		String widgetClass;
+
+		/**
+		 * <p>
+		 * Resource id of the widget.
+		 * </p>
+		 */
+		String resourceId;
+
+		/**
+		 * <p>
+		 * Modality of the widget.
+		 * </p>
+		 */
+		String modality;
+
+		/**
+		 * <p>
+		 * Pre-computed hash code of the widget.
+		 * </p>
+		 */
+		int hashCode = 0;
+
+		/**
+		 * <p>
+		 * List of children of the widget.
+		 * </p>
+		 */
+		List<MFCWidget> children = new ArrayList<MFCTargetComparator.MFCWidget>();
+
+		/**
+		 * <p>
+		 * Two widgets are equal, if {@link #widgetClass}, {@link #resourceId},
+		 * and {@link #modality} are equal and the intersection of either the
+		 * {@link #hwnds}, the {@link #names}, or both of them is not empty.
+		 * </p>
+		 * 
+		 * @see java.lang.Object#equals(java.lang.Object)
+		 */
+		@Override
+		public boolean equals(Object obj) {
+			if (obj instanceof MFCWidget) {
+				MFCWidget other = (MFCWidget) obj;
+				boolean titleEqual = CollectionUtils.containsAny(names,
+						other.names);
+				boolean hashEqual = CollectionUtils.containsAny(hwnds,
+						other.hwnds);
+
+				return widgetClass.equals(other.widgetClass)
+						&& resourceId.equals(other.resourceId)
+						&& modality.equals(other.modality)
+						&& (titleEqual || hashEqual);
+			}
+			return false;
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see java.lang.Object#hashCode()
+		 */
+		@Override
+		public int hashCode() {
+			if (hashCode == 0) {
+				int multiplier = 17;
+				hashCode = multiplier * hashCode + widgetClass.hashCode();
+				hashCode = multiplier * hashCode + resourceId.hashCode();
+				hashCode = multiplier * hashCode + modality.hashCode();
+			}
+			return hashCode;
+		}
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/eventcore/WindowTree.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/eventcore/WindowTree.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/eventcore/WindowTree.java	(revision 540)
@@ -0,0 +1,188 @@
+package de.ugoe.cs.quest.plugin.mfc.eventcore;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+/**
+ * <p>
+ * This class provides an the interfaces for window trees.
+ * </p>
+ * <p>
+ * The window tree represents the hierarchical structure of the windows
+ * "as it is" currently during a session. It may change during the session due
+ * to creation and destruction of windows.
+ * </p>
+ * <p>
+ * The class is implemented as a singleton. The rational behind implementing
+ * this class as a singleton is to ease the access of all class that may request
+ * information about the windows during the parsing of a session. As the tree
+ * may change during the session, it does not make sense to preserve it after a
+ * session. Thus, it can just be deleted. Therefore, as long as only one session
+ * is parsed at a time, a single instance is sufficient.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class WindowTree {
+
+	/**
+	 * <p>
+	 * Handle to the window instance.
+	 * </p>
+	 */
+	private static WindowTree theInstance = null;
+
+	/**
+	 * <p>
+	 * Maintains a set of all the target strings of all widgets that were at
+	 * some point part of the window tree.
+	 * </p>
+	 */
+	private SortedSet<String> targets;
+
+	/**
+	 * <p>
+	 * Obtain a handle to the window instance.
+	 * </p>
+	 * 
+	 * @return instance of the window tree
+	 */
+	public static WindowTree getInstance() {
+		if (theInstance == null) {
+			theInstance = new WindowTree();
+		}
+		return theInstance;
+	}
+
+	/**
+	 * <p>
+	 * Resets the tree. Should be used between sessions.
+	 * </p>
+	 */
+	public static void resetTree() {
+		theInstance = null;
+	}
+
+	/**
+	 * <p>
+	 * Map of all windows that are part of the tree for efficient searching. The
+	 * keys of the map are the hwnd's of the windows.
+	 * </p>
+	 */
+	private Map<Integer, WindowTreeNode> nodes;
+
+	/**
+	 * <p>
+	 * Creates a new WindowTree.
+	 * </p>
+	 * <p>
+	 * Private, as the class is a singleton.
+	 * </p>
+	 */
+	private WindowTree() {
+		nodes = new HashMap<Integer, WindowTreeNode>();
+		targets = new TreeSet<String>();
+	}
+
+	/**
+	 * <p>
+	 * Adds a new window to the tree.
+	 * </p>
+	 * 
+	 * @param parentHwnd
+	 *            hwnd of the parent window
+	 * @param childHwnd
+	 *            hwnd of the window to be created
+	 * @param childWindowName
+	 *            resource id of the window to be created
+	 * @param resourceId
+	 *            resource id of the window to be created
+	 * @param className
+	 *            class name of the window to be created
+	 */
+	public void add(int parentHwnd, int childHwnd, String childWindowName,
+			int resourceId, String className, boolean isModal) {
+		WindowTreeNode parent = nodes.get(parentHwnd);
+		WindowTreeNode child = nodes.get(childHwnd);
+		if (child == null) {
+			if (parent != null) {
+				child = parent.addChild(childHwnd, childWindowName, resourceId,
+						className, isModal);
+			} else {
+				child = new WindowTreeNode(childHwnd, null, childWindowName,
+						resourceId, className, isModal);
+			}
+			nodes.put(childHwnd, child);
+			targets.add(child.xmlRepresentation());
+		}
+	}
+
+	/**
+	 * <p>
+	 * Removes a window (defined by its hwnd) from the tree. All children of the
+	 * window will be removed recursively.
+	 * </p>
+	 * 
+	 * @param hwnd
+	 *            hwnd of the window to be removed
+	 * @return number of windows that were removed
+	 */
+	public int remove(int hwnd) {
+		int removedCounter = 0;
+		WindowTreeNode node = nodes.get(hwnd);
+		if (node != null) {
+			List<WindowTreeNode> nodesToBeRemoved = node.remove();
+			for (int i = 0; i < nodesToBeRemoved.size(); i++) {
+				WindowTreeNode nodeToBeRemoved = nodesToBeRemoved.get(i);
+				nodesToBeRemoved.addAll(nodeToBeRemoved.getChildren());
+				nodes.remove(nodeToBeRemoved.getHwnd());
+				removedCounter++;
+			}
+			nodes.remove(hwnd);
+			removedCounter++;
+		}
+		return removedCounter;
+	}
+
+	/**
+	 * <p>
+	 * Searches the tree for a window with the specified hwnd and returns its
+	 * {@link WindowTreeNode}.
+	 * </p>
+	 * 
+	 * @param hwnd
+	 *            hwnd that is looked for
+	 * @return {@link WindowTreeNode} of the window with the given hwnd if
+	 *         found, null otherwise
+	 */
+	public WindowTreeNode find(int hwnd) {
+		return nodes.get(hwnd);
+	}
+
+	/**
+	 * <p>
+	 * Returns the number of nodes contained in the WindowTree.
+	 * </p>
+	 * 
+	 * @return number of nodes
+	 */
+	public int size() {
+		return nodes.size();
+	}
+
+	/**
+	 * <p>
+	 * Returns a sorted set of all targets that existed any time in the window
+	 * tree.
+	 * </p>
+	 * 
+	 * @return set of targets
+	 */
+	public SortedSet<String> getTargets() {
+		return targets;
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/eventcore/WindowTreeNode.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/eventcore/WindowTreeNode.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/eventcore/WindowTreeNode.java	(revision 540)
@@ -0,0 +1,292 @@
+package de.ugoe.cs.quest.plugin.mfc.eventcore;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import de.ugoe.cs.util.StringTools;
+
+/**
+ * <p>
+ * This class implements a node in the {@link WindowTree} that is maintained
+ * during parsing a session.
+ * </p>
+ * <p>
+ * The window tree is structure that contains the hierarchy of the windows of a
+ * application as well as basic information about each window: the hwnd; its
+ * name; its resource id; its class name.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class WindowTreeNode {
+
+	/**
+	 * <p>
+	 * Name of the window. May change over time.
+	 * </p>
+	 */
+	private String windowName;
+
+	/**
+	 * <p>
+	 * Handle of the window. Used as unique identifier during its existence.
+	 * </p>
+	 */
+	private final int hwnd;
+
+	/**
+	 * <p>
+	 * Resource id of the window.
+	 * </p>
+	 */
+	private final int resourceId;
+
+	/**
+	 * <p>
+	 * Class name of the window.
+	 * </p>
+	 */
+	private final String className;
+
+	/**
+	 * <p>
+	 * True, if the window is modal.
+	 * </p>
+	 */
+	private final boolean isModal;
+
+	/**
+	 * <p>
+	 * Parent of the window. <code>null</code> if the window has no parent.
+	 * </p>
+	 */
+	private WindowTreeNode parent;
+
+	/**
+	 * <p>
+	 * List of the windows children. May be empty.
+	 * </p>
+	 */
+	private List<WindowTreeNode> children;
+
+	/**
+	 * <p>
+	 * Creates a new WindowTreeNode.
+	 * </p>
+	 * <p>
+	 * The constructor is protected WindowTreeNode may only be created from the
+	 * WindowTree.
+	 * </p>
+	 * 
+	 * @param hwnd
+	 *            hwnd of the window
+	 * @param parent
+	 *            reference to the parent's WindowTreeNode
+	 * @param windowName
+	 *            name of the window
+	 * @param resourceId
+	 *            resource id of the window
+	 * @param className
+	 *            class name of the window
+	 * @param isModal
+	 *            modality of the window
+	 */
+	protected WindowTreeNode(int hwnd, WindowTreeNode parent,
+			String windowName, int resourceId, String className, boolean isModal) {
+		this.hwnd = hwnd;
+		this.parent = parent;
+		this.windowName = windowName;
+		this.resourceId = resourceId;
+		this.className = className;
+		this.isModal = isModal;
+		children = new ArrayList<WindowTreeNode>();
+	}
+
+	/**
+	 * <p>
+	 * Returns a reference to the WindowTreeNode of the parent.
+	 * </p>
+	 * 
+	 * @return WindowTreeNode of the parent
+	 */
+	public WindowTreeNode getParent() {
+		return parent;
+	}
+
+	/**
+	 * <p>
+	 * Returns the list of the windows children.
+	 * </p>
+	 * 
+	 * @return list of the windows children
+	 */
+	public List<WindowTreeNode> getChildren() {
+		return children;
+	}
+
+	/**
+	 * <p>
+	 * Returns the name of the window.
+	 * </p>
+	 * 
+	 * @return name of the window
+	 */
+	public String getName() {
+		return windowName;
+	}
+
+	/**
+	 * <p>
+	 * Returns the hwnd of the window.
+	 * </p>
+	 * 
+	 * @return hwnd of the window
+	 */
+	public int getHwnd() {
+		return hwnd;
+	}
+
+	/**
+	 * <p>
+	 * Returns the resource id of the window.
+	 * </p>
+	 * 
+	 * @return resource id of the window
+	 */
+	public int getResourceId() {
+		return resourceId;
+	}
+
+	/**
+	 * <p>
+	 * Returns the class name of the window.
+	 * </p>
+	 * 
+	 * @return class name of the window
+	 */
+	public String getClassName() {
+		return className;
+	}
+
+	/**
+	 * <p>
+	 * Sets the name of the window.
+	 * </p>
+	 * 
+	 * @param text
+	 *            new name of the window
+	 */
+	public void setName(String text) {
+		windowName = text;
+	}
+
+	/**
+	 * <p>
+	 * Removes a the window and all its children from the {@link WindowTree}.
+	 * </p>
+	 * 
+	 * @return list of the children of the window for further clean up.
+	 */
+	public List<WindowTreeNode> remove() {
+		if (parent != null) {
+			parent.removeChild(this);
+		}
+		return children;
+	}
+
+	/**
+	 * <p>
+	 * Removes a child window.
+	 * </p>
+	 * 
+	 * @param child
+	 *            reference to the child window to be removed
+	 */
+	public void removeChild(WindowTreeNode child) {
+		children.remove(child);
+	}
+
+	/**
+	 * <p>
+	 * Adds a new child window and creates WindowTreeNode for it.
+	 * </p>
+	 * 
+	 * @param childHwnd
+	 *            hwnd of the child window
+	 * @param childWindowName
+	 *            name of the child window
+	 * @param resourceId
+	 *            resource id of the child window
+	 * @param className
+	 *            class name of the child window
+	 * @param isModal
+	 *            modality of the child window
+	 * @return reference to the WindowTreeNode created for the child window
+	 */
+	public WindowTreeNode addChild(int childHwnd, String childWindowName,
+			int resourceId, String className, boolean isModal) {
+		WindowTreeNode child = new WindowTreeNode(childHwnd, this,
+				childWindowName, resourceId, className, isModal);
+		children.add(child);
+		return child;
+	}
+
+	/**
+	 * <p>
+	 * Returns a string identfier of the window:<br>
+	 * {@code [resourceId;"windowName";"className";modality]}
+	 * </p>
+	 * 
+	 * @return identifier string of the window
+	 */
+	@Override
+	public String toString() {
+		return "[" + resourceId + ";\"" + windowName + "\";\"" + className
+				+ "\";" + isModal + "]";
+	}
+
+	/**
+	 * <p>
+	 * Returns an XML representation of the window, including its parents. It is
+	 * defined as follows:<br>
+	 * <code>
+	 * parent#xmlRepresentation()<br>
+	 * &lt;window name="this.windowname" class="this.className" resourceId="this.resourceId" isModal="this.isModel"/&gt;
+	 * </code>
+	 * </p>
+	 * 
+	 * @return xml representation of the window
+	 */
+	public String xmlRepresentation() {
+		String xmlString = "";
+		if (parent != null) {
+			xmlString = parent.xmlRepresentation();
+		}
+		xmlString += "<window name=\""
+				+ StringTools.xmlEntityReplacement(windowName) + "\" class=\""
+				+ StringTools.xmlEntityReplacement(className)
+				+ "\" resourceId=\"" + resourceId + "\" isModal=\"" + isModal
+				+ "\" hwnd=\"" + hwnd + "\""
+				+ "/>";
+		return xmlString;
+	}
+
+	/**
+	 * <p>
+	 * Returns the names of the parents and itself separated by dots, e.g.,
+	 * "GrandParent.Parent.windowName"
+	 * </p>
+	 * 
+	 * @return names of the parents separated by dots
+	 */
+	public String getParentNames() {
+		String parentNames = "";
+		if (parent != null) {
+			parentNames = parent.getParentNames() + ".";
+		}
+		parentNames += windowName;
+		return parentNames;
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/eventcore/WindowsEvent.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/eventcore/WindowsEvent.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/eventcore/WindowsEvent.java	(revision 540)
@@ -0,0 +1,86 @@
+package de.ugoe.cs.quest.plugin.mfc.eventcore;
+
+import java.io.ByteArrayInputStream;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+import de.ugoe.cs.quest.eventcore.ReplayableEvent;
+
+/**
+ * <p>
+ * Convenience class for working with Windows MFC events.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class WindowsEvent extends ReplayableEvent<WindowsMessage> {
+
+	/**
+	 * <p>
+	 * Id for object serialization.
+	 * </p>
+	 */
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new WindowEvent.
+	 * </p>
+	 * 
+	 * @see de.ugoe.cs.quest.eventcore.Event#Event(String)
+	 * @param type
+	 *            type of the event.
+	 */
+	public WindowsEvent(String type) {
+		super(type);
+	}
+
+	@Override
+	protected boolean targetEquals(String otherTarget) {
+		return MFCTargetComparator.compare(target, otherTarget);
+	}
+	
+	int targetHash = 0;
+	
+	@Override
+	protected int targetHashCode() {
+		if( targetHash==0 ) {
+			int multiplier = 17;
+			if (target != null) {
+				Document doc;
+				try {
+					DocumentBuilder documentBuilder = DocumentBuilderFactory
+							.newInstance().newDocumentBuilder();
+					doc = documentBuilder.parse(new ByteArrayInputStream(
+							("<dummy>" + target + "</dummy>").getBytes("UTF-8")));
+				} catch (Exception e) {
+					e.printStackTrace();
+					return 0;
+				}
+				doc.getDocumentElement().normalize();
+				NodeList widgets = doc.getElementsByTagName("window");
+
+				for (int i = 0; i < widgets.getLength(); i++) {
+					Element currentWidget = (Element) widgets.item(i);
+					targetHash = targetHash* multiplier + widgetHashCode(currentWidget);
+				}
+			}
+		}
+		return targetHash;
+	}
+	
+	private int widgetHashCode(Element currentWidget) {
+		int hashCode = 0;
+		int multiplier = 41;
+		hashCode = hashCode * multiplier + currentWidget.getAttribute("class").hashCode();
+		hashCode = hashCode * multiplier + currentWidget.getAttribute("resourceId").hashCode();
+		hashCode = hashCode * multiplier + currentWidget.getAttribute("isModal").hashCode();
+		return hashCode;
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/eventcore/WindowsMessage.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/eventcore/WindowsMessage.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/mfc/eventcore/WindowsMessage.java	(revision 540)
@@ -0,0 +1,520 @@
+package de.ugoe.cs.quest.plugin.mfc.eventcore;
+
+import java.security.InvalidParameterException;
+import java.util.HashMap;
+import java.util.Map;
+
+import de.ugoe.cs.quest.eventcore.IReplayable;
+import de.ugoe.cs.util.StringTools;
+
+/**
+ * <p>
+ * Contains all informations about a windows message, i.e., all parameters that
+ * are read when a windows message is parsed as well as its target, hwnd, etc.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ * 
+ */
+public class WindowsMessage implements IReplayable {
+
+	/**
+	 * <p>
+	 * Id for object serialization.
+	 * </p>
+	 */
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * <p>
+	 * Type of the message.
+	 * </p>
+	 */
+	final int type;
+
+	/**
+	 * <p>
+	 * Window class of the message target. Default: ""
+	 * </p>
+	 */
+	private String windowClass = "";
+
+	/**
+	 * <p>
+	 * Resource Id of the message target. Default: 0
+	 * </p>
+	 */
+	private int resourceId = 0;
+
+	/**
+	 * <p>
+	 * XML representation of the message target.
+	 * </p>
+	 */
+	private String xmlWindowDescription = "";
+
+	/**
+	 * <p>
+	 * String that contains the names of all parent widgets and itself, separated by dots,
+	 * e.g., "GrandParent.Parent.self".
+	 * </p>
+	 */
+	private String parentNames = null;
+
+	/**
+	 * <p>
+	 * String that contains the window class of the parent widget.
+	 * </p>
+	 */
+	private String parentClass = null;
+
+	/**
+	 * <p>
+	 * LPARAM of the message. Default: 0
+	 * </p>
+	 */
+	private long LPARAM = 0;
+
+	/**
+	 * <p>
+	 * WPARAM of the message. Default: 0
+	 * </p>
+	 */
+	private long WPARAM = 0;
+
+	/**
+	 * <p>
+	 * If the LPARAM contains a HWND, this string stores the target of the HWND.
+	 * </p>
+	 */
+	private String LPARAMasWindowDesc = null;
+
+	/**
+	 * <p>
+	 * If the WPARAM contains a HWND, this string stores the target of the HWND.
+	 * </p>
+	 */
+	private String WPARAMasWindowDesc = null;
+
+	/**
+	 * <p>
+	 * Delay after sending the messages during a replay. Default: 0
+	 * </p>
+	 */
+	private int delay = 0;
+
+	/**
+	 * <p>
+	 * A map of all parameters, associated with the message, created during the
+	 * parsing of messages from the logs {@code param}-nodes.
+	 * </p>
+	 */
+	private Map<String, String> params = new HashMap<String, String>();
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new message with a given message type.
+	 * </p>
+	 * 
+	 * @param type
+	 *            type of the message
+	 */
+	public WindowsMessage(int type) {
+		this.type = type;
+	}
+
+	/**
+	 * <p>
+	 * Adds a parameter to the message.
+	 * </p>
+	 * 
+	 * @param type
+	 *            type descriptor of the parameter
+	 * @param value
+	 *            value of the parameter
+	 */
+	public void addParameter(String type, String value) {
+		params.put(type, value);
+		if (type.equals("LPARAM")) {
+			LPARAM = Long.parseLong(value);
+		} else if (type.equals("WPARAM")) {
+			WPARAM = Long.parseLong(value);
+		}
+	}
+
+	/**
+	 * <p>
+	 * Returns the type of the message.
+	 * </p>
+	 * 
+	 * @return type of the message
+	 */
+	public int getType() {
+		return type;
+	}
+
+	/**
+	 * <p>
+	 * Returns the value of a parameter, given its type. If the parameter is not
+	 * found, {@code null} is returned.
+	 * </p>
+	 * 
+	 * @param type
+	 *            type of the parameter
+	 * @return value of the parameter
+	 */
+	public String getParameter(String type) {
+		return params.get(type);
+	}
+
+	/**
+	 * <p>
+	 * Returns the window class of the message target.
+	 * </p>
+	 * 
+	 * @return window class of the message target
+	 */
+	public String getWindowClass() {
+		return windowClass;
+	}
+
+	/**
+	 * <p>
+	 * Returns the HWND the message is addressed to.
+	 * </p>
+	 * 
+	 * @return HWND the message is addressed to
+	 */
+	public int getHwnd() {
+		int hwnd = -1;
+		String hwndString = getParameter("window.hwnd"); // possible, as
+															// "window.hwnd" is
+															// mandatory
+		if (hwndString != null) {
+			hwnd = Integer.parseInt(hwndString);
+		}
+		return hwnd;
+	}
+
+	/**
+	 * <p>
+	 * Returns the resource Id of the message target.
+	 * </p>
+	 * 
+	 * @return resource Id of the message target
+	 */
+	public int getWindowResourceId() {
+		return resourceId;
+	}
+
+	/**
+	 * <p>
+	 * Two {@link WindowsMessage} are equal, if their {@link #type},
+	 * {@link #xmlWindowDescription}, and {@link #params} are equal.
+	 * </p>
+	 * 
+	 * @see java.lang.Object#equals(java.lang.Object)
+	 */
+	@Override
+	public boolean equals(Object other) {
+		if (other == this) {
+			return true;
+		}
+		boolean isEqual = false;
+		if (other instanceof WindowsMessage) {
+			isEqual = ((WindowsMessage) other).type == this.type
+					&& ((WindowsMessage) other).xmlWindowDescription
+							.equals(this.xmlWindowDescription)
+					&& ((WindowsMessage) other).params.equals(this.params);
+		}
+		return isEqual;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see java.lang.Object#hashCode()
+	 */
+	@Override
+	public int hashCode() {
+		int multiplier = 17;
+		int hash = 42;
+
+		hash = multiplier * hash + type;
+		hash = multiplier * hash + xmlWindowDescription.hashCode();
+		hash = multiplier * hash + params.hashCode();
+
+		return hash;
+	}
+
+	/**
+	 * <p>
+	 * Returns a string representation of the message of the form
+	 * "msg[target=HWND;type=TYPE]".
+	 * </p>
+	 * 
+	 * @see java.lang.Object#toString()
+	 */
+	@Override
+	public String toString() {
+		return "msg[target=" + getParameter("window.hwnd") + ";type=" + type
+				+ "]";
+	}
+
+	/**
+	 * <p>
+	 * Retrieves the target string of a message from a given {@link WindowTree}
+	 * through looking up the HWND the message is addressed to in the window
+	 * tree.
+	 * </p>
+	 * 
+	 * @param windowTree
+	 *            {@link WindowTree} from which the target is extracted
+	 * @throws InvalidParameterException
+	 *             thrown if HWND is not contained in windowTree
+	 */
+	public void setTarget(WindowTree windowTree)
+			throws InvalidParameterException {
+		int hwnd = Integer.parseInt(getParameter("window.hwnd"));
+		WindowTreeNode node = windowTree.find(hwnd);
+		if (node == null) {
+			throw new InvalidParameterException("No window with HWND " + hwnd
+					+ " found in window tree!");
+		} else {
+			windowClass = node.getClassName();
+			resourceId = node.getResourceId();
+			xmlWindowDescription = node.xmlRepresentation();
+			parentNames = node.getParentNames();
+			WindowTreeNode parent = node.getParent();
+			if (parent == null) {
+				parentClass = "";
+			} else {
+				parentClass = parent.getClassName();
+			}
+		}
+	}
+
+	/**
+	 * <p>
+	 * Sets the LPARAM of a message.
+	 * </p>
+	 * 
+	 * @param paramValue
+	 *            value of the LPARAM
+	 */
+	public void setLPARAM(long paramValue) {
+		LPARAM = paramValue;
+	}
+
+	/**
+	 * <p>
+	 * Sets the WPARAM of a message.
+	 * </p>
+	 * 
+	 * @param paramValue
+	 *            value of the WPARAM
+	 */
+	public void setWPARAM(long paramValue) {
+		WPARAM = paramValue;
+	}
+
+	/**
+	 * <p>
+	 * Returns the LPARAM of a message.
+	 * </p>
+	 * 
+	 * @return LPARAM of the message
+	 */
+	public long getLPARAM() {
+		return LPARAM;
+	}
+
+	/**
+	 * <p>
+	 * Returns the WPARAM of a message.
+	 * </p>
+	 * 
+	 * @return WPARAM of the message
+	 */
+	public long getWPARAM() {
+		return WPARAM;
+	}
+
+	/**
+	 * <p>
+	 * If the LPARAM contains a HWND, this function can be used to set a target
+	 * string to identify the HWND at run-time.
+	 * </p>
+	 * 
+	 * @param windowDesc
+	 *            target string
+	 */
+	public void setLPARAMasWindowDesc(String windowDesc) {
+		LPARAMasWindowDesc = windowDesc;
+	}
+
+	/**
+	 * <p>
+	 * If the WPARAM contains a HWND, this function can be used to set a target
+	 * string to identify the HWND at run-time.
+	 * </p>
+	 * 
+	 * @param windowDesc
+	 *            target string
+	 */
+	public void setWPARAMasWindowDesc(String windowDesc) {
+		WPARAMasWindowDesc = windowDesc;
+	}
+
+	/**
+	 * <p>
+	 * If the LPARAM contains a HWND and the target string for the HWND is set,
+	 * this function returns the target string. Otherwise, {@code null} is
+	 * returned.
+	 * </p>
+	 * 
+	 * @return target string if available; {@code null} otherwise
+	 */
+	public String getLPARAMasWindowDesc() {
+		return LPARAMasWindowDesc;
+	}
+
+	/**
+	 * <p>
+	 * If the WPARAM contains a HWND and the target string for the HWND is set,
+	 * this function returns the target string. Otherwise, {@code null} is
+	 * returned.
+	 * </p>
+	 * 
+	 * @return target string if available; {@code null} otherwise
+	 */
+	public String getWPARAMasWindowDesc() {
+		return WPARAMasWindowDesc;
+	}
+
+	/**
+	 * <p>
+	 * Returns the target string of the message.
+	 * </p>
+	 * 
+	 * @return target string of the message
+	 */
+	public String getXmlWindowDescription() {
+		return xmlWindowDescription;
+	}
+
+	/**
+	 * <p>
+	 * Sets the target string manually.
+	 * </p>
+	 * 
+	 * @param xmlWindowDescription
+	 *            target string
+	 */
+	public void setXmlWindowDescription(String xmlWindowDescription) {
+		this.xmlWindowDescription = xmlWindowDescription;
+	}
+
+	/**
+	 * <p>
+	 * Returns the delay after this message during replays.
+	 * </p>
+	 * 
+	 * @return delay after this message
+	 */
+	public int getDelay() {
+		return delay;
+	}
+
+	/**
+	 * <p>
+	 * Sets the delay after this message during replays.
+	 * </p>
+	 * 
+	 * @param delay
+	 *            delay after this message
+	 */
+	public void setDelay(int delay) {
+		this.delay = delay;
+	}
+
+	/**
+	 * <p>
+	 * Returns the parent names separated by dots, e.g., "GrandParent.Parent".
+	 * </p>
+	 * 
+	 * @return names of the parents
+	 */
+	public String getParentNames() {
+		return parentNames;
+	}
+
+	/**
+	 * <p>
+	 * Returns the window class of the parent.
+	 * </p>
+	 * 
+	 * @return window classes of the parents
+	 */
+	public String getParentClass() {
+		return parentClass;
+	}
+
+	/**
+	 * <p>
+	 * Returns the number of parameters stored together with this message.
+	 * </p>
+	 * 
+	 * @return number of parameters stored with this message
+	 */
+	public int getNumParams() {
+		return params.size();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.eventcore.IReplayable#getReplay()
+	 */
+	@Override
+	public String getReplay() {
+		StringBuilder currentMsgStr = new StringBuilder(400);
+		currentMsgStr.append("  <msg type=\"" + type + "\" ");
+		currentMsgStr.append("LPARAM=\"" + LPARAM + "\" ");
+		currentMsgStr.append("WPARAM=\"" + WPARAM + "\" ");
+		currentMsgStr.append("delay=\"" + delay + "\">");
+		if (LPARAMasWindowDesc != null) {
+			currentMsgStr.append(StringTools.ENDLINE);
+			currentMsgStr.append("   <LPARAM>");
+			currentMsgStr.append(StringTools.ENDLINE);
+			currentMsgStr.append(LPARAMasWindowDesc);
+			currentMsgStr.append(StringTools.ENDLINE);
+			currentMsgStr.append("</LPARAM>");
+		}
+		if (WPARAMasWindowDesc != null) {
+			currentMsgStr.append(StringTools.ENDLINE);
+			currentMsgStr.append("   <WPARAM>");
+			currentMsgStr.append(StringTools.ENDLINE);
+			currentMsgStr.append(WPARAMasWindowDesc);
+			currentMsgStr.append(StringTools.ENDLINE);
+			currentMsgStr.append("   </WPARAM>");
+		}
+		currentMsgStr.append(StringTools.ENDLINE);
+		currentMsgStr.append(xmlWindowDescription);
+		currentMsgStr.append(StringTools.ENDLINE);
+		currentMsgStr.append("  </msg>");
+		currentMsgStr.append(StringTools.ENDLINE);
+		return currentMsgStr.toString();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.eventcore.IReplayable#getTarget()
+	 */
+	@Override
+	public String getTarget() {
+		return xmlWindowDescription;
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/php/WeblogParser.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/php/WeblogParser.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/php/WeblogParser.java	(revision 540)
@@ -0,0 +1,497 @@
+package de.ugoe.cs.quest.plugin.php;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import de.ugoe.cs.quest.plugin.php.eventcore.WebEvent;
+import de.ugoe.cs.util.FileTools;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Provides functionality to parse log files with web request.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class WeblogParser {
+
+	/**
+	 * <p>
+	 * Timeout between two sessions in milliseconds.
+	 * </p>
+	 */
+	private long timeout;
+
+	/**
+	 * <p>
+	 * Minimal length of a session. All shorter sessions will be pruned.<br>
+	 * Default: 2
+	 * </p>
+	 */
+	private int minLength = 2;
+
+	/**
+	 * <p>
+	 * Maximal length of a session. All longer sessions will be pruned.<br>
+	 * Default: 100
+	 * </p>
+	 */
+	private int maxLength = 100;
+
+	/**
+	 * <p>
+	 * URL of the server that generated the log that is currently parser; null
+	 * of URL is not available.<br>
+	 * Default: null
+	 * </p>
+	 */
+	private String url = null;
+
+	/**
+	 * <p>
+	 * Collection of generated sequences.
+	 * </p>
+	 */
+	private List<List<WebEvent>> sequences;
+
+	/**
+	 * <p>
+	 * List that stores the users (identified through their cookie id) to each
+	 * sequence.
+	 * </p>
+	 */
+	private List<String> users;
+
+	/**
+	 * <p>
+	 * List that stores the frequent users (identified through their cookie id)
+	 * to each sequence.
+	 * </p>
+	 */
+	private List<String> frequentUsers;
+
+	/**
+	 * <p>
+	 * Sequences for all frequent users.
+	 * </p>
+	 */
+	private List<Collection<List<WebEvent>>> sequencesFrequentUsers;
+
+	/**
+	 * <p>
+	 * Threshold that defines how many sessions of a user are require to deem
+	 * the user frequent. Note, that only sessions whose lengths is in range if
+	 * {@link #minLength} and {@link #maxLength} are counted.
+	 * </p>
+	 */
+	private int frequentUsersThreshold = -1;
+
+	/**
+	 * <p>
+	 * Name and path of the robot filter.
+	 * </p>
+	 */
+	private static final String ROBOTFILTERFILE = "misc/robotfilter.txt";
+
+	/**
+	 * <p>
+	 * Field that contains a regular expression that matches all robots
+	 * contained in {@link #ROBOTFILTERFILE}.
+	 * </p>
+	 */
+	private String robotRegex = null;
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new WeblogParser with a default timeout of
+	 * 3,600,000 milliseconds (1 hour).
+	 * </p>
+	 */
+	public WeblogParser() {
+		this(3600000);
+	}
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new WeblogParser.
+	 * </p>
+	 * 
+	 * @param timeout
+	 *            session timeout
+	 */
+	public WeblogParser(long timeout) {
+		this.timeout = timeout;
+	}
+
+	/**
+	 * <p>
+	 * Returns the generated event sequences.
+	 * </p>
+	 * 
+	 * @return generated event sequences
+	 */
+	public Collection<List<WebEvent>> getSequences() {
+		return sequences;
+	}
+
+	/**
+	 * <p>
+	 * Sets the session timeout.
+	 * </p>
+	 * 
+	 * @param timeout
+	 *            new session timeout
+	 */
+	public void setTimeout(long timeout) {
+		this.timeout = timeout;
+	}
+
+	/**
+	 * <p>
+	 * Sets the minimal length of a session. All sessions that contain less
+	 * events will be pruned.
+	 * </p>
+	 * 
+	 * @param minLength
+	 *            new minimal length
+	 */
+	public void setMinLength(int minLength) {
+		this.minLength = minLength;
+	}
+
+	/**
+	 * <p>
+	 * Sets the maximal length of a session. All sessions that contain more
+	 * events will be pruned.
+	 * </p>
+	 * 
+	 * @param maxLength
+	 *            new maximal length
+	 */
+	public void setMaxLength(int maxLength) {
+		this.maxLength = maxLength;
+	}
+
+	/**
+	 * <p>
+	 * Sets the URL of the server from which this log was generated. Often
+	 * required for replay generation
+	 * </p>
+	 * 
+	 * @param url
+	 *            URL of the server
+	 */
+	public void setUrl(String url) {
+		this.url = url;
+	}
+
+	/**
+	 * <p>
+	 * Sets the threshold for frequent users.
+	 * </p>
+	 * 
+	 * @param threshold
+	 *            threshold value; if the value is &lt;1, the sessions of the
+	 *            frequent users will not be determined
+	 */
+	public void setFrequentUserThreshold(int threshold) {
+		this.frequentUsersThreshold = threshold;
+	}
+
+	/**
+	 * <p>
+	 * Returns the IDs of all frequent users.
+	 * </p>
+	 * 
+	 * @return IDs of the frequent users
+	 */
+	public List<String> getFrequentUsers() {
+		return frequentUsers;
+	}
+
+	/**
+	 * <p>
+	 * Returns the sequences of all frequent users.
+	 * </p>
+	 * </p>
+	 * 
+	 * @return list of the sequences of all frequent users
+	 */
+	public List<Collection<List<WebEvent>>> getFrequentUserSequences() {
+		return sequencesFrequentUsers;
+	}
+
+	/**
+	 * <p>
+	 * Parses a web log file.
+	 * </p>
+	 * 
+	 * @param filename
+	 *            name and path of the log file
+	 * @throws IOException
+	 *             thrown if there is a problem with reading the log file
+	 * @throws FileNotFoundException
+	 *             thrown if the log file is not found
+	 * @throws ParseException
+	 *             thrown the date format is invalid
+	 */
+	public void parseFile(String filename) throws IOException,
+			FileNotFoundException, ParseException {
+		String[] lines = FileTools.getLinesFromFile(filename);
+
+		Map<String, List<Integer>> cookieSessionMap = new HashMap<String, List<Integer>>();
+		int lastId = -1;
+
+		SimpleDateFormat dateFormat = new SimpleDateFormat(
+				"yyyy-MM-dd HH:mm:ss");
+		loadRobotRegex();
+
+		sequences = new ArrayList<List<WebEvent>>();
+		users = new ArrayList<String>();
+
+		int lineCounter = 0;
+		for (String line : lines) {
+			lineCounter++;
+			String[] values = line.substring(1, line.length() - 1).split(
+					"\" \"");
+
+			// use cookie as session identifier
+			int cookieStart = values[0].lastIndexOf('.');
+			String cookie = values[0].substring(cookieStart + 1);
+			String dateString = values[1];
+			long timestamp = dateFormat.parse(dateString).getTime();
+			String uriString = values[2];
+			// String ref = values[3]; // referer is not yet used!
+			String agent;
+			if (values.length > 4) {
+				agent = values[4];
+			} else {
+				agent = "noagent";
+			}
+
+			List<String> postedVars = new ArrayList<String>();
+			if (values.length == 6) { // post vars found
+				for (String postVar : values[5].trim().split(" ")) {
+					if (!isBrokenVariable(postVar)) {
+						postedVars.add(postVar);
+					}
+				}
+			}
+			if (!isRobot(agent)) {
+				try {
+					URI uri = new URI(uriString);
+					String path = uri.getPath();
+					List<String> getVars = extractGetVarsFromUri(uri);
+					
+					WebEvent event = new WebEvent(url, path, timestamp,
+							postedVars, getVars);
+
+					// find session and add event
+					List<Integer> sessionIds = cookieSessionMap.get(cookie);
+					if (sessionIds == null) {
+						sessionIds = new ArrayList<Integer>();
+						// start new session
+						sessionIds.add(++lastId);
+						cookieSessionMap.put(cookie, sessionIds);
+						sequences.add(new LinkedList<WebEvent>());
+						users.add(cookie);
+					}
+					Integer lastSessionIndex = sessionIds
+							.get(sessionIds.size() - 1);
+					List<WebEvent> lastSession = sequences
+							.get(lastSessionIndex);
+					long lastEventTime = timestamp;
+					if (!lastSession.isEmpty()) {
+						lastEventTime = lastSession.get(lastSession.size() - 1)
+								.getTimestamp();
+					}
+					if (timestamp - lastEventTime > timeout) {
+						sessionIds.add(++lastId);
+						List<WebEvent> newSession = new LinkedList<WebEvent>();
+						newSession.add(event);
+						sequences.add(newSession);
+						users.add(cookie);
+					} else {
+						lastSession.add(event);
+					}
+				} catch (URISyntaxException e) {
+					Console.traceln("Ignored line " + lineCounter + ": "
+							+ e.getMessage());
+				}
+			}
+		}
+		Console.traceln("" + sequences.size() + " user sequences found");
+		pruneSequences();
+		Console.traceln("" + sequences.size()
+				+ " remaining after pruning of sequences shorter than "
+				+ minLength);
+		Set<String> uniqueUsers = new HashSet<String>(users);
+		Console.traceln("" + uniqueUsers.size() + " unique users");
+		if (frequentUsersThreshold > 0) {
+			generateFrequentUserSequences(uniqueUsers);
+		}
+	}
+
+	/**
+	 * <p>
+	 * Generates the frequent user sequences, according to the threshold
+	 * {@link #frequentUsersThreshold}.
+	 * </p>
+	 * 
+	 * @param uniqueUsers
+	 *            set with all user IDs
+	 */
+	private void generateFrequentUserSequences(Set<String> uniqueUsers) {
+		frequentUsers = new ArrayList<String>();
+		sequencesFrequentUsers = new ArrayList<Collection<List<WebEvent>>>();
+		for (String user : uniqueUsers) {
+			List<String> tmp = new ArrayList<String>();
+			tmp.add(user);
+			List<String> usersCopy = new LinkedList<String>(users);
+			usersCopy.retainAll(tmp);
+			int size = usersCopy.size();
+			if (size >= frequentUsersThreshold) {
+				frequentUsers.add(user);
+				Collection<List<WebEvent>> sequencesUser = new ArrayList<List<WebEvent>>();
+				for (int i = 0; i < sequences.size(); i++) {
+					if (users.get(i).equals(user)) {
+						sequencesUser.add(sequences.get(i));
+					}
+				}
+				sequencesFrequentUsers.add(sequencesUser);
+
+			}
+		}
+		Console.traceln("" + frequentUsers.size() + " users with more than "
+				+ frequentUsersThreshold + " sequences");
+	}
+
+	/**
+	 * <p>
+	 * Prunes sequences shorter than {@link #minLength} and longer than
+	 * {@link #maxLength}.
+	 * </p>
+	 */
+	private void pruneSequences() {
+		int i = 0;
+		while (i < sequences.size()) {
+			if ((sequences.get(i).size() < minLength)
+					|| sequences.get(i).size() > maxLength) {
+				sequences.remove(i);
+				users.remove(i);
+			} else {
+				i++;
+			}
+		}
+
+	}
+
+	/**
+	 * <p>
+	 * Reads {@link #ROBOTFILTERFILE} and creates a regular expression that
+	 * matches all the robots defined in the file. The regular expression is
+	 * stored in the field {@link #robotRegex}.
+	 * </p>
+	 * 
+	 * @throws IOException
+	 *             thrown if there is a problem reading the robot filter
+	 * @throws FileNotFoundException
+	 *             thrown if the robot filter is not found
+	 */
+	private void loadRobotRegex() throws IOException, FileNotFoundException {
+		String[] lines = FileTools.getLinesFromFile(ROBOTFILTERFILE);
+		StringBuilder regex = new StringBuilder();
+		for (int i = 0; i < lines.length; i++) {
+			regex.append("(.*" + lines[i] + ".*)");
+			if (i != lines.length - 1) {
+				regex.append('|');
+			}
+		}
+		robotRegex = regex.toString();
+	}
+
+	/**
+	 * <p>
+	 * Checks whether an agent is a robot.
+	 * </p>
+	 * 
+	 * @param agent
+	 *            agent that is checked
+	 * @return true, if the agent is a robot; false otherwise
+	 */
+	private boolean isRobot(String agent) {
+		return agent.matches(robotRegex);
+	}
+
+	/**
+	 * <p>
+	 * Parses the URI and extracts the GET variables that have been passed.
+	 * </p>
+	 * 
+	 * @param uri
+	 *            URI that is parsed
+	 * @return a list with all GET variables
+	 * @throws URISyntaxException
+	 *             thrown if one of the variables seems to indicate that the
+	 *             request is a malicious attack on the web application
+	 */
+	private List<String> extractGetVarsFromUri(URI uri)
+			throws URISyntaxException {
+		List<String> getVars = new ArrayList<String>();
+		String query = uri.getQuery();
+		if (query != null) {
+			String[] paramPairs = query.split("&");
+			for (String paramPair : paramPairs) {
+				String[] paramSplit = paramPair.split("=");
+				if (!isBrokenVariable(paramSplit[0])) {
+					for (int i = 1; i < paramSplit.length; i++) {
+						checkForAttack(paramSplit[i]);
+					}
+					getVars.add(paramSplit[0]);
+				}
+			}
+		}
+		return getVars;
+	}
+
+	/**
+	 * <p>
+	 * Checks if a variable is broken.Currently, the check rather imprecise and
+	 * checks only if the term &quot;and&quot; is part of the variable name.
+	 * </p>
+	 * 
+	 * @param var
+	 *            variable that is checked
+	 * @return true if the variable is broken, false otherwise
+	 */
+	private boolean isBrokenVariable(String var) {
+		return var.contains("and");
+	}
+
+	/**
+	 * <p>
+	 * Checks if the variable name send with a request seems like an attack on the server.
+	 * </p>
+	 * @param value
+	 * @throws URISyntaxException
+	 */
+	private void checkForAttack(String value) throws URISyntaxException {
+		if (value.contains("UNION+") || value.contains("SELECT+")) {
+			throw new URISyntaxException(value, "possible injection attack");
+		}
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/php/commands/CMDloadWebSequences.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/php/commands/CMDloadWebSequences.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/php/commands/CMDloadWebSequences.java	(revision 540)
@@ -0,0 +1,117 @@
+package de.ugoe.cs.quest.plugin.php.commands;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.security.InvalidParameterException;
+import java.text.ParseException;
+import java.util.Collection;
+import java.util.List;
+
+import de.ugoe.cs.quest.CommandHelpers;
+import de.ugoe.cs.quest.plugin.php.WeblogParser;
+import de.ugoe.cs.quest.plugin.php.eventcore.WebEvent;
+import de.ugoe.cs.quest.ui.GlobalDataContainer;
+import de.ugoe.cs.util.console.Command;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Command to load sessions from a web log.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CMDloadWebSequences implements Command {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#run(java.util.List)
+	 */
+	@Override
+	public void run(List<Object> parameters) {
+		if (parameters.size() < 1) {
+			throw new InvalidParameterException();
+		}
+		String source;
+		String sequencesName;
+		String serverUrl = null;
+		int timeout = -1;
+		int minLength = -1;
+		int maxLength = -1;
+		boolean generateFrequentUsers = false;
+		int frequentUserThreshold = 20;
+		try {
+			source = (String) parameters.get(0);
+			sequencesName = (String) parameters.get(1);
+			if (parameters.size() >= 3) {
+				serverUrl = (String) parameters.get(2);
+			}
+			if (parameters.size() >= 6) {
+				timeout = Integer.parseInt((String) parameters.get(3));
+				minLength = Integer.parseInt((String) parameters.get(4));
+				maxLength = Integer.parseInt((String) parameters.get(5));
+			}
+			if (parameters.size() >= 8) {
+				generateFrequentUsers = Boolean
+						.parseBoolean((String) parameters.get(6));
+				frequentUserThreshold = Integer.parseInt((String) parameters
+						.get(7));
+			}
+		} catch (Exception e) {
+			throw new InvalidParameterException();
+		}
+
+		WeblogParser parser = new WeblogParser();
+		if (serverUrl != null) {
+			parser.setUrl(serverUrl);
+		}
+		if (timeout != -1) {
+			parser.setTimeout(timeout);
+			parser.setMinLength(minLength);
+			parser.setMaxLength(maxLength);
+		}
+		if (generateFrequentUsers) {
+			parser.setFrequentUserThreshold(frequentUserThreshold);
+		}
+		try {
+			parser.parseFile(source);
+		} catch (FileNotFoundException e) {
+			Console.printerrln(e.getMessage());
+		} catch (IOException e) {
+			Console.printerrln(e.getMessage());
+		} catch (ParseException e) {
+			Console.printerrln("Invalid format of date stamps.");
+			Console.printerrln(e.getMessage());
+		}
+
+		if (GlobalDataContainer.getInstance().addData(sequencesName,
+				parser.getSequences())) {
+			CommandHelpers.dataOverwritten(sequencesName);
+		}
+		if (generateFrequentUsers) {
+			List<String> frequentUserIDs = parser.getFrequentUsers();
+			List<Collection<List<WebEvent>>> frequentUserSessions = parser
+					.getFrequentUserSequences();
+			for (int i = 0; i < frequentUserIDs.size(); i++) {
+				String seqName = sequencesName + "_" + frequentUserIDs.get(i);
+				if (GlobalDataContainer.getInstance().addData(seqName,
+						frequentUserSessions.get(i))) {
+					CommandHelpers.dataOverwritten(seqName);
+				}
+			}
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#help()
+	 */
+	@Override
+	public void help() {
+		Console.println("Usage: loadWebSequences <filename> <sequencesName> {<serverUrl>} {<timeout> <minSessionLength> <maxSessionLength>} {<generateFrequentUsers> <frequentUserThreshold>}");
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/php/eventcore/WebEvent.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/php/eventcore/WebEvent.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/php/eventcore/WebEvent.java	(revision 540)
@@ -0,0 +1,108 @@
+package de.ugoe.cs.quest.plugin.php.eventcore;
+
+import java.util.List;
+
+import de.ugoe.cs.quest.eventcore.ReplayableEvent;
+
+/**
+ * <p>
+ * This class defines web events (of PHP-based web applications).
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ * 
+ */
+public class WebEvent extends ReplayableEvent<WebRequest> {
+
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * <p>
+	 * Timestamp of the event.
+	 * </p>
+	 */
+	private final long timestamp;
+
+	/**
+	 * <p>
+	 * Helper method that generates the type of the event based on the of the
+	 * URI, the POST variables, and the GET variables.
+	 * </p>
+	 * 
+	 * @param path
+	 *            path of the URI of the event
+	 * @param postVars
+	 *            POST variables send with the event
+	 * @param getVars
+	 *            GET variables send with the event
+	 * @return type of the event
+	 */
+	private final static String makeType(String path, List<String> postVars,
+			List<String> getVars) {
+		String type = path;
+		if (getVars != null && !getVars.isEmpty()) {
+			type += "+GET" + getVars.toString().replace(" ", "");
+		}
+		if (postVars != null && !postVars.isEmpty()) {
+			type += "+POST" + postVars.toString().replace(" ", "");
+		}
+		return type;
+	}
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new WebEvent.
+	 * </p>
+	 * 
+	 * @param url
+	 *            URL of the server that received the event
+	 * @param path
+	 *            path of the URI
+	 * @param timestamp
+	 *            timestamp of when the event took place
+	 * @param postVars
+	 *            POST variables send with the event
+	 * @param getVars
+	 *            GET variables send with the event
+	 */
+	public WebEvent(String url, String path, long timestamp,
+			List<String> postVars, List<String> getVars) {
+		super(makeType(path, postVars, getVars));
+		this.timestamp = timestamp;
+		super.setTarget(path);
+		addReplayEvent(new WebRequest(url, path, postVars, getVars));
+	}
+
+	/**
+	 * <p>
+	 * Returns the timestamp of the event.
+	 * </p>
+	 * 
+	 * @return timestamp of th event
+	 */
+	public long getTimestamp() {
+		return timestamp;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.eventcore.ReplayableEvent#equals(java.lang.Object)
+	 */
+	@Override
+	public boolean equals(Object other) {
+		return super.equals(other);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.eventcore.ReplayableEvent#hashCode()
+	 */
+	@Override
+	public int hashCode() {
+		return super.hashCode();
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/php/eventcore/WebRequest.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/php/eventcore/WebRequest.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/plugin/php/eventcore/WebRequest.java	(revision 540)
@@ -0,0 +1,172 @@
+package de.ugoe.cs.quest.plugin.php.eventcore;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import de.ugoe.cs.quest.eventcore.IReplayable;
+
+/**
+ * <p>
+ * Contains all information related to a web request, i.e., the path, the POST
+ * variables and the GET variables. The generated replay are for the command
+ * line tool {@code curl}. The requests do not contain correct values for the
+ * POST and GET request. Instead, only the parameters that are part of the
+ * requests are added and the values of the parameters are
+ * DATA_$PARAMNAME$_DATA, where $PARAMNAME$ is the upper case string of the
+ * parameter name. This allows test data generators to insert concrete values,
+ * as EventBench does not include a test data generator for web software.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class WebRequest implements IReplayable {
+
+	/**
+	 * <p>
+	 * Id for object serialization.
+	 * </p>
+	 */
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * <p>
+	 * POST variables of the web request.
+	 * </p>
+	 */
+	List<String> postVars;
+
+	/**
+	 * <p>
+	 * GET variables of the web request.
+	 * </p>
+	 */
+	List<String> getVars;
+
+	/**
+	 * <p>
+	 * URI of the web request.
+	 * </p>
+	 */
+	String targetUri;
+
+	/**
+	 * <p>
+	 * URL of the server.
+	 * </p>
+	 */
+	String serverUrl;
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new WebRequest.
+	 * </p>
+	 * 
+	 * @param uri
+	 *            URI of the request
+	 * @param postVars
+	 *            POST variables of the request
+	 * @param getVars
+	 *            GET variables of the request
+	 */
+	public WebRequest(String url, String uri, List<String> postVars,
+			List<String> getVars) {
+		serverUrl = url;
+		targetUri = uri;
+		this.postVars = new ArrayList<String>(postVars); // defensive copy
+		this.getVars = new ArrayList<String>(getVars);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.eventcore.IReplayable#getReplay()
+	 */
+	@Override
+	public String getReplay() {
+		StringBuilder builder = new StringBuilder();
+		builder.append("curl");
+		if (!postVars.isEmpty()) {
+			boolean isFirstPost = true;
+			for (String postVar : postVars) {
+				if (isFirstPost) {
+					builder.append(" --data \"");
+					isFirstPost = false;
+				} else {
+					builder.append('&');
+				}
+				builder.append(postVar + "=DATA_" + postVar.toUpperCase()
+						+ "_DATA");
+			}
+			builder.append('\"');
+		}
+		builder.append(' ');
+		if (serverUrl != null) {
+			builder.append(serverUrl);
+		}
+		builder.append(targetUri);
+		if (!getVars.isEmpty()) {
+			boolean isFirstGet = true;
+			for (String getVar : getVars) {
+				if (isFirstGet) {
+					builder.append('?');
+					isFirstGet = false;
+				} else {
+					builder.append('&');
+				}
+				builder.append(getVar + "=DATA_" + getVar.toUpperCase()
+						+ "_DATA");
+			}
+		}
+		return builder.toString();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.eventcore.IReplayable#getTarget()
+	 */
+	@Override
+	public String getTarget() {
+		return targetUri;
+	}
+
+	/**
+	 * <p>
+	 * Two {@link WebRequest}s are equal, if their {@link #targetUri},
+	 * {@link #postVars}, and {@link #getVars} are equal.
+	 * </p>
+	 * 
+	 * @see java.lang.Object#equals(java.lang.Object)
+	 */
+	@Override
+	public boolean equals(Object other) {
+		if (this == other) {
+			return true;
+		}
+		if (other instanceof WebRequest) {
+			return targetUri.equals(((WebRequest) other).targetUri)
+					&& postVars.equals(((WebRequest) other).postVars)
+					&& getVars.equals(((WebRequest) other).getVars);
+		}
+		return false;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see java.lang.Object#hashCode()
+	 */
+	@Override
+	public int hashCode() {
+		int multiplier = 17;
+		int hash = 42;
+
+		hash = multiplier * hash + targetUri.hashCode();
+		hash = multiplier * hash + postVars.hashCode();
+		hash = multiplier * hash + getVars.hashCode();
+
+		return hash;
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/GlobalDataContainer.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/GlobalDataContainer.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/GlobalDataContainer.java	(revision 540)
@@ -0,0 +1,226 @@
+package de.ugoe.cs.quest.ui;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import de.ugoe.cs.quest.SequenceInstanceOf;
+import de.ugoe.cs.quest.usageprofiles.IStochasticProcess;
+
+/**
+ * <p>
+ * This data structure can be used by the commands to store any {@link Object}.
+ * The data is stored in a key-value map, with strings as keys.
+ * </p>
+ * <p>
+ * This class is implemented as a singleton, as more than one data container
+ * does not serves no purpose.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class GlobalDataContainer implements Serializable {
+
+	/**
+	 * <p>
+	 * Id for object serialization.
+	 * </p>
+	 */
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * <p>
+	 * Instance of the {@link GlobalDataContainer} (implemented as singleton).
+	 * </p>
+	 */
+	transient private static GlobalDataContainer theInstance = null;
+
+	/**
+	 * <p>
+	 * Internal storage of the data.
+	 * </p>
+	 */
+	private Map<String, Object> dataObjects;
+
+	/**
+	 * <p>
+	 * Returns the instance of the container. If it does not yet exist, the data
+	 * container is created.
+	 * </p>
+	 * 
+	 * @return instance of the container
+	 */
+	public static GlobalDataContainer getInstance() {
+		if (theInstance == null) {
+			theInstance = new GlobalDataContainer();
+		}
+		return theInstance;
+	}
+
+	/**
+	 * <p>
+	 * Manual serialization of the object. Necessary to guarantee the singleton
+	 * property.
+	 * </p>
+	 * 
+	 * @param s
+	 *            output stream for the serialization
+	 * @throws IOException
+	 *             thrown if there is problem writing to the output stream
+	 */
+	private void writeObject(ObjectOutputStream s) throws IOException {
+		s.defaultWriteObject();
+		s.writeObject(dataObjects);
+	}
+
+	/**
+	 * <p>
+	 * Manual de-serialization of the object. Necessary to guarantee the
+	 * singleton property.
+	 * 
+	 * @param s
+	 *            input stream for the de-serialization
+	 * @throws IOException
+	 *             thrown if there is problem reading from the input stream
+	 * @throws ClassNotFoundException
+	 *             thrown if there is a problem reading from the input stream
+	 */
+	@SuppressWarnings("unchecked")
+	private void readObject(ObjectInputStream s) throws IOException,
+			ClassNotFoundException {
+		s.defaultReadObject();
+		if (theInstance == null) {
+			theInstance = new GlobalDataContainer();
+		}
+		theInstance.dataObjects = (Map<String, Object>) s.readObject();
+	}
+
+	/**
+	 * <p>
+	 * Manual de-serialization to guarantee the singleton property.
+	 * </p>
+	 * 
+	 * @return instance of the container
+	 */
+	private Object readResolve() {
+		return theInstance;
+	}
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new GlobalDataContainer. Private to guarantee the
+	 * singleton property.
+	 * </p>
+	 */
+	private GlobalDataContainer() {
+		dataObjects = new HashMap<String, Object>();
+	}
+
+	/**
+	 * <p>
+	 * Adds data to the container.
+	 * </p>
+	 * 
+	 * @param key
+	 *            key that identifies the data
+	 * @param data
+	 *            data that is stored
+	 * @return true, if an old entry was overwritten; false otherwise
+	 */
+	public boolean addData(String key, Object data) {
+		Object previousEntry = dataObjects.put(key, data);
+		return previousEntry != null;
+	}
+
+	/**
+	 * <p>
+	 * Removes data from the container.
+	 * </p>
+	 * 
+	 * @param key
+	 *            key of the data to be removed
+	 * @return true, if the object was removed; false if it was not present
+	 */
+	public boolean removeData(String key) {
+		Object previousEntry = dataObjects.remove(key);
+		return previousEntry != null;
+	}
+
+	/**
+	 * <p>
+	 * Returns the data associated with a key or {@code null} if no data is
+	 * stored for the key.
+	 * </p>
+	 * 
+	 * @param key
+	 *            key whose data is returned
+	 * @return data associated with the key; {@code null} if no data is
+	 *         available
+	 */
+	public Object getData(String key) {
+		return dataObjects.get(key);
+	}
+
+	/**
+	 * <p>
+	 * Resets the data container, i.e., deletes all its contents.
+	 * </p>
+	 */
+	public void reset() {
+		dataObjects = new HashMap<String, Object>();
+	}
+
+	/**
+	 * <p>
+	 * Returns all keys of collections of sequences contained in the storage.
+	 * </p>
+	 * 
+	 * @return keys of all collections of sequences contained in the storage
+	 */
+	public Collection<String> getAllSequencesNames() {
+		Collection<String> allSequencesNames = new LinkedList<String>();
+		for (Entry<String, Object> entry : dataObjects.entrySet()) {
+			if( SequenceInstanceOf.isCollectionOfSequences(entry.getValue())) {
+				allSequencesNames.add(entry.getKey());
+			}
+		}
+		return allSequencesNames;
+	}
+
+	/**
+	 * <p>
+	 * Returns the keys of all {@link IStochasticProcess}s contained in the
+	 * storage.
+	 * </p>
+	 * 
+	 * @return keys of all {@link IStochasticProcess}s contained in the storage
+	 */
+	public Collection<String> getAllModelNames() {
+		Collection<String> modelNames = new LinkedList<String>();
+		for (Entry<String, Object> entry : dataObjects.entrySet()) {
+			if (entry.getValue() instanceof IStochasticProcess) {
+				modelNames.add(entry.getKey());
+			}
+		}
+		return modelNames;
+	}
+
+	/**
+	 * <p>
+	 * Returns the keys of all objects contained in the storage.
+	 * </p>
+	 * 
+	 * @return keys of all objects in the storage
+	 */
+	public Collection<String> getAllKeys() {
+		return dataObjects.keySet();
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/AbstractTrainCommand.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/AbstractTrainCommand.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/AbstractTrainCommand.java	(revision 540)
@@ -0,0 +1,93 @@
+package de.ugoe.cs.quest.ui.commands;
+
+import java.security.InvalidParameterException;
+import java.util.Collection;
+import java.util.List;
+
+import de.ugoe.cs.quest.CommandHelpers;
+import de.ugoe.cs.quest.SequenceInstanceOf;
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.ui.GlobalDataContainer;
+import de.ugoe.cs.quest.usageprofiles.TrieBasedModel;
+import de.ugoe.cs.util.console.Command;
+
+/**
+ * <p>
+ * Abstract class for commands to train {@link TrieBasedModel}s.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public abstract class AbstractTrainCommand implements Command {
+
+	/**
+	 * <p>
+	 * Handling of additional parameters.
+	 * </p>
+	 * 
+	 * @param parameters
+	 *            same as the parameters passed to {@link #run(List)}.
+	 * @throws Exception
+	 *             thrown, if there is an error parsing the parameters
+	 */
+	abstract void handleAdditionalParameters(List<Object> parameters)
+			throws Exception;
+
+	/**
+	 * <p>
+	 * Returns a concrete instance of {@link TrieBasedModel} to be trained. This
+	 * is a factory method.
+	 * </p>
+	 * 
+	 * @return instance of {@link TrieBasedModel}
+	 */
+	abstract TrieBasedModel createModel();
+
+	/**
+	 * <p>
+	 * The command is implemented as a template method. The general structure of
+	 * the command is always the same, only the parameters of the command and
+	 * the creation of the {@link TrieBasedModel} instance. The former is
+	 * handled by {@link #handleAdditionalParameters(List)}, the latter by
+	 * {@link #createModel()}.
+	 * </p>
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#run(java.util.List)
+	 */
+	@SuppressWarnings("unchecked")
+	@Override
+	public void run(List<Object> parameters) {
+		String modelname;
+		String sequencesName;
+
+		try {
+			modelname = (String) parameters.get(0);
+			sequencesName = (String) parameters.get(1);
+			handleAdditionalParameters(parameters);
+		} catch (Exception e) {
+			throw new InvalidParameterException();
+		}
+
+		Object dataObject = GlobalDataContainer.getInstance().getData(
+				sequencesName);
+		if (dataObject == null) {
+			CommandHelpers.objectNotFoundMessage(sequencesName);
+			return;
+		}
+		if (!SequenceInstanceOf.isCollectionOfSequences(dataObject)) {
+			CommandHelpers.objectNotType(sequencesName,
+					"Collection<List<Event<?>>>");
+			return;
+		}
+		Collection<List<? extends Event<?>>> sequences = (Collection<List<? extends Event<?>>>) dataObject;
+
+		TrieBasedModel model = createModel();
+		model.train(sequences);
+		if (GlobalDataContainer.getInstance().addData(modelname, model)) {
+			CommandHelpers.dataOverwritten(modelname);
+		}
+
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDcalcCoverage.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDcalcCoverage.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDcalcCoverage.java	(revision 540)
@@ -0,0 +1,141 @@
+package de.ugoe.cs.quest.ui.commands;
+
+import java.security.InvalidParameterException;
+import java.util.Collection;
+import java.util.List;
+
+import de.ugoe.cs.quest.CommandHelpers;
+import de.ugoe.cs.quest.SequenceInstanceOf;
+import de.ugoe.cs.quest.coverage.CoverageCalculatorObserved;
+import de.ugoe.cs.quest.coverage.CoverageCalculatorProcess;
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.ui.GlobalDataContainer;
+import de.ugoe.cs.quest.usageprofiles.IStochasticProcess;
+import de.ugoe.cs.util.console.Command;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Command to calculate the coverage of a test suite.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CMDcalcCoverage implements Command {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#run(java.util.List)
+	 */
+	@SuppressWarnings("unchecked")
+	@Override
+	public void run(List<Object> parameters) {
+		String modelname;
+		String observedName;
+		String[] sequenceNames;
+		int minLength;
+		int maxLength;
+		try {
+			modelname = (String) parameters.get(0);
+			observedName = (String) parameters.get(1);
+			sequenceNames = (String[]) parameters.get(2);
+			minLength = Integer.parseInt((String) parameters.get(3));
+			maxLength = Integer.parseInt((String) parameters.get(4));
+		} catch (Exception e) {
+			throw new InvalidParameterException();
+		}
+
+		IStochasticProcess process = null;
+		Collection<List<? extends Event<?>>> observedSequences = null;
+		Collection<List<? extends Event<?>>> sequences = null;
+		Object dataObjectProcess = GlobalDataContainer.getInstance().getData(
+				modelname);
+		Object dataObjectObserved = GlobalDataContainer.getInstance().getData(
+				observedName);
+		if (dataObjectProcess == null) {
+			CommandHelpers.objectNotFoundMessage(modelname);
+			return;
+		}
+		if (!(dataObjectProcess instanceof IStochasticProcess)) {
+			CommandHelpers.objectNotType(modelname, "IStochasticProcess");
+			return;
+		}
+		if (dataObjectObserved == null) {
+			CommandHelpers.objectNotFoundMessage(observedName);
+			return;
+		}
+		if (!SequenceInstanceOf.isCollectionOfSequences(dataObjectObserved)) {
+			CommandHelpers.objectNotType(observedName,
+					"Collection<List<Event<?>>>");
+			return;
+		}
+		process = (IStochasticProcess) dataObjectProcess;
+		observedSequences = (Collection<List<? extends Event<?>>>) dataObjectObserved;
+
+		Console.print("seqName");
+		for (int length = minLength; length <= maxLength; length++) {
+			Console.print(";numObs_" + length);
+			Console.print(";numCov_" + length);
+			Console.print(";numNew_" + length);
+			Console.print(";numPos_" + length);
+			Console.print(";all_" + length);
+			Console.print(";pos_" + length);
+			Console.print(";poswei_" + length);
+			Console.print(";obs_" + length);
+			Console.print(";obswei_" + length);
+			Console.print(";new_" + length);
+			Console.print(";newpos_" + length);
+			Console.print(";newposwei_" + length);
+		}
+		Console.println("");
+		for (String sequenceName : sequenceNames) {
+			Object dataObjectSequences = GlobalDataContainer.getInstance()
+					.getData(sequenceName);
+			if (dataObjectSequences == null) {
+				CommandHelpers.objectNotFoundMessage(sequenceName);
+				return;
+			} else if (!SequenceInstanceOf
+					.isCollectionOfSequences(dataObjectSequences)) {
+				CommandHelpers.objectNotType(sequenceName,
+						"Collection<List<Event<?>>>");
+				return;
+			}
+			sequences = (Collection<List<? extends Event<?>>>) dataObjectSequences;
+			Console.print(sequenceName);
+			for (int length = minLength; length <= maxLength; length++) {
+				CoverageCalculatorProcess covCalcProc = new CoverageCalculatorProcess(
+						process, sequences, length);
+				CoverageCalculatorObserved covCalcObs = new CoverageCalculatorObserved(
+						observedSequences, sequences, length);
+				Console.print(";" + covCalcObs.getNumObserved());
+				Console.print(";" + covCalcObs.getNumCovered());
+				Console.print(";" + covCalcObs.getNumNew());
+				Console.print(";" + covCalcProc.getNumPossible());
+				Console.print(";" + covCalcProc.getCoverageAllNoWeight());
+				Console.print(";" + covCalcProc.getCoveragePossibleNoWeight());
+				Console.print(";" + covCalcProc.getCoveragePossibleWeight());
+				Console.print(";" + covCalcObs.getCoverageObserved());
+				Console.print(";"
+						+ covCalcObs.getCoverageObservedWeigth(process));
+				Console.print(";" + covCalcObs.getNewPercentage());
+				Console.print(";" + covCalcObs.getCoveragePossibleNew(process));
+				Console.print(";"
+						+ covCalcObs.getCoveragePossibleNewWeight(process));
+			}
+			Console.println("");
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#help()
+	 */
+	@Override
+	public void help() {
+		Console.println("Usage: calcCoverage <modelname> <observedSequences> [sequenceNames] <minCovLength> <maxCovLength>");
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDcalcEntropy.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDcalcEntropy.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDcalcEntropy.java	(revision 540)
@@ -0,0 +1,64 @@
+package de.ugoe.cs.quest.ui.commands;
+
+import java.security.InvalidParameterException;
+import java.util.List;
+
+import de.ugoe.cs.quest.CommandHelpers;
+import de.ugoe.cs.quest.ui.GlobalDataContainer;
+import de.ugoe.cs.quest.usageprofiles.FirstOrderMarkovModel;
+import de.ugoe.cs.util.console.Command;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Command to calculate the entropy of first-order Markov models.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CMDcalcEntropy implements Command {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#help()
+	 */
+	@Override
+	public void help() {
+		Console.println("Usage: calcEntropy <modelname>");
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#run(java.util.List)
+	 */
+	@Override
+	public void run(List<Object> parameters) {
+		String modelname = "";
+		try {
+			modelname = (String) parameters.get(0);
+		} catch (Exception e) {
+			throw new InvalidParameterException();
+		}
+
+		FirstOrderMarkovModel model = null;
+		Object dataObject = GlobalDataContainer.getInstance()
+				.getData(modelname);
+		if (dataObject == null) {
+			CommandHelpers.objectNotFoundMessage(modelname);
+			return;
+		}
+		if (!(dataObject instanceof FirstOrderMarkovModel)) {
+			CommandHelpers.objectNotType(modelname, "FirstOrderMarkovModel");
+			return;
+		}
+		model = (FirstOrderMarkovModel) dataObject;
+		double entropy = model.calcEntropy();
+		if (!Double.isNaN(entropy)) {
+			Console.println("entropy: " + entropy);
+		}
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDdeleteObject.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDdeleteObject.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDdeleteObject.java	(revision 540)
@@ -0,0 +1,50 @@
+package de.ugoe.cs.quest.ui.commands;
+
+import java.security.InvalidParameterException;
+import java.util.List;
+
+import de.ugoe.cs.quest.CommandHelpers;
+import de.ugoe.cs.quest.ui.GlobalDataContainer;
+import de.ugoe.cs.util.console.Command;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Command to delete object from {@link GlobalDataContainer}.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CMDdeleteObject implements Command {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#help()
+	 */
+	@Override
+	public void help() {
+		Console.println("Usage: deleteObject <objectname>");
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#run(java.util.List)
+	 */
+	@Override
+	public void run(List<Object> parameters) {
+		String objectName;
+		try {
+			objectName = (String) parameters.get(0);
+		} catch (Exception e) {
+			throw new InvalidParameterException();
+		}
+		boolean deleted = GlobalDataContainer.getInstance().removeData(
+				objectName);
+		if (!deleted) {
+			CommandHelpers.objectNotFoundMessage(objectName);
+		}
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDflattenModel.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDflattenModel.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDflattenModel.java	(revision 540)
@@ -0,0 +1,72 @@
+package de.ugoe.cs.quest.ui.commands;
+
+import java.security.InvalidParameterException;
+import java.util.List;
+
+import de.ugoe.cs.quest.CommandHelpers;
+import de.ugoe.cs.quest.ui.GlobalDataContainer;
+import de.ugoe.cs.quest.usageprofiles.FirstOrderMarkovModel;
+import de.ugoe.cs.quest.usageprofiles.HighOrderMarkovModel;
+import de.ugoe.cs.quest.usageprofiles.ModelFlattener;
+import de.ugoe.cs.util.console.Command;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Command to flatten high-order models and create first-order markov models
+ * with the same stochastic properties.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CMDflattenModel implements Command {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#run(java.util.List)
+	 */
+	@Override
+	public void run(List<Object> parameters) {
+		String modelname;
+		String modelnameFOM;
+
+		try {
+			modelname = (String) parameters.get(0);
+			modelnameFOM = (String) parameters.get(1);
+		} catch (Exception e) {
+			throw new InvalidParameterException();
+		}
+
+		Object dataObject = GlobalDataContainer.getInstance()
+				.getData(modelname);
+		if (dataObject == null) {
+			CommandHelpers.objectNotFoundMessage(modelname);
+			return;
+		}
+		if (!(dataObject instanceof HighOrderMarkovModel)) {
+			CommandHelpers.objectNotType(modelname, "HighOrderMarkovModel");
+			return;
+		}
+
+		HighOrderMarkovModel model = (HighOrderMarkovModel) dataObject;
+		ModelFlattener flattener = new ModelFlattener();
+		FirstOrderMarkovModel modelFOM = flattener
+				.flattenHighOrderMarkovModel(model);
+
+		if (GlobalDataContainer.getInstance().addData(modelnameFOM, modelFOM)) {
+			CommandHelpers.dataOverwritten(modelnameFOM);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#help()
+	 */
+	@Override
+	public void help() {
+		Console.println("Usage: flattenModel <modelname> <modelname_flattened>");
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDgenerateFixedLengthSequences.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDgenerateFixedLengthSequences.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDgenerateFixedLengthSequences.java	(revision 540)
@@ -0,0 +1,89 @@
+package de.ugoe.cs.quest.ui.commands;
+
+import java.security.InvalidParameterException;
+import java.util.Collection;
+import java.util.List;
+
+import de.ugoe.cs.quest.CommandHelpers;
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.testgeneration.DrawFromAllSequencesGenerator;
+import de.ugoe.cs.quest.ui.GlobalDataContainer;
+import de.ugoe.cs.quest.usageprofiles.IStochasticProcess;
+import de.ugoe.cs.util.console.Command;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Command to generate all sequences of a given length.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CMDgenerateFixedLengthSequences implements Command {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#run(java.util.List)
+	 */
+	@Override
+	public void run(List<Object> parameters) {
+		String modelname;
+		String sequencesName;
+		int minLength;
+		int maxLength;
+		boolean all = true;
+		int numSequences = -1;
+		boolean validEnd = true;
+		try {
+			modelname = (String) parameters.get(0);
+			sequencesName = (String) parameters.get(1);
+			minLength = Integer.parseInt((String) parameters.get(2));
+			maxLength = Integer.parseInt((String) parameters.get(3));
+			if (parameters.size() >= 5) {
+				all = Boolean.parseBoolean((String) parameters.get(4));
+			}
+			if (parameters.size() >= 6) {
+				numSequences = Integer.parseInt((String) parameters.get(5));
+			}
+			if (parameters.size() >= 7) {
+				validEnd = Boolean.parseBoolean((String) parameters.get(6));
+			}
+		} catch (Exception e) {
+			throw new InvalidParameterException();
+		}
+
+		IStochasticProcess model = null;
+		Object dataObject = GlobalDataContainer.getInstance()
+				.getData(modelname);
+		if (dataObject == null) {
+			CommandHelpers.objectNotFoundMessage(modelname);
+			return;
+		} else if (!(dataObject instanceof IStochasticProcess)) {
+			CommandHelpers.objectNotType(modelname, "IStochasticProcess");
+			return;
+		}
+		model = (IStochasticProcess) dataObject;
+		DrawFromAllSequencesGenerator generator = new DrawFromAllSequencesGenerator(
+				numSequences, minLength, maxLength, validEnd, all);
+		Collection<List<? extends Event<?>>> sequences = generator
+				.generateTestSuite(model);
+
+		if (GlobalDataContainer.getInstance().addData(sequencesName, sequences)) {
+			CommandHelpers.dataOverwritten(sequencesName);
+		}
+		Console.println("" + sequences.size() + " sequences generated");
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#help()
+	 */
+	@Override
+	public void help() {
+		Console.println("Usage: generateFixedLengthSequences <modelname> <sequencesName> <minlenght> <maxlength> {<all>} {<numSequences>} {<validEnd>}");
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDgenerateGreedy.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDgenerateGreedy.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDgenerateGreedy.java	(revision 540)
@@ -0,0 +1,179 @@
+package de.ugoe.cs.quest.ui.commands;
+
+import java.security.InvalidParameterException;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import de.ugoe.cs.quest.CommandHelpers;
+import de.ugoe.cs.quest.coverage.SequenceTools;
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.ui.GlobalDataContainer;
+import de.ugoe.cs.quest.usageprofiles.IStochasticProcess;
+import de.ugoe.cs.util.ArrayTools;
+import de.ugoe.cs.util.console.Command;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Command to generate test suite with a greedy strategy to achieve a desired
+ * coverage.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CMDgenerateGreedy implements Command {
+
+	/**
+	 * <p>
+	 * Tolerance for double comparisons
+	 * </p>
+	 */
+	final static double eps = 0.000000000001;
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#run(java.util.List)
+	 */
+	@Override
+	public void run(List<Object> parameters) {
+		String modelname;
+		String sequencesName;
+		int minLength;
+		int maxLength;
+		int coverageDepth;
+		float desiredCoverage;
+		boolean validEnd = true;
+		try {
+			modelname = (String) parameters.get(0);
+			sequencesName = (String) parameters.get(1);
+			minLength = Integer.parseInt((String) parameters.get(2));
+			maxLength = Integer.parseInt((String) parameters.get(3));
+			coverageDepth = Integer.parseInt((String) parameters.get(4));
+			desiredCoverage = Float.parseFloat((String) parameters.get(5));
+			if (parameters.size() >= 7) {
+				validEnd = Boolean.parseBoolean((String) parameters.get(6));
+			}
+		} catch (Exception e) {
+			throw new InvalidParameterException();
+		}
+
+		IStochasticProcess model = null;
+		Object dataObject = GlobalDataContainer.getInstance()
+				.getData(modelname);
+		if (dataObject == null) {
+			CommandHelpers.objectNotFoundMessage(modelname);
+			return;
+		} else if (!(dataObject instanceof IStochasticProcess)) {
+			CommandHelpers.objectNotType(modelname, "IStochasticProcess");
+			return;
+		}
+		model = (IStochasticProcess) dataObject;
+
+		// set up everything
+		List<List<? extends Event<?>>> allSequences = new LinkedList<List<? extends Event<?>>>();
+		for (int length = minLength; length <= maxLength; length++) {
+			if (validEnd) {
+				allSequences.addAll(model.generateValidSequences(length + 2));
+			} else {
+				allSequences.addAll(model.generateSequences(length + 1, true));
+			}
+		}
+		Console.traceln("" + allSequences.size() + " possible");
+
+		Collection<List<? extends Event<?>>> allSubSeqs = model
+				.generateSequences(coverageDepth);
+		Map<List<? extends Event<?>>, Double> weightMap = SequenceTools
+				.generateWeights(model, allSubSeqs);
+		Set<List<? extends Event<?>>> coveredSubSeqs = new LinkedHashSet<List<? extends Event<?>>>();
+
+		List<Set<List<? extends Event<?>>>> containedSubSeqs = new LinkedList<Set<List<? extends Event<?>>>>();
+		for (List<? extends Event<?>> sequence : allSequences) {
+			List<List<? extends Event<?>>> wrapper = new LinkedList<List<? extends Event<?>>>();
+			wrapper.add(sequence);
+			Set<List<? extends Event<?>>> currentSubSeqs = SequenceTools
+					.containedSubSequences(wrapper, coverageDepth);
+			containedSubSeqs.add(currentSubSeqs);
+		}
+
+		List<List<? extends Event<?>>> testSuite = new LinkedList<List<? extends Event<?>>>();
+		double currentCoverage = 0.0d;
+
+		// Build test suite
+		double prevGain = 1.0d;
+		boolean gainEqual = false;
+		while (currentCoverage < desiredCoverage) {
+			Double[] sequenceGain = new Double[allSequences.size()];
+			int i = 0;
+			for (Set<List<? extends Event<?>>> containedSubSeq : containedSubSeqs) {
+				double gain = 0.0d;
+				Iterator<List<? extends Event<?>>> subSeqIter = containedSubSeq
+						.iterator();
+				while (subSeqIter.hasNext()) {
+					List<? extends Event<?>> subSeq = subSeqIter.next();
+					if (!coveredSubSeqs.contains(subSeq)) {
+						gain += weightMap.get(subSeq);
+					} else {
+						subSeqIter.remove();
+					}
+				}
+				sequenceGain[i] = gain;
+				// optimization using that the gain is monotonically decreasing
+				if (Math.abs(gain - prevGain) <= eps) {
+					gainEqual = true;
+					break;
+				}
+				i++;
+			}
+			int maxIndex;
+			if (gainEqual) {
+				maxIndex = i;
+			} else {
+				maxIndex = ArrayTools.findMax(sequenceGain);
+			}
+			if (maxIndex < 0 || sequenceGain[maxIndex] <= 0.0 + eps) {
+				Console.traceln("No gain anymore! Desired coverage cannot be satisfied!");
+				break;
+			}
+			prevGain = sequenceGain[maxIndex];
+			testSuite.add(allSequences.get(maxIndex));
+			coveredSubSeqs.addAll(containedSubSeqs.get(maxIndex));
+			currentCoverage += sequenceGain[maxIndex];
+			if (gainEqual) {
+				allSequences.remove(maxIndex);
+				containedSubSeqs.remove(maxIndex);
+				gainEqual = false;
+			} else {
+				for (int j = sequenceGain.length - 1; j >= 0; j--) {
+					if (j == maxIndex || sequenceGain[j] <= 0.0 + eps) {
+						allSequences.remove(j);
+						containedSubSeqs.remove(j);
+					}
+				}
+			}
+		}
+
+		if (GlobalDataContainer.getInstance().addData(sequencesName, testSuite)) {
+			CommandHelpers.dataOverwritten(sequencesName);
+		}
+		Console.println("" + testSuite.size() + " sequences generated");
+		Console.println("" + currentCoverage + " coverage achieved");
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#help()
+	 */
+	@Override
+	public void help() {
+		Console.println("generateGreedy <modelname> <sequencesName> <minLength> <maxLength> <coverageDepth> <desiredCoverage> {<validEnd>}");
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDgenerateHybrid.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDgenerateHybrid.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDgenerateHybrid.java	(revision 540)
@@ -0,0 +1,98 @@
+package de.ugoe.cs.quest.ui.commands;
+
+import java.security.InvalidParameterException;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+
+import de.ugoe.cs.quest.CommandHelpers;
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.testgeneration.HybridGenerator;
+import de.ugoe.cs.quest.ui.GlobalDataContainer;
+import de.ugoe.cs.quest.usageprofiles.IStochasticProcess;
+import de.ugoe.cs.util.console.Command;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Command to generate sequences of a given length.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CMDgenerateHybrid implements Command {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#run(java.util.List)
+	 */
+	@Override
+	public void run(List<Object> parameters) {
+		String modelname;
+		String sequencesName;
+		int length;
+		int maxLengthAll;
+		int numSequences;
+		boolean validEnd = true;
+		try {
+			modelname = (String) parameters.get(0);
+			sequencesName = (String) parameters.get(1);
+			length = Integer.parseInt((String) parameters.get(2));
+			maxLengthAll = Integer.parseInt((String) parameters.get(3));
+			numSequences = Integer.parseInt((String) parameters.get(4));
+			if (parameters.size() >= 6) {
+				validEnd = Boolean.parseBoolean((String) parameters.get(5));
+			}
+		} catch (Exception e) {
+			throw new InvalidParameterException();
+		}
+
+		if (length <= maxLengthAll) {
+			// indirectly call command generateFixedLengthSequences
+			List<Object> parameters2 = new LinkedList<Object>();
+			parameters2.add(modelname);
+			parameters2.add(sequencesName);
+			parameters2.add(Integer.toString(length));
+			parameters2.add(Integer.toString(length));
+			parameters2.add(Boolean.toString(false));
+			parameters2.add(Integer.toString(numSequences));
+			parameters2.add(Boolean.toString(validEnd));
+			CMDgenerateFixedLengthSequences cmd = new CMDgenerateFixedLengthSequences();
+			cmd.run(parameters2);
+			return;
+		}
+
+		IStochasticProcess model = null;
+		Object dataObject = GlobalDataContainer.getInstance()
+				.getData(modelname);
+		if (dataObject == null) {
+			CommandHelpers.objectNotFoundMessage(modelname);
+			return;
+		} else if (!(dataObject instanceof IStochasticProcess)) {
+			CommandHelpers.objectNotType(modelname, "IStochasticProcess");
+			return;
+		}
+		model = (IStochasticProcess) dataObject;
+		
+		HybridGenerator generator = new HybridGenerator(numSequences, length, maxLengthAll, validEnd);
+		Collection<List<? extends Event<?>>> sequences = generator.generateTestSuite(model);
+		
+		if (GlobalDataContainer.getInstance().addData(sequencesName, sequences)) {
+			CommandHelpers.dataOverwritten(sequencesName);
+		}
+		Console.println("" + sequences.size() + " sequences generated");
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#help()
+	 */
+	@Override
+	public void help() {
+		Console.println("Usage: generateHybrid <modelname> <sequencesName> <lenght> <maxlengthAll> <numSequences> {<validEnd>}");
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDgenerateRandomReplay.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDgenerateRandomReplay.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDgenerateRandomReplay.java	(revision 540)
@@ -0,0 +1,82 @@
+package de.ugoe.cs.quest.ui.commands;
+
+import java.security.InvalidParameterException;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+
+import de.ugoe.cs.quest.CommandHelpers;
+import de.ugoe.cs.quest.ReplayGenerator;
+import de.ugoe.cs.quest.eventcore.ReplayableEvent;
+import de.ugoe.cs.quest.ui.GlobalDataContainer;
+import de.ugoe.cs.quest.usageprofiles.IStochasticProcess;
+import de.ugoe.cs.util.console.Command;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Command to create a replay file with randomly generated sessions.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CMDgenerateRandomReplay implements Command {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#help()
+	 */
+	@Override
+	public void help() {
+		Console.println("Usage: generateRandomReplay <modelName> <filename> {<numSessions>}");
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#run(java.util.List)
+	 */
+	@SuppressWarnings("unchecked")
+	@Override
+	public void run(List<Object> parameters) {
+		String modelname;
+		String filename;
+		int numSessions = 1;
+		try {
+			modelname = (String) parameters.get(0);
+			filename = (String) parameters.get(1);
+			if (parameters.size() < 3) {
+				numSessions = Integer.parseInt((String) parameters.get(2));
+			}
+		} catch (Exception e) {
+			throw new InvalidParameterException();
+		}
+
+		IStochasticProcess model = null;
+		Object dataObject = GlobalDataContainer.getInstance()
+				.getData(modelname);
+		if (dataObject == null) {
+			CommandHelpers.objectNotFoundMessage(modelname);
+			return;
+		}
+		if (!(dataObject instanceof IStochasticProcess)) {
+			CommandHelpers.objectNotType(modelname, "IStochasticProcess");
+			return;
+		}
+		model = (IStochasticProcess) dataObject;
+		Collection<List<ReplayableEvent<?>>> sequences = new LinkedList<List<ReplayableEvent<?>>>();
+		try {
+			for (int i = 0; i < numSessions; i++) {
+				sequences
+						.add((List<ReplayableEvent<?>>) model.randomSequence());
+			}
+		} catch (ClassCastException e) {
+			Console.printerrln("Modeled events don't support replay.");
+		}
+		ReplayGenerator generator = new ReplayGenerator();
+		generator.createLogfileMultipleSessions(sequences, filename);
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDgenerateRandomSequences.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDgenerateRandomSequences.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDgenerateRandomSequences.java	(revision 540)
@@ -0,0 +1,95 @@
+package de.ugoe.cs.quest.ui.commands;
+
+import java.security.InvalidParameterException;
+import java.util.Collection;
+import java.util.List;
+
+import de.ugoe.cs.quest.CommandHelpers;
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.testgeneration.RandomWalkGenerator;
+import de.ugoe.cs.quest.ui.GlobalDataContainer;
+import de.ugoe.cs.quest.usageprofiles.IStochasticProcess;
+import de.ugoe.cs.util.console.Command;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Command to generate random sessions.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CMDgenerateRandomSequences implements Command {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#run(java.util.List)
+	 */
+	@Override
+	public void run(List<Object> parameters) {
+		String modelname;
+		String sequencesName;
+		int numSessions;
+		int minLength = 0;
+		int maxLength = Integer.MAX_VALUE;
+		long maxIter;
+		boolean validEnd = true;
+		try {
+			modelname = (String) parameters.get(0);
+			sequencesName = (String) parameters.get(1);
+			numSessions = Integer.parseInt((String) parameters.get(2));
+			minLength = Integer.parseInt((String) parameters.get(3));
+			maxLength = Integer.parseInt((String) parameters.get(4));
+			maxIter = numSessions * 10;
+			if (parameters.size() >= 5) {
+				maxIter = Long.parseLong((String) parameters.get(5));
+			}
+			if (parameters.size() >= 6) {
+				validEnd = Boolean.parseBoolean((String) parameters.get(6));
+			}
+		} catch (Exception e) {
+			throw new InvalidParameterException();
+		}
+
+		IStochasticProcess model = null;
+		Object dataObject = GlobalDataContainer.getInstance()
+				.getData(modelname);
+		if (dataObject == null) {
+			CommandHelpers.objectNotFoundMessage(modelname);
+			return;
+		}
+		if (!(dataObject instanceof IStochasticProcess)) {
+			CommandHelpers.objectNotType(modelname, "IStochasticProcess");
+			return;
+		}
+		model = (IStochasticProcess) dataObject;
+
+		RandomWalkGenerator generator = new RandomWalkGenerator(numSessions,
+				minLength, maxLength, validEnd, maxIter);
+		Collection<List<? extends Event<?>>> sequences = generator
+				.generateTestSuite(model);
+
+		if (sequences.size() < numSessions) {
+			Console.println("Only " + sequences.size()
+					+ " unique sessions generated after " + maxIter
+					+ " iterations");
+		}
+
+		if (GlobalDataContainer.getInstance().addData(sequencesName, sequences)) {
+			CommandHelpers.dataOverwritten(sequencesName);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#help()
+	 */
+	@Override
+	public void help() {
+		Console.println("Usage: generateRandomSequenecs <modelName> <sequencesName> <numSessions> <minLength> <maxLength> {<maxIter>} {<validEnd>}");
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDgenerateReplayfile.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDgenerateReplayfile.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDgenerateReplayfile.java	(revision 540)
@@ -0,0 +1,70 @@
+package de.ugoe.cs.quest.ui.commands;
+
+import java.security.InvalidParameterException;
+import java.util.Collection;
+import java.util.List;
+
+import de.ugoe.cs.quest.CommandHelpers;
+import de.ugoe.cs.quest.ReplayGenerator;
+import de.ugoe.cs.quest.SequenceInstanceOf;
+import de.ugoe.cs.quest.eventcore.ReplayableEvent;
+import de.ugoe.cs.quest.ui.GlobalDataContainer;
+import de.ugoe.cs.util.console.Command;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Command to create a replay file from stored sessions.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CMDgenerateReplayfile implements Command {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#help()
+	 */
+	@Override
+	public void help() {
+		Console.println("Usage: generateReplayfile <filename> <sequences>");
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#run(java.util.List)
+	 */
+	@SuppressWarnings("unchecked")
+	@Override
+	public void run(List<Object> parameters) {
+		String filename;
+		String sequencesName;
+		try {
+			filename = (String) parameters.get(0);
+			sequencesName = (String) parameters.get(1);
+		} catch (Exception e) {
+			throw new InvalidParameterException();
+		}
+
+		Collection<List<ReplayableEvent<?>>> sequences = null;
+		Object dataObject = GlobalDataContainer.getInstance().getData(
+				sequencesName);
+		if (dataObject == null) {
+			CommandHelpers.objectNotFoundMessage(sequencesName);
+			return;
+		}
+		if (!SequenceInstanceOf.isCollectionOfSequences(dataObject)) {
+			CommandHelpers.objectNotType(sequencesName,
+					"Collection<List<Event<?>>>");
+			return;
+		}
+
+		sequences = (Collection<List<ReplayableEvent<?>>>) dataObject;
+		ReplayGenerator generator = new ReplayGenerator();
+		generator.createLogfileMultipleSessions(sequences, filename);
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDlistSymbols.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDlistSymbols.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDlistSymbols.java	(revision 540)
@@ -0,0 +1,73 @@
+package de.ugoe.cs.quest.ui.commands;
+
+import java.security.InvalidParameterException;
+import java.util.Arrays;
+import java.util.List;
+
+import de.ugoe.cs.quest.CommandHelpers;
+import de.ugoe.cs.quest.ui.GlobalDataContainer;
+import de.ugoe.cs.quest.usageprofiles.IStochasticProcess;
+import de.ugoe.cs.util.console.Command;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Command to list all events (symbols) known to a usage profile (stochastic
+ * process).
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CMDlistSymbols implements Command {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#run(java.util.List)
+	 */
+	@Override
+	public void run(List<Object> parameters) {
+		String modelname = "";
+		boolean sort = false;
+		try {
+			modelname = (String) parameters.get(0);
+			if (parameters.size() == 2) {
+				sort = Boolean.parseBoolean((String) parameters.get(1));
+			}
+		} catch (Exception e) {
+			throw new InvalidParameterException();
+		}
+
+		IStochasticProcess model = null;
+		Object dataObject = GlobalDataContainer.getInstance()
+				.getData(modelname);
+		if (dataObject == null) {
+			CommandHelpers.objectNotFoundMessage(modelname);
+			return;
+		}
+		if (!(dataObject instanceof IStochasticProcess)) {
+			CommandHelpers.objectNotType(modelname, "IStochasticProcess");
+			return;
+		}
+		model = (IStochasticProcess) dataObject;
+		String[] stateStrings = model.getSymbolStrings();
+		if (sort) {
+			Arrays.sort(stateStrings);
+		}
+		for (String stateString : stateStrings) {
+			Console.println(stateString);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#help()
+	 */
+	@Override
+	public void help() {
+		Console.println("Usage: listStates <modelName> {<sort>}");
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDload.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDload.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDload.java	(revision 540)
@@ -0,0 +1,61 @@
+package de.ugoe.cs.quest.ui.commands;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.security.InvalidParameterException;
+import java.util.List;
+
+import de.ugoe.cs.quest.ui.GlobalDataContainer;
+import de.ugoe.cs.util.console.Command;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Command that loads a previously serialized {@link GlobalDataContainer}.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CMDload implements Command {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#run(java.util.List)
+	 */
+	@Override
+	public void run(List<Object> parameters) {
+		String filename;
+		try {
+			filename = (String) parameters.get(0);
+		} catch (Exception e) {
+			throw new InvalidParameterException();
+		}
+
+		FileInputStream fis = null;
+		ObjectInputStream in = null;
+		try {
+			fis = new FileInputStream(filename);
+			in = new ObjectInputStream(fis);
+			in.readObject();
+			in.close();
+		} catch (IOException ex) {
+			Console.logException(ex);
+		} catch (ClassNotFoundException ex) {
+			Console.logException(ex);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#help()
+	 */
+	@Override
+	public void help() {
+		Console.println("Usage: load <filename>");
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDloadObject.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDloadObject.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDloadObject.java	(revision 540)
@@ -0,0 +1,69 @@
+package de.ugoe.cs.quest.ui.commands;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.security.InvalidParameterException;
+import java.util.List;
+
+import de.ugoe.cs.quest.CommandHelpers;
+import de.ugoe.cs.quest.ui.GlobalDataContainer;
+import de.ugoe.cs.util.console.Command;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Command to load a previously serialized object and store it in the
+ * {@link GlobalDataContainer}.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CMDloadObject implements Command {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#run(java.util.List)
+	 */
+	@Override
+	public void run(List<Object> parameters) {
+		String filename;
+		String objectName;
+		try {
+			filename = (String) parameters.get(0);
+			objectName = (String) parameters.get(1);
+		} catch (Exception e) {
+			throw new InvalidParameterException();
+		}
+
+		Object data = null;
+		FileInputStream fis = null;
+		ObjectInputStream in = null;
+		try {
+			fis = new FileInputStream(filename);
+			in = new ObjectInputStream(fis);
+			data = in.readObject();
+			in.close();
+		} catch (IOException ex) {
+			Console.logException(ex);
+		} catch (ClassNotFoundException ex) {
+			Console.logException(ex);
+		}
+		if (GlobalDataContainer.getInstance().addData(objectName, data)) {
+			CommandHelpers.dataOverwritten(objectName);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#help()
+	 */
+	@Override
+	public void help() {
+		Console.println("Usage: loadObject <filename> <objectName>");
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDmodelSize.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDmodelSize.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDmodelSize.java	(revision 540)
@@ -0,0 +1,63 @@
+package de.ugoe.cs.quest.ui.commands;
+
+import java.security.InvalidParameterException;
+import java.util.List;
+
+import de.ugoe.cs.quest.CommandHelpers;
+import de.ugoe.cs.quest.ui.GlobalDataContainer;
+import de.ugoe.cs.quest.usageprofiles.IStochasticProcess;
+import de.ugoe.cs.util.console.Command;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Command that prints the size of a stochastic process to the console.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CMDmodelSize implements Command {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#run(java.util.List)
+	 */
+	@Override
+	public void run(List<Object> parameters) {
+		String modelname;
+		try {
+			modelname = (String) parameters.get(0);
+		} catch (Exception e) {
+			throw new InvalidParameterException();
+		}
+
+		Object dataObject = GlobalDataContainer.getInstance()
+				.getData(modelname);
+		if (dataObject == null) {
+			CommandHelpers.objectNotFoundMessage(modelname);
+			return;
+		}
+		if (!(dataObject instanceof IStochasticProcess)) {
+			CommandHelpers.objectNotType(modelname, "IStochasticProcess");
+			return;
+		}
+
+		IStochasticProcess process = (IStochasticProcess) dataObject;
+		Console.println("#symbols: " + process.getNumSymbols()
+				+ " ; #FOMstates " + process.getNumFOMStates()
+				+ " ; #transitions: " + process.getNumTransitions());
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#help()
+	 */
+	@Override
+	public void help() {
+		Console.println("Usage: modelSize <modelName>");
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDprintDot.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDprintDot.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDprintDot.java	(revision 540)
@@ -0,0 +1,63 @@
+package de.ugoe.cs.quest.ui.commands;
+
+import java.security.InvalidParameterException;
+import java.util.List;
+
+import de.ugoe.cs.quest.CommandHelpers;
+import de.ugoe.cs.quest.ui.GlobalDataContainer;
+import de.ugoe.cs.quest.usageprofiles.IDotCompatible;
+import de.ugoe.cs.util.console.Command;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Command that prints a dot representation of a model (if supported) to the
+ * console.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CMDprintDot implements Command {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#help()
+	 */
+	@Override
+	public void help() {
+		Console.println("Usage: printDot <modelname>");
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#run(java.util.List)
+	 */
+	@Override
+	public void run(List<Object> parameters) {
+		String modelname = "";
+		try {
+			modelname = (String) parameters.get(0);
+		} catch (Exception e) {
+			throw new InvalidParameterException();
+		}
+
+		IDotCompatible model = null;
+		Object dataObject = GlobalDataContainer.getInstance()
+				.getData(modelname);
+		if (dataObject == null) {
+			CommandHelpers.objectNotFoundMessage(modelname);
+			return;
+		}
+		if (!(dataObject instanceof IDotCompatible)) {
+			CommandHelpers.objectNotType(modelname, "IDotCompatible");
+			return;
+		}
+
+		model = (IDotCompatible) dataObject;
+		Console.println(model.getDotRepresentation());
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDprintTrieDot.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDprintTrieDot.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDprintTrieDot.java	(revision 540)
@@ -0,0 +1,64 @@
+package de.ugoe.cs.quest.ui.commands;
+
+import java.security.InvalidParameterException;
+import java.util.List;
+
+import de.ugoe.cs.quest.CommandHelpers;
+import de.ugoe.cs.quest.ui.GlobalDataContainer;
+import de.ugoe.cs.quest.usageprofiles.Trie;
+import de.ugoe.cs.quest.usageprofiles.TrieBasedModel;
+import de.ugoe.cs.util.console.Command;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Command that prints the {@link Trie} of a {@link TrieBasedModel} as dot to
+ * the console.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CMDprintTrieDot implements Command {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#help()
+	 */
+	@Override
+	public void help() {
+		Console.println("Usage: printTreeDot <modelname>");
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#run(java.util.List)
+	 */
+	@Override
+	public void run(List<Object> parameters) {
+		String modelname = "";
+		try {
+			modelname = (String) parameters.get(0);
+		} catch (Exception e) {
+			throw new InvalidParameterException();
+		}
+
+		TrieBasedModel model = null;
+		Object dataObject = GlobalDataContainer.getInstance()
+				.getData(modelname);
+		if (dataObject == null) {
+			CommandHelpers.objectNotFoundMessage(modelname);
+			return;
+		}
+		if (!(dataObject instanceof TrieBasedModel)) {
+			CommandHelpers.objectNotType(modelname, "TrieBasedModel");
+			return;
+		}
+
+		model = (TrieBasedModel) dataObject;
+		Console.println(model.getTrieDotRepresentation());
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDsave.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDsave.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDsave.java	(revision 540)
@@ -0,0 +1,59 @@
+package de.ugoe.cs.quest.ui.commands;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.security.InvalidParameterException;
+import java.util.List;
+
+import de.ugoe.cs.quest.ui.GlobalDataContainer;
+import de.ugoe.cs.util.console.Command;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Command to save the {@link GlobalDataContainer} through serialization.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CMDsave implements Command {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#run(java.util.List)
+	 */
+	@Override
+	public void run(List<Object> parameters) {
+		String filename;
+		try {
+			filename = (String) parameters.get(0);
+		} catch (Exception e) {
+			throw new InvalidParameterException();
+		}
+
+		FileOutputStream fos = null;
+		ObjectOutputStream out = null;
+		try {
+			fos = new FileOutputStream(filename);
+			out = new ObjectOutputStream(fos);
+			out.writeObject(GlobalDataContainer.getInstance());
+			out.close();
+		} catch (IOException ex) {
+			Console.logException(ex);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#help()
+	 */
+	@Override
+	public void help() {
+		Console.println("Usage: save <filename>");
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDsaveObject.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDsaveObject.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDsaveObject.java	(revision 540)
@@ -0,0 +1,70 @@
+package de.ugoe.cs.quest.ui.commands;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.security.InvalidParameterException;
+import java.util.List;
+
+import de.ugoe.cs.quest.CommandHelpers;
+import de.ugoe.cs.quest.ui.GlobalDataContainer;
+import de.ugoe.cs.util.console.Command;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Command that saves an object contained in the {@link GlobalDataContainer}
+ * through serialization.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CMDsaveObject implements Command {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#run(java.util.List)
+	 */
+	@Override
+	public void run(List<Object> parameters) {
+		String filename;
+		String objectName;
+		try {
+			filename = (String) parameters.get(0);
+			objectName = (String) parameters.get(1);
+		} catch (Exception e) {
+			throw new InvalidParameterException();
+		}
+
+		Object dataObject = GlobalDataContainer.getInstance().getData(
+				objectName);
+		if (dataObject == null) {
+			CommandHelpers.objectNotFoundMessage(objectName);
+			return;
+		}
+
+		FileOutputStream fos = null;
+		ObjectOutputStream out = null;
+		try {
+			fos = new FileOutputStream(filename);
+			out = new ObjectOutputStream(fos);
+			out.writeObject(dataObject);
+			out.close();
+		} catch (IOException ex) {
+			Console.logException(ex);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#help()
+	 */
+	@Override
+	public void help() {
+		Console.println("Usage: saveObject <filename> <objectName>");
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDsequenceStatistics.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDsequenceStatistics.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDsequenceStatistics.java	(revision 540)
@@ -0,0 +1,83 @@
+package de.ugoe.cs.quest.ui.commands;
+
+import java.security.InvalidParameterException;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import de.ugoe.cs.quest.CommandHelpers;
+import de.ugoe.cs.quest.SequenceInstanceOf;
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.ui.GlobalDataContainer;
+import de.ugoe.cs.util.console.Command;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Command to print basic statistical information about stored sequences, e.g.,
+ * how many there are of which lenght.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CMDsequenceStatistics implements Command {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#run(java.util.List)
+	 */
+	@SuppressWarnings("unchecked")
+	@Override
+	public void run(List<Object> parameters) {
+		String sequencesName;
+		try {
+			sequencesName = (String) parameters.get(0);
+		} catch (Exception e) {
+			throw new InvalidParameterException();
+		}
+
+		Collection<List<Event<?>>> sequences = null;
+		Object dataObject = GlobalDataContainer.getInstance().getData(
+				sequencesName);
+		if (dataObject == null) {
+			CommandHelpers.objectNotFoundMessage(sequencesName);
+			return;
+		}
+		if (!SequenceInstanceOf.isCollectionOfSequences(dataObject)) {
+			CommandHelpers.objectNotType(sequencesName,
+					"Collection<List<Event<?>>>");
+			return;
+		}
+
+		sequences = (Collection<List<Event<?>>>) dataObject;
+		Console.println("Number of Sequences: " + sequences.size());
+		SortedMap<Integer, Integer> lengthMap = new TreeMap<Integer, Integer>();
+		for (List<Event<?>> sequence : sequences) {
+			Integer currentSize = sequence.size();
+			if (lengthMap.containsKey(currentSize)) {
+				lengthMap.put(currentSize, lengthMap.get(currentSize) + 1);
+			} else {
+				lengthMap.put(currentSize, 1);
+			}
+		}
+		for (Entry<Integer, Integer> entry : lengthMap.entrySet()) {
+			Console.println("Of length " + entry.getKey() + ": "
+					+ entry.getValue());
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#help()
+	 */
+	@Override
+	public void help() {
+		Console.println("Usage: sequenceStatistics <sequencesName>");
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDshowMarkovModel.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDshowMarkovModel.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDshowMarkovModel.java	(revision 540)
@@ -0,0 +1,114 @@
+package de.ugoe.cs.quest.ui.commands;
+
+import java.awt.Dimension;
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.security.InvalidParameterException;
+import java.util.List;
+
+import javax.swing.JFrame;
+
+import org.apache.commons.collections15.Transformer;
+
+import de.ugoe.cs.quest.CommandHelpers;
+import de.ugoe.cs.quest.ui.GlobalDataContainer;
+import de.ugoe.cs.quest.usageprofiles.FirstOrderMarkovModel;
+import de.ugoe.cs.quest.usageprofiles.FirstOrderMarkovModel.MarkovEdge;
+import de.ugoe.cs.util.console.Command;
+import de.ugoe.cs.util.console.Console;
+import edu.uci.ics.jung.algorithms.layout.Layout;
+import edu.uci.ics.jung.algorithms.layout.ISOMLayout;
+import edu.uci.ics.jung.graph.Graph;
+import edu.uci.ics.jung.visualization.BasicVisualizationServer;
+import edu.uci.ics.jung.visualization.decorators.ToStringLabeller;
+import edu.uci.ics.jung.visualization.renderers.Renderer.VertexLabel.Position;
+
+/**
+ * <p>
+ * Command that visualizes first-order Markov models.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CMDshowMarkovModel implements Command {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#help()
+	 */
+	@Override
+	public void help() {
+		Console.println("Usage: showMarkovModel <modelName> {<showNodeNames>}");
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#run(java.util.List)
+	 */
+	@Override
+	public void run(List<Object> parameters) {
+		String modelname;
+		boolean showNodeNames = false;
+		try {
+			modelname = (String) parameters.get(0);
+			if (parameters.size() == 2) {
+				showNodeNames = Boolean
+						.parseBoolean((String) parameters.get(1));
+			}
+		} catch (Exception e) {
+			throw new InvalidParameterException();
+		}
+
+		Object dataObject = GlobalDataContainer.getInstance()
+				.getData(modelname);
+		if (dataObject == null) {
+			CommandHelpers.objectNotFoundMessage(modelname);
+			return;
+		}
+		if (!(dataObject instanceof FirstOrderMarkovModel)) {
+			CommandHelpers.objectNotType(modelname, "FirstOrderMarkovModel");
+			return;
+		}
+		FirstOrderMarkovModel mm = (FirstOrderMarkovModel) dataObject;
+
+		Graph<String, MarkovEdge> graph = mm.getGraph();
+		Layout<String, MarkovEdge> layout = new ISOMLayout<String, MarkovEdge>(
+				graph);
+		layout.setSize(new Dimension(1000, 800)); // sets the initial size
+													// of the space
+		// The BasicVisualizationServer<V,E> is parameterized by the edge
+		// types
+		BasicVisualizationServer<String, MarkovEdge> vv = new BasicVisualizationServer<String, MarkovEdge>(
+				layout);
+		vv.setPreferredSize(new Dimension(1100, 850)); // Sets the viewing
+														// area size
+
+		if (showNodeNames) {
+			final Rectangle rect = new Rectangle(240, 20);
+
+			Transformer<String, Shape> vertexShapeTransformer = new Transformer<String, Shape>() {
+				public Shape transform(String s) {
+					return rect;
+				}
+			};
+			vv.getRenderer().getVertexLabelRenderer()
+					.setPosition(Position.CNTR);
+			vv.getRenderContext().setVertexShapeTransformer(
+					vertexShapeTransformer);
+			vv.getRenderContext().setVertexLabelTransformer(
+					new ToStringLabeller<String>());
+		}
+
+		vv.getRenderContext().setEdgeLabelTransformer(
+				new ToStringLabeller<MarkovEdge>());
+
+		JFrame frame = new JFrame("Markov Model");
+		frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
+		frame.getContentPane().add(vv);
+		frame.pack();
+		frame.setVisible(true);
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDshowTimer.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDshowTimer.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDshowTimer.java	(revision 540)
@@ -0,0 +1,60 @@
+package de.ugoe.cs.quest.ui.commands;
+
+import java.security.InvalidParameterException;
+import java.util.List;
+
+import de.ugoe.cs.quest.CommandHelpers;
+import de.ugoe.cs.quest.ui.GlobalDataContainer;
+import de.ugoe.cs.util.console.Command;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Command to show the time elapsed since a timer has been started.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CMDshowTimer implements Command {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#run(java.util.List)
+	 */
+	@Override
+	public void run(List<Object> parameters) {
+		String timerName;
+		try {
+			timerName = (String) parameters.get(0);
+		} catch (Exception e) {
+			throw new InvalidParameterException();
+		}
+
+		Object dataObject = GlobalDataContainer.getInstance().getData(timerName);
+		if (dataObject == null) {
+			CommandHelpers.objectNotFoundMessage(timerName);
+			return;
+		}
+		if (!(dataObject instanceof Long)) {
+			CommandHelpers.objectNotType(timerName, "Long");
+			return;
+		}
+
+		long startTime = (Long) dataObject;
+		long currentTime = System.currentTimeMillis();
+		Console.traceln("" + (currentTime - startTime) + " milliseconds");
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#help()
+	 */
+	@Override
+	public void help() {
+		Console.println("Usage: showTimer <timerName>");
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDshowTrie.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDshowTrie.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDshowTrie.java	(revision 540)
@@ -0,0 +1,101 @@
+package de.ugoe.cs.quest.ui.commands;
+
+import java.awt.Dimension;
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.security.InvalidParameterException;
+import java.util.List;
+
+import javax.swing.JFrame;
+
+import org.apache.commons.collections15.Transformer;
+
+import de.ugoe.cs.quest.CommandHelpers;
+import de.ugoe.cs.quest.ui.GlobalDataContainer;
+import de.ugoe.cs.quest.usageprofiles.Trie;
+import de.ugoe.cs.quest.usageprofiles.TrieBasedModel;
+import de.ugoe.cs.quest.usageprofiles.Trie.Edge;
+import de.ugoe.cs.quest.usageprofiles.Trie.TrieVertex;
+import de.ugoe.cs.util.console.Command;
+import de.ugoe.cs.util.console.Console;
+import edu.uci.ics.jung.algorithms.layout.Layout;
+import edu.uci.ics.jung.algorithms.layout.TreeLayout;
+import edu.uci.ics.jung.graph.Tree;
+import edu.uci.ics.jung.visualization.BasicVisualizationServer;
+import edu.uci.ics.jung.visualization.decorators.ToStringLabeller;
+import edu.uci.ics.jung.visualization.renderers.Renderer.VertexLabel.Position;
+
+/**
+ * <p>
+ * Command that visualizes the {@link Trie} of a {@link TrieBasedModel}.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CMDshowTrie implements Command {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#help()
+	 */
+	@Override
+	public void help() {
+		Console.println("Usage: showTrie <modelName>");
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#run(java.util.List)
+	 */
+	@Override
+	public void run(List<Object> parameters) {
+		String modelname;
+		try {
+			modelname = (String) parameters.get(0);
+		} catch (Exception e) {
+			throw new InvalidParameterException();
+		}
+
+		Object dataObject = GlobalDataContainer.getInstance()
+				.getData(modelname);
+		if (dataObject == null) {
+			CommandHelpers.objectNotFoundMessage(modelname);
+			return;
+		}
+		if (!(dataObject instanceof TrieBasedModel)) {
+			CommandHelpers.objectNotType(modelname, "TrieBasedModel");
+		}
+		TrieBasedModel model = (TrieBasedModel) dataObject;
+		Tree<TrieVertex, Edge> graph = model.getTrieGraph();
+		Layout<TrieVertex, Edge> layout = new TreeLayout<TrieVertex, Edge>(
+				graph, 60);
+		// The BasicVisualizationServer<V,E> is parameterized by the edge
+		// types
+		BasicVisualizationServer<TrieVertex, Edge> vv = new BasicVisualizationServer<TrieVertex, Edge>(
+				layout);
+		vv.setPreferredSize(new Dimension(1100, 850)); // Sets the viewing
+														// area size
+
+		final Rectangle rect = new Rectangle(40, 20);
+
+		Transformer<TrieVertex, Shape> vertexShapeTransformer = new Transformer<TrieVertex, Shape>() {
+			public Shape transform(TrieVertex s) {
+				return rect;
+			}
+		};
+		vv.getRenderer().getVertexLabelRenderer().setPosition(Position.CNTR);
+		vv.getRenderContext().setVertexShapeTransformer(vertexShapeTransformer);
+		vv.getRenderContext().setVertexLabelTransformer(
+				new ToStringLabeller<TrieVertex>());
+
+		JFrame frame = new JFrame("Trie");
+		frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
+		frame.getContentPane().add(vv);
+		frame.pack();
+		frame.setVisible(true);
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDstartFileListener.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDstartFileListener.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDstartFileListener.java	(revision 540)
@@ -0,0 +1,53 @@
+package de.ugoe.cs.quest.ui.commands;
+
+import java.security.InvalidParameterException;
+import java.util.List;
+
+import de.ugoe.cs.quest.CommandHelpers;
+import de.ugoe.cs.quest.ui.GlobalDataContainer;
+import de.ugoe.cs.util.console.Command;
+import de.ugoe.cs.util.console.Console;
+import de.ugoe.cs.util.console.FileOutputListener;
+
+/**
+ * <p>
+ * Command to start a {@link FileOutputListener}.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CMDstartFileListener implements Command {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#run(java.util.List)
+	 */
+	@Override
+	public void run(List<Object> parameters) {
+		String filename;
+		try {
+			filename = (String) parameters.get(0);
+		} catch (Exception e) {
+			throw new InvalidParameterException();
+		}
+
+		FileOutputListener listener = new FileOutputListener(filename);
+		listener.start();
+		if (GlobalDataContainer.getInstance().addData(filename, listener)) {
+			CommandHelpers.dataOverwritten(filename);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#help()
+	 */
+	@Override
+	public void help() {
+		Console.println("Usage: startFileListener <filename>");
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDstartTimer.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDstartTimer.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDstartTimer.java	(revision 540)
@@ -0,0 +1,50 @@
+package de.ugoe.cs.quest.ui.commands;
+
+import java.security.InvalidParameterException;
+import java.util.List;
+
+import de.ugoe.cs.quest.CommandHelpers;
+import de.ugoe.cs.quest.ui.GlobalDataContainer;
+import de.ugoe.cs.util.console.Command;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Command to start a time.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CMDstartTimer implements Command {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#run(java.util.List)
+	 */
+	@Override
+	public void run(List<Object> parameters) {
+		String timerName;
+		try {
+			timerName = (String) parameters.get(0);
+		} catch (Exception e) {
+			throw new InvalidParameterException();
+		}
+		Long time = System.currentTimeMillis();
+		if (GlobalDataContainer.getInstance().addData(timerName, time)) {
+			CommandHelpers.dataOverwritten(timerName);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#help()
+	 */
+	@Override
+	public void help() {
+		Console.println("Usage: startTimer <timerName>");
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDstopFileListener.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDstopFileListener.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDstopFileListener.java	(revision 540)
@@ -0,0 +1,51 @@
+package de.ugoe.cs.quest.ui.commands;
+
+import java.security.InvalidParameterException;
+import java.util.List;
+
+import de.ugoe.cs.quest.CommandHelpers;
+import de.ugoe.cs.quest.ui.GlobalDataContainer;
+import de.ugoe.cs.util.console.Command;
+import de.ugoe.cs.util.console.Console;
+import de.ugoe.cs.util.console.FileOutputListener;
+
+/**
+ * <p>
+ * Command to stop a {@link FileOutputListener}.
+ * </p>
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CMDstopFileListener implements Command {
+
+	@Override
+	public void run(List<Object> parameters) {
+		String filename;
+		try {
+			filename = (String) parameters.get(0);
+		} catch (Exception e) {
+			throw new InvalidParameterException();
+		}
+
+		Object dataObject = GlobalDataContainer.getInstance().getData(filename);
+		if( dataObject==null ) {
+			CommandHelpers.objectNotFoundMessage(filename);
+			return;
+		}
+		if( !(dataObject instanceof FileOutputListener) ) {
+			CommandHelpers.objectNotType(filename, "FileOutputListener");
+			return;
+		}
+		
+		FileOutputListener listener = (FileOutputListener) dataObject;
+		listener.stop();
+		GlobalDataContainer.getInstance().removeData(filename);
+	}
+
+	@Override
+	public void help() {
+		Console.println("Command: stopFileListener <filename>");
+
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDtrainDFA.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDtrainDFA.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDtrainDFA.java	(revision 540)
@@ -0,0 +1,52 @@
+package de.ugoe.cs.quest.ui.commands;
+
+import java.util.List;
+import java.util.Random;
+
+import de.ugoe.cs.quest.usageprofiles.DeterministicFiniteAutomaton;
+import de.ugoe.cs.quest.usageprofiles.TrieBasedModel;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Command to train a Deterministic Finite Automaton (DFA).
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 2.0
+ */
+public class CMDtrainDFA extends AbstractTrainCommand {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#help()
+	 */
+	@Override
+	public void help() {
+		Console.println("Usage: trainDFA <modelName> <sequencesName>");
+	}
+
+	/**
+	 * <p>
+	 * No additional parameters.
+	 * </p>
+	 * 
+	 * @see de.ugoe.cs.quest.ui.commands.AbstractTrainCommand#handleAdditionalParameters(java.util.List)
+	 */
+	@Override
+	void handleAdditionalParameters(List<Object> parameters) throws Exception {
+		// no additional parameters.
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.ui.commands.AbstractTrainCommand#createModel()
+	 */
+	@Override
+	TrieBasedModel createModel() {
+		return new DeterministicFiniteAutomaton(new Random());
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDtrainMarkovModel.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDtrainMarkovModel.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDtrainMarkovModel.java	(revision 540)
@@ -0,0 +1,68 @@
+package de.ugoe.cs.quest.ui.commands;
+
+import java.util.List;
+import java.util.Random;
+
+import de.ugoe.cs.quest.usageprofiles.FirstOrderMarkovModel;
+import de.ugoe.cs.quest.usageprofiles.HighOrderMarkovModel;
+import de.ugoe.cs.quest.usageprofiles.TrieBasedModel;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Command to train first-order and high-order Markov models.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 2.0
+ */
+public class CMDtrainMarkovModel extends AbstractTrainCommand {
+
+	/**
+	 * <p>
+	 * Order of the Markov model.
+	 * </p>
+	 */
+	int order;
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#help()
+	 */
+	@Override
+	public void help() {
+		Console.println("Usage: trainMarkovModel <modelName> <sequencesName> {<order>}");
+	}
+
+	/**
+	 * <p>
+	 * Handles the parameter order.
+	 * </p>
+	 * 
+	 * @see de.ugoe.cs.quest.ui.commands.AbstractTrainCommand#handleOptionalParameters(java.util.List)
+	 */
+	@Override
+	void handleAdditionalParameters(List<Object> parameters) throws Exception {
+		if (parameters.size() >= 3) {
+			order = Integer.parseInt((String) parameters.get(2));
+		} else {
+			order = 1;
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.ui.commands.AbstractTrainCommand#createModel()
+	 */
+	@Override
+	TrieBasedModel createModel() {
+		if (order == 1) {
+			return new FirstOrderMarkovModel(new Random());
+		} else {
+			return new HighOrderMarkovModel(order, new Random());
+		}
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDtrainPPM.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDtrainPPM.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDtrainPPM.java	(revision 540)
@@ -0,0 +1,78 @@
+package de.ugoe.cs.quest.ui.commands;
+
+import java.util.List;
+import java.util.Random;
+
+import de.ugoe.cs.quest.usageprofiles.PredictionByPartialMatch;
+import de.ugoe.cs.quest.usageprofiles.TrieBasedModel;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Command that trains Prediction by Partial Match (PPM) models.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 2.0
+ */
+public class CMDtrainPPM extends AbstractTrainCommand {
+
+	/**
+	 * <p>
+	 * Escape probability of the PPM model.
+	 * </p>
+	 */
+	double probEscape;
+
+	/**
+	 * <p>
+	 * Maximal Markov order of the PPM model.
+	 * </p>
+	 */
+	int maxOrder;
+
+	/**
+	 * <p>
+	 * Minimal Markov order of the PPM model. Default: 0
+	 * </p>
+	 */
+	int minOrder = 0;
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#help()
+	 */
+	@Override
+	public void help() {
+		Console.println("Usage: trainPPM <modelName> <sequencesName> <probEscape> <maxOrder> {<minOrder>}");
+	}
+
+	/**
+	 * <p>
+	 * Handles the parameters probEscape, maxOrder, and minOrder.
+	 * </p>
+	 * 
+	 * @see de.ugoe.cs.quest.ui.commands.AbstractTrainCommand#handleOptionalParameters(java.util.List)
+	 */
+	@Override
+	void handleAdditionalParameters(List<Object> parameters) throws Exception {
+		probEscape = Double.parseDouble((String) parameters.get(2));
+		maxOrder = Integer.parseInt((String) parameters.get(3));
+		if (parameters.size() == 5) {
+			minOrder = Integer.parseInt((String) parameters.get(4));
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.ui.commands.AbstractTrainCommand#createModel()
+	 */
+	@Override
+	TrieBasedModel createModel() {
+		return new PredictionByPartialMatch(maxOrder, minOrder, new Random(),
+				probEscape);
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDupdateModel.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDupdateModel.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-core/src/main/java/de/ugoe/cs/quest/ui/commands/CMDupdateModel.java	(revision 540)
@@ -0,0 +1,80 @@
+package de.ugoe.cs.quest.ui.commands;
+
+import java.security.InvalidParameterException;
+import java.util.Collection;
+import java.util.List;
+
+import de.ugoe.cs.quest.CommandHelpers;
+import de.ugoe.cs.quest.SequenceInstanceOf;
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.ui.GlobalDataContainer;
+import de.ugoe.cs.quest.usageprofiles.TrieBasedModel;
+import de.ugoe.cs.util.console.Command;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Command to update a {@link TrieBasedModel}.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class CMDupdateModel implements Command {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#run(java.util.List)
+	 */
+	@SuppressWarnings("unchecked")
+	@Override
+	public void run(List<Object> parameters) {
+		String modelname;
+		String sequencesName;
+
+		try {
+			modelname = (String) parameters.get(0);
+			sequencesName = (String) parameters.get(1);
+		} catch (Exception e) {
+			throw new InvalidParameterException();
+		}
+
+		Object dataObject = GlobalDataContainer.getInstance().getData(
+				sequencesName);
+		if (dataObject == null) {
+			CommandHelpers.objectNotFoundMessage(sequencesName);
+			return;
+		}
+		if (!SequenceInstanceOf.isCollectionOfSequences(dataObject)) {
+			CommandHelpers.objectNotType(sequencesName,
+					"Collection<List<Event<?>>>");
+			return;
+		}
+		Collection<List<? extends Event<?>>> sequences = (Collection<List<? extends Event<?>>>) dataObject;
+
+		dataObject = GlobalDataContainer.getInstance().getData(modelname);
+		if (dataObject == null) {
+			CommandHelpers.objectNotFoundMessage(modelname);
+			return;
+		}
+		if (!(dataObject instanceof TrieBasedModel)) {
+			CommandHelpers.objectNotType(modelname, "TrieBasedModel");
+			return;
+		}
+
+		TrieBasedModel model = (TrieBasedModel) dataObject;
+		model.update(sequences);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#help()
+	 */
+	@Override
+	public void help() {
+		Console.println("Usage: updateModel <modelname> <sequencesName>");
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-swt/.classpath
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-swt/.classpath	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-swt/.classpath	(revision 540)
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/classes" path="src/main/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="src" output="target/test-classes" path="src/test/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
Index: /tags/quest-pre-eventrefactoring/quest-ui-swt/.project
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-swt/.project	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-swt/.project	(revision 540)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>quest-ui-swt</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
Index: /tags/quest-pre-eventrefactoring/quest-ui-swt/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-swt/.settings/org.eclipse.jdt.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-swt/.settings/org.eclipse.jdt.core.prefs	(revision 540)
@@ -0,0 +1,5 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.6
Index: /tags/quest-pre-eventrefactoring/quest-ui-swt/.settings/org.eclipse.m2e.core.prefs
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-swt/.settings/org.eclipse.m2e.core.prefs	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-swt/.settings/org.eclipse.m2e.core.prefs	(revision 540)
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
Index: /tags/quest-pre-eventrefactoring/quest-ui-swt/pom.xml
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-swt/pom.xml	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-swt/pom.xml	(revision 540)
@@ -0,0 +1,164 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>de.ugoe.cs.quest</groupId>
+  <artifactId>quest-ui-swt</artifactId>
+  <version>0.0.1-SNAPSHOT</version>
+  <name>quest-ui-swt</name>
+<scm>
+		<url>https://quest.informatik.uni-goettingen.de/svn/quest/trunk/quest-ui-swt</url>
+	</scm>
+	<repositories>
+		<repository>
+			<id>swt-repo</id>
+			<url>https://swt-repo.googlecode.com/svn/repo</url>
+		</repository>
+		<repository>
+			<id>quest-repo</id>
+			<url>https://trex.informatik.uni-goettingen.de/nexus/content/repositories/thirdparty</url>
+		</repository>
+	</repositories>
+	<dependencies>
+		<dependency>
+			<groupId>de.ugoe.cs</groupId>
+			<artifactId>java-utils</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+		</dependency>
+		<dependency>
+			<groupId>de.ugoe.cs.quest</groupId>
+			<artifactId>quest-core-events</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+		</dependency>
+		<dependency>
+			<groupId>de.ugoe.cs.quest</groupId>
+			<artifactId>quest-core-assertions</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+		</dependency>
+		<dependency>
+			<groupId>de.ugoe.cs.quest</groupId>
+			<artifactId>quest-core-usageprofiles</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+		</dependency>
+		<dependency>
+			<groupId>de.ugoe.cs.quest</groupId>
+			<artifactId>quest-ui-core</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+		</dependency>
+		<dependency>
+			<groupId>${swt.groupId}</groupId>
+			<artifactId>${swt.artifactId}</artifactId>
+			<version>3.8</version>
+		</dependency>
+		<dependency>
+			<groupId>org.eclipse</groupId>
+			<artifactId>ui-forms</artifactId>
+			<version>3.5</version>
+		</dependency>
+	</dependencies>
+
+	<profiles>
+		<profile>
+			<id>Windows x86</id>
+			<activation>
+				<os>
+					<family>windows</family>
+					<arch>x86</arch>
+				</os>
+			</activation>
+			<properties>
+				<swt.groupId>org.eclipse.swt</swt.groupId>
+				<swt.artifactId>org.eclipse.swt.win32.win32.x86</swt.artifactId>
+			</properties>
+		</profile>
+		<profile>
+			<id>Windows amd64</id>
+			<activation>
+				<os>
+					<family>windows</family>
+					<arch>amd64</arch>
+				</os>
+			</activation>
+			<properties>
+				<swt.groupId>org.eclipse.swt</swt.groupId>
+				<swt.artifactId>org.eclipse.swt.win32.win32.x86_64</swt.artifactId>
+			</properties>
+		</profile>
+		<profile>
+			<id>Linux x86</id>
+			<activation>
+				<os>
+					<family>linux</family>
+					<arch>x86</arch>
+				</os>
+			</activation>
+			<properties>
+				<swt.groupId>org.eclipse.swt</swt.groupId>
+				<swt.artifactId>org.eclipse.swt.gtk.linux.x86</swt.artifactId>
+			</properties>
+		</profile>
+		<profile>
+			<id>Linux i386</id>
+			<activation>
+				<os>
+					<family>linux</family>
+					<arch>i386</arch>
+				</os>
+			</activation>
+			<properties>
+				<swt.groupId>org.eclipse.swt</swt.groupId>
+				<swt.artifactId>org.eclipse.swt.gtk.linux.x86</swt.artifactId>
+			</properties>
+		</profile>
+		<profile>
+			<id>Linux x86_64</id>
+			<activation>
+				<os>
+					<family>linux</family>
+					<arch>x86_64</arch>
+				</os>
+			</activation>
+			<properties>
+				<swt.groupId>org.eclipse.swt</swt.groupId>
+				<swt.artifactId>org.eclipse.swt.gtk.linux.x86_64</swt.artifactId>
+			</properties>
+		</profile>
+		<profile>
+			<id>Linux amd64</id>
+			<activation>
+				<os>
+					<family>linux</family>
+					<arch>amd64</arch>
+				</os>
+			</activation>
+			<properties>
+				<swt.groupId>org.eclipse.swt</swt.groupId>
+				<swt.artifactId>org.eclipse.swt.gtk.linux.x86_64</swt.artifactId>
+			</properties>
+		</profile>
+		<profile>
+			<id>Linux ppc64</id>
+			<activation>
+				<os>
+					<family>linux</family>
+					<arch>ppc64</arch>
+				</os>
+			</activation>
+			<properties>
+				<swt.groupId>org.eclipse.swt</swt.groupId>
+				<swt.artifactId>org.eclipse.swt.gtk.linux.ppc64</swt.artifactId>
+			</properties>
+		</profile>
+	</profiles>
+
+	<build>
+		<plugins>
+			<plugin>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>2.3.2</version>
+				<configuration>
+					<source>1.6</source>
+					<target>1.6</target>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+</project>
Index: /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/AboutDialog.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/AboutDialog.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/AboutDialog.java	(revision 540)
@@ -0,0 +1,72 @@
+package de.ugoe.cs.quest.ui.swt;
+
+import org.eclipse.swt.program.Program;
+import org.eclipse.swt.widgets.Dialog;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.SWT;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.ui.forms.widgets.Hyperlink;
+import org.eclipse.swt.events.MouseAdapter;
+import org.eclipse.swt.events.MouseEvent;
+
+public class AboutDialog extends Dialog {
+
+	protected Shell shlAboutEventbenchconsole;
+	private final FormToolkit formToolkit = new FormToolkit(Display.getDefault());
+
+	/**
+	 * Create the dialog.
+	 * @param parent
+	 * @param style
+	 */
+	public AboutDialog(Shell parent, int style) {
+		super(parent, style);
+		setText("SWT Dialog");
+	}
+
+	/**
+	 * Open the dialog.
+	 */
+	public void open() {
+		createContents();
+		shlAboutEventbenchconsole.open();
+		shlAboutEventbenchconsole.layout();
+		Display display = getParent().getDisplay();
+		while (!shlAboutEventbenchconsole.isDisposed()) {
+			if (!display.readAndDispatch()) {
+				display.sleep();
+			}
+		}
+	}
+
+	/**
+	 * Create contents of the dialog.
+	 */
+	private void createContents() {
+		shlAboutEventbenchconsole = new Shell(getParent(), SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
+		shlAboutEventbenchconsole.setSize(283, 113);
+		shlAboutEventbenchconsole.setText("About EventBenchConsole");
+		
+		Label lblEventbenchconsole = new Label(shlAboutEventbenchconsole, SWT.CENTER);
+		lblEventbenchconsole.setBounds(10, 10, 267, 15);
+		lblEventbenchconsole.setText("EventBenchConsole");
+		
+		Label lblFurtherInformationAbout = new Label(shlAboutEventbenchconsole, SWT.WRAP);
+		lblFurtherInformationAbout.setBounds(10, 31, 267, 31);
+		lblFurtherInformationAbout.setText("Further information about this software is provided on our homepage.");
+		
+		final Hyperlink hprlnkHttpeventbenchinformatikunigoettingende = formToolkit.createHyperlink(shlAboutEventbenchconsole, "http://eventbench.informatik.uni-goettingen.de", SWT.NONE);
+		hprlnkHttpeventbenchinformatikunigoettingende.addMouseListener(new MouseAdapter() {
+			@Override
+			public void mouseDown(MouseEvent e) {
+				Program.launch(hprlnkHttpeventbenchinformatikunigoettingende.getText());
+			}
+		});
+		hprlnkHttpeventbenchinformatikunigoettingende.setBounds(10, 68, 267, 17);
+		formToolkit.paintBordersFor(hprlnkHttpeventbenchinformatikunigoettingende);
+		hprlnkHttpeventbenchinformatikunigoettingende.setBackground(null);
+
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/AbstractInsertEventComposite.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/AbstractInsertEventComposite.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/AbstractInsertEventComposite.java	(revision 540)
@@ -0,0 +1,20 @@
+package de.ugoe.cs.quest.ui.swt;
+
+import java.util.SortedSet;
+
+import org.eclipse.swt.widgets.Composite;
+
+import de.ugoe.cs.quest.eventcore.Event;
+
+abstract public class AbstractInsertEventComposite extends Composite {
+
+	protected SortedSet<String> targets;
+	
+	public AbstractInsertEventComposite(Composite parent, int style, SortedSet<String> targets) {
+		super(parent, style);
+		this.targets = targets;
+	}
+	
+	public abstract Event<?> getEvent(); 
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/CommandHistoryDialog.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/CommandHistoryDialog.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/CommandHistoryDialog.java	(revision 540)
@@ -0,0 +1,179 @@
+package de.ugoe.cs.quest.ui.swt;
+
+import java.awt.Toolkit;
+import java.awt.datatransfer.Clipboard;
+import java.awt.datatransfer.StringSelection;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.util.LinkedList;
+
+import org.eclipse.swt.widgets.Dialog;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.List;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.layout.GridData;
+
+import de.ugoe.cs.util.StringTools;
+import de.ugoe.cs.util.console.CommandExecuter;
+import de.ugoe.cs.util.console.Console;
+import de.ugoe.cs.util.console.listener.ICommandListener;
+
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+
+public class CommandHistoryDialog extends Dialog implements ICommandListener {
+	
+	protected java.util.List<String> history = new LinkedList<String>();
+	
+	protected List commandHistoryList;
+	protected Shell shell;
+	
+	boolean isOpen;
+
+	/**
+	 * Create the dialog.
+	 * @param parent
+	 * @param style
+	 */
+	public CommandHistoryDialog(Shell parent, int style) {
+		super(parent, style);
+		setText("Command History");
+		isOpen = false;
+		Console.getInstance().registerCommandListener(this);
+	}
+
+	/**
+	 * Open the dialog.
+	 */
+	public void open() {
+		createContents();
+		shell.open();
+		shell.layout();
+		isOpen = true;
+		Display display = getParent().getDisplay();
+		while (!shell.isDisposed()) {
+			if (!display.readAndDispatch()) {
+				display.sleep();
+			}
+		}
+	}
+
+	/**
+	 * Create contents of the dialog.
+	 */
+	private void createContents() {
+		shell = new Shell(getParent(), SWT.DIALOG_TRIM | SWT.RESIZE);
+		shell.addDisposeListener(new DisposeListener() {
+			public void widgetDisposed(DisposeEvent arg0) {
+				isOpen = false;
+			}
+		});
+		shell.setSize(450, 300);
+		shell.setText(getText());
+		shell.setLayout(new GridLayout(3, false));
+		
+		Label lblRecentCommands = new Label(shell, SWT.NONE);
+		lblRecentCommands.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1));
+		lblRecentCommands.setText("Recent Commands:");
+		new Label(shell, SWT.NONE);
+		
+		commandHistoryList = new List(shell, SWT.BORDER | SWT.V_SCROLL | SWT.MULTI);
+		commandHistoryList.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1));
+		for( String command : history ) {
+			commandHistoryList.add(command);
+		}
+		
+		Button btnExec = new Button(shell, SWT.NONE);
+		btnExec.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				for( String command : commandHistoryList.getSelection() ) {
+					CommandExecuter.getInstance().exec(command);
+				}
+			}
+		});
+		btnExec.setText("Execute");
+		
+		Button btnCopyToClipboard = new Button(shell, SWT.NONE);
+		btnCopyToClipboard.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
+				StringSelection content = new StringSelection(getSelectedCommands());
+				clipboard.setContents(content, null);
+			}
+		});
+		btnCopyToClipboard.setText("Copy to Clipboard");
+		
+		Button btnCreateBatchfile = new Button(shell, SWT.NONE);
+		btnCreateBatchfile.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent event) {
+				FileDialog fileDialog = new FileDialog(shell, SWT.SAVE);
+				String filename = fileDialog.open();
+				if( filename!=null ) {
+					File file = new File(filename);
+					boolean fileCreated;
+					try {
+						fileCreated = file.createNewFile();
+						if (!fileCreated) {
+							Console.traceln("Created batchfile " + filename);
+						} else {
+							Console.traceln("Overwrote file " + filename);
+						}
+					} catch (IOException e) {
+						Console.printerrln("Unable to create file " + filename);
+						Console.logException(e);
+					}
+					OutputStreamWriter writer = null;
+					try {
+						writer = new OutputStreamWriter(new FileOutputStream(file), "UTF-8");
+					} catch (IOException e) {
+						Console.printerrln("Unable to open file for writing (read-only file):"
+								+ filename);
+						Console.logException(e);
+						return;
+					}
+					try {
+						writer.write(getSelectedCommands());
+						writer.close();
+					} catch (IOException e) {
+						Console.printerrln("Unable to write to file.");
+						Console.logException(e);
+					}
+				}
+			}
+		});
+		btnCreateBatchfile.setText("Create Batchfile");
+
+	}
+
+	@Override
+	public void commandNotification(String command) {
+		history.add(command);
+		if( isOpen ) {
+			commandHistoryList.add(command);
+		}
+	}
+	
+	public boolean isOpen() {
+		return isOpen;
+	}
+	
+	private String getSelectedCommands() {
+		StringBuilder commands = new StringBuilder();
+		for( String command : commandHistoryList.getSelection()) {
+			commands.append(command + StringTools.ENDLINE);
+		}
+		return commands.toString();
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/ConsoleTabComposite.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/ConsoleTabComposite.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/ConsoleTabComposite.java	(revision 540)
@@ -0,0 +1,99 @@
+package de.ugoe.cs.quest.ui.swt;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
+
+
+import de.ugoe.cs.util.console.CommandExecuter;
+
+/**
+ * <p>
+ * Implements the composite for the console tab in the applications main window. 
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class ConsoleTabComposite extends Composite {
+
+	protected Text textCommand;
+	
+	protected StyledText textConsoleOutput;
+	
+	/**
+	 * Create the composite.
+	 * @param parent
+	 * @param style
+	 */
+	public ConsoleTabComposite(Composite parent, int style) {
+		super(parent, style);
+		createContents();
+	}
+	
+	private void createContents() {
+		setLayout(new GridLayout(3, false));
+		
+		Label lblCommand = new Label(this, SWT.NONE);
+		lblCommand.setText("Command:");
+		
+		textCommand = new Text(this, SWT.BORDER);
+		textCommand.addKeyListener(new KeyAdapter() {
+			@Override
+			public void keyReleased(KeyEvent e) {
+				if( e.keyCode==SWT.CR ) {
+					executeCommand();
+				}
+			}
+		});
+		GridData gd_textCommand = new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1);
+		gd_textCommand.widthHint = 304;
+		textCommand.setLayoutData(gd_textCommand);
+		textCommand.setFocus();
+		
+		Button btnEnter = new Button(this, SWT.NONE);
+		btnEnter.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				executeCommand();
+			}
+		});
+		btnEnter.setText("Enter");
+		
+		textConsoleOutput = new StyledText(this, SWT.BORDER | SWT.READ_ONLY | SWT.H_SCROLL | SWT.V_SCROLL | SWT.CANCEL);
+		GridData gd_textConsoleOutput = new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1);
+		gd_textConsoleOutput.heightHint = 102;
+		gd_textConsoleOutput.widthHint = 456;
+		textConsoleOutput.setLayoutData(gd_textConsoleOutput);
+		textConsoleOutput.addListener(SWT.Modify, new Listener(){
+		    public void handleEvent(Event e){
+		    	textConsoleOutput.setTopIndex(textConsoleOutput.getLineCount() - 1);
+		    }
+		});
+
+	}
+	
+	private void executeCommand() {
+		String command = textCommand.getText().trim();
+		CommandExecuter.getInstance().exec(command);
+		textCommand.setText("");
+	}
+
+	@Override
+	protected void checkSubclass() {
+		// Disable the check that prevents subclassing of SWT components
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/DataTabComposite.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/DataTabComposite.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/DataTabComposite.java	(revision 540)
@@ -0,0 +1,113 @@
+package de.ugoe.cs.quest.ui.swt;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.List;
+import org.eclipse.swt.widgets.MessageBox;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.layout.GridData;
+
+import de.ugoe.cs.quest.ui.GlobalDataContainer;
+import de.ugoe.cs.util.StringTools;
+import de.ugoe.cs.util.console.CommandExecuter;
+
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+
+public class DataTabComposite extends Composite {
+
+	List dataList;
+	
+	/**
+	 * Create the composite.
+	 * @param parent
+	 * @param style
+	 */
+	public DataTabComposite(Composite parent, int style) {
+		super(parent, style);
+		createContent();
+	}
+	
+	private void createContent() {
+		setLayout(new GridLayout(3, false));
+		
+		dataList = new List(this, SWT.BORDER | SWT.V_SCROLL);
+		dataList.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1));
+		
+		Button btnLoad = new Button(this, SWT.NONE);
+		btnLoad.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				GetObjectNameDialog getObjectNameDialog = new GetObjectNameDialog(getShell(), SWT.NONE);
+				getObjectNameDialog.open();
+				String objectName = getObjectNameDialog.getObjectName();
+				if( "".equals(objectName) ) {
+					return;
+				}
+				FileDialog fileDialog = new FileDialog(getShell(), SWT.OPEN);
+				String filename = fileDialog.open();
+				if( filename==null ) {
+					return;
+				}
+				String command = "loadObject " + filename + " " + objectName;
+				CommandExecuter.getInstance().exec(command);
+				updateDataList();
+			}
+		});
+		btnLoad.setText("Load");
+		
+		Button btnSave = new Button(this, SWT.NONE);
+		btnSave.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				String[] selectedStrings = dataList.getSelection();
+				if( selectedStrings.length==0 ) {
+					SWTHelpers.noSelectionError(getShell());
+					return;
+				}
+				if( selectedStrings.length>1 ) {
+					MessageBox messageBox = new MessageBox(getShell(), SWT.ERROR);
+					messageBox.setText("Error");
+					messageBox.setMessage("Only one object storable at a time." + StringTools.ENDLINE + "Please select only one object.");
+					return;
+				}
+				FileDialog fileDialog = new FileDialog(getShell(), SWT.SAVE);
+				String filename = fileDialog.open();
+				if( filename==null ) {
+					return;
+				}
+				String command = "saveObject " + filename + " " + selectedStrings[0];
+				CommandExecuter.getInstance().exec(command);
+			}
+		});
+		btnSave.setText("Save");
+		
+		Button btnDelete_2 = new Button(this, SWT.NONE);
+		btnDelete_2.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				if( SWTHelpers.deleteSelectedFromStorage(dataList)) {
+					updateDataList();
+				} else {
+					SWTHelpers.noSelectionError(getShell());
+				}
+			}
+		});
+		btnDelete_2.setText("Delete");
+	}
+
+	@Override
+	protected void checkSubclass() {
+		// Disable the check that prevents subclassing of SWT components
+	}
+	
+	public void updateDataList() {
+		dataList.removeAll();
+		for( String sequencesName : GlobalDataContainer.getInstance().getAllKeys() ) {
+			dataList.add(sequencesName);
+		}
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/EditSequenceDialog.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/EditSequenceDialog.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/EditSequenceDialog.java	(revision 540)
@@ -0,0 +1,192 @@
+package de.ugoe.cs.quest.ui.swt;
+
+import java.util.SortedSet;
+
+import org.eclipse.swt.widgets.Dialog;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.MessageBox;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Point;
+
+import de.ugoe.cs.quest.eventcore.Event;
+
+public class EditSequenceDialog extends Dialog {
+
+	protected Shell shell;
+	private Table table;
+	private TableColumn tblclmnEventType;
+	private TableColumn tblclmnEventTarget;
+
+	private java.util.List<Event<?>> sequence;
+	private SortedSet<String> targets;
+
+	/**
+	 * Create the dialog.
+	 * 
+	 * @param parent
+	 * @param style
+	 */
+	public EditSequenceDialog(Shell parent, int style, SortedSet<String> targets) {
+		super(parent, style);
+		setText("SWT Dialog");
+		this.targets = targets;
+	}
+
+	/**
+	 * Open the dialog.
+	 */
+	public void open(java.util.List<Event<?>> sequence) {
+		this.sequence = sequence;
+		createContents();
+		shell.open();
+		shell.layout();
+		Display display = getParent().getDisplay();
+		while (!shell.isDisposed()) {
+			if (!display.readAndDispatch()) {
+				display.sleep();
+			}
+		}
+	}
+
+	/**
+	 * Create contents of the dialog.
+	 */
+	private void createContents() {
+		shell = new Shell(getParent(), SWT.SHELL_TRIM | SWT.BORDER
+				| SWT.APPLICATION_MODAL);
+		shell.setSize(450, 300);
+		shell.setText(getText());
+		shell.setLayout(new GridLayout(3, false));
+
+		table = new Table(shell, SWT.BORDER | SWT.FULL_SELECTION);
+		table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1));
+		table.setHeaderVisible(true);
+		table.setLinesVisible(true);
+
+		tblclmnEventType = new TableColumn(table, SWT.NONE);
+		tblclmnEventType.setWidth(100);
+		tblclmnEventType.setText("Event Type");
+
+		tblclmnEventTarget = new TableColumn(table, SWT.NONE);
+		tblclmnEventTarget.setWidth(100);
+		tblclmnEventTarget.setText("Event Target");
+
+		// this listener makes the table entries multiline
+		Listener paintListener = new Listener() {
+			public void handleEvent(org.eclipse.swt.widgets.Event event) {
+				switch (event.type) {
+				case SWT.MeasureItem: {
+					TableItem item = (TableItem) event.item;
+					String text = item.getText(event.index);
+					Point size = event.gc.textExtent(text);
+					event.width = size.x;
+					event.height = Math.max(event.height, size.y);
+					break;
+				}
+				case SWT.PaintItem: {
+					TableItem item = (TableItem) event.item;
+					String text = item.getText(event.index);
+					Point size = event.gc.textExtent(text);
+					int offset = event.index == 0 ? Math.max(0,
+							(event.height - size.y) / 2) : 0;
+					event.gc.drawText(text, event.x, event.y + offset, true);
+					break;
+				}
+				case SWT.EraseItem:
+					event.detail &= ~SWT.FOREGROUND;
+					break;
+				default:
+					break;
+				}
+			}
+
+		};
+		table.addListener(SWT.MeasureItem, paintListener);
+		table.addListener(SWT.PaintItem, paintListener);
+		table.addListener(SWT.EraseItem, paintListener);
+
+		updateTableContents();
+
+		Button btnInsertBefore = new Button(shell, SWT.NONE);
+		btnInsertBefore.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				int index = table.getSelectionIndex();
+				if (index == -1) {
+					MessageBox messageBox = new MessageBox(shell, SWT.ERROR);
+					messageBox.setMessage("No event selected!");
+					messageBox.setText("Error");
+					messageBox.open();
+				} else {
+					openInsertDialog(index);
+				}
+			}
+		});
+		btnInsertBefore.setText("Insert Before");
+
+		Button btnInsertAfter = new Button(shell, SWT.NONE);
+		btnInsertAfter.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				int index = table.getSelectionIndex();
+				if (index == -1) {
+					MessageBox messageBox = new MessageBox(shell, SWT.ERROR);
+					messageBox.setMessage("No event selected!");
+					messageBox.setText("Error");
+					messageBox.open();
+				} else {
+					openInsertDialog(index + 1);
+				}
+			}
+		});
+		btnInsertAfter.setText("Insert After");
+
+		Button btnClose = new Button(shell, SWT.NONE);
+		btnClose.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				shell.dispose();
+			}
+		});
+		btnClose.setText("Close");
+
+	}
+
+	private void updateTableContents() {
+		table.removeAll();
+		for (Event<?> event : sequence) {
+			TableItem tableItem = new TableItem(table, SWT.NONE);
+			String target = event.getTarget();
+			if (target != null) {
+				// the target is split into multiple lines, as one line may
+				// only  be 259 characters in tables with Windows
+				target = target.replace("].", "].\n");
+			}
+			tableItem.setText(new String[] { event.getType(), target });
+		}
+		for (int i = 0; i < table.getColumnCount(); i++) {
+			table.getColumn(i).pack();
+		}
+	}
+
+	private void openInsertDialog(int position) {
+		InsertAssertionDialog insertDialog = new InsertAssertionDialog(shell,
+				SWT.NONE, targets);
+		Event<?> event = insertDialog.open();
+		if (event != null) {
+			sequence.add(position, event);
+			updateTableContents();
+		}
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/GenerateSequencesDialog.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/GenerateSequencesDialog.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/GenerateSequencesDialog.java	(revision 540)
@@ -0,0 +1,206 @@
+package de.ugoe.cs.quest.ui.swt;
+
+import org.eclipse.swt.widgets.Dialog;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.MessageBox;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Spinner;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.layout.GridData;
+
+import de.ugoe.cs.util.console.CommandExecuter;
+
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+
+public class GenerateSequencesDialog extends Dialog {
+
+	private String processName;
+	
+	protected Button btnNumberAll;
+	protected Button btnLengthAll;
+	protected Spinner numberSpinner;
+	protected Spinner iterationsSpinner;
+	protected Spinner minLengthSpinner;
+	protected Spinner maxLengthSpinner;
+	
+	protected Shell shlGenerateSequences;
+	private Text sequencesNameText;
+	private final FormToolkit formToolkit = new FormToolkit(Display.getDefault());
+
+	/**
+	 * Create the dialog.
+	 * @param parent
+	 * @param style
+	 */
+	public GenerateSequencesDialog(Shell parent, int style) {
+		super(parent, style);
+		setText("SWT Dialog");
+	}
+
+	/**
+	 * Open the dialog.
+	 */
+	public void open() {
+		createContents();
+		shlGenerateSequences.open();
+		shlGenerateSequences.layout();
+		Display display = getParent().getDisplay();
+		while (!shlGenerateSequences.isDisposed()) {
+			if (!display.readAndDispatch()) {
+				display.sleep();
+			}
+		}
+	}
+
+	/**
+	 * Create contents of the dialog.
+	 */
+	private void createContents() {
+		shlGenerateSequences = new Shell(getParent(), SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
+		shlGenerateSequences.setSize(201, 303);
+		shlGenerateSequences.setText("Generate Sequences");
+		shlGenerateSequences.setLayout(new GridLayout(2, false));
+		
+		Group group = new Group(shlGenerateSequences, SWT.NONE);
+		group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1));
+		group.setText("Name");
+		group.setLayout(new GridLayout(1, false));
+		
+		sequencesNameText = new Text(group, SWT.BORDER);
+		sequencesNameText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
+		
+		Group grpNumber = new Group(shlGenerateSequences, SWT.NONE);
+		grpNumber.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
+		grpNumber.setText("Number");
+		grpNumber.setLayout(new GridLayout(2, false));
+		
+		numberSpinner = new Spinner(grpNumber, SWT.BORDER);
+		numberSpinner.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
+		numberSpinner.setMinimum(1);
+		numberSpinner.setMaximum(Integer.MAX_VALUE);
+		
+		btnNumberAll = new Button(grpNumber, SWT.CHECK);
+		btnNumberAll.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				numberSpinner.setEnabled(!btnNumberAll.getSelection());
+				btnLengthAll.setEnabled(!btnNumberAll.getSelection());
+				iterationsSpinner.setEnabled(!btnNumberAll.getSelection());
+			}
+		});
+		btnNumberAll.setText("All");
+		
+		Group grpIterations = new Group(shlGenerateSequences, SWT.NONE);
+		grpIterations.setLayout(new GridLayout(1, false));
+		grpIterations.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1));
+		grpIterations.setText("Iterations");
+		
+		iterationsSpinner = new Spinner(grpIterations, SWT.BORDER);
+		iterationsSpinner.setMinimum(1);
+		iterationsSpinner.setMaximum(Integer.MAX_VALUE);
+		iterationsSpinner.setSelection(100000);
+		iterationsSpinner.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
+		
+		Group grpLength = new Group(shlGenerateSequences, SWT.NONE);
+		grpLength.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1));
+		grpLength.setText("Length");
+		grpLength.setLayout(new GridLayout(4, false));
+		
+		btnLengthAll = new Button(grpLength, SWT.CHECK);
+		btnLengthAll.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				minLengthSpinner.setEnabled(!btnLengthAll.getSelection());
+				maxLengthSpinner.setEnabled(!btnLengthAll.getSelection());
+			}
+		});
+		btnLengthAll.setText("All");
+		new Label(grpLength, SWT.NONE);
+		new Label(grpLength, SWT.NONE);
+		new Label(grpLength, SWT.NONE);
+		
+		Label label = new Label(grpLength, SWT.NONE);
+		label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
+		label.setText("Min.");
+		
+		minLengthSpinner = new Spinner(grpLength, SWT.BORDER);
+		minLengthSpinner.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
+		minLengthSpinner.setMinimum(1);
+		
+		Label label_1 = new Label(grpLength, SWT.NONE);
+		label_1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, true, 1, 1));
+		label_1.setText("Max.");
+		
+		maxLengthSpinner = new Spinner(grpLength, SWT.BORDER);
+		maxLengthSpinner.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
+		maxLengthSpinner.setToolTipText("0 means no limitations");
+		maxLengthSpinner.setMinimum(1);
+		
+		Button btnGenerate = formToolkit.createButton(shlGenerateSequences, "Generate!", SWT.NONE);
+		btnGenerate.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				if("".equals(sequencesNameText.getText())) {
+					MessageBox messageBox = new MessageBox(shlGenerateSequences, SWT.ERROR);
+					messageBox.setText("Error");
+					messageBox.setMessage("Sequences name not defined!");
+					messageBox.open();
+					return;
+				}
+				String sequencesName = sequencesNameText.getText();
+				int number = numberSpinner.getSelection();
+				int minLength = minLengthSpinner.getSelection();
+				int maxLength = maxLengthSpinner.getSelection();
+				int maxIter = iterationsSpinner.getSelection();
+				if( maxIter<=number ) {
+					maxIter = number;
+				}
+				String command = "";
+				if( btnNumberAll.getSelection() ) {
+					if( minLength>maxLength ) {
+						MessageBox messageBox = new MessageBox(shlGenerateSequences, SWT.ERROR);
+						messageBox.setText("Error");
+						messageBox.setMessage("Min. length must be smaller than or equal to max. length!");
+						messageBox.open();
+						return;
+					}
+					command = "generateFixedLengthSequences " + processName + " " + sequencesName + " " + minLength + " " + maxLength + " true";
+				} else {
+					command = "generateRandomSequences " + processName + " " + sequencesName + " " + number + " " + maxIter;
+					if( !btnLengthAll.getSelection() ) {
+						if( minLength>maxLength ) {
+							MessageBox messageBox = new MessageBox(shlGenerateSequences, SWT.ERROR);
+							messageBox.setText("Error");
+							messageBox.setMessage("Min. length must be smaller than or equal to max. length!");
+							messageBox.open();
+							return;
+						}
+						command += " " + minLength + " " + maxLength;
+					}
+				}
+				CommandExecuter.getInstance().exec(command);
+				shlGenerateSequences.dispose();
+			}
+		});
+		
+		Button btnAbort = formToolkit.createButton(shlGenerateSequences, "Abort", SWT.NONE);
+		btnAbort.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				shlGenerateSequences.dispose();
+			}
+		});
+
+	}
+	
+	public void setProcessName(String name) {
+		this.processName = name;
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/GetObjectNameDialog.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/GetObjectNameDialog.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/GetObjectNameDialog.java	(revision 540)
@@ -0,0 +1,96 @@
+package de.ugoe.cs.quest.ui.swt;
+
+import org.eclipse.swt.widgets.Dialog;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.MessageBox;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+
+public class GetObjectNameDialog extends Dialog {
+
+	String objectName = "";
+	
+	protected Shell shlObjectName;
+	private Text text;
+
+	/**
+	 * Create the dialog.
+	 * @param parent
+	 * @param style
+	 */
+	public GetObjectNameDialog(Shell parent, int style) {
+		super(parent, style);
+		setText("SWT Dialog");
+	}
+
+	/**
+	 * Open the dialog.
+	 */
+	public void open() {
+		createContents();
+		shlObjectName.open();
+		shlObjectName.layout();
+		Display display = getParent().getDisplay();
+		while (!shlObjectName.isDisposed()) {
+			if (!display.readAndDispatch()) {
+				display.sleep();
+			}
+		}
+	}
+
+	/**
+	 * Create contents of the dialog.
+	 */
+	private void createContents() {
+		shlObjectName = new Shell(getParent(), SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
+		shlObjectName.setSize(171, 109);
+		shlObjectName.setText("Object Name");
+		shlObjectName.setLayout(new GridLayout(2, false));
+		
+		Label lblPleaseEnterThe = new Label(shlObjectName, SWT.NONE);
+		lblPleaseEnterThe.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1));
+		lblPleaseEnterThe.setText("Please enter the object name:");
+		
+		text = new Text(shlObjectName, SWT.BORDER);
+		text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
+		
+		Button btnOk = new Button(shlObjectName, SWT.NONE);
+		btnOk.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				if( text.getText().equals("") ) {
+					MessageBox messageBox = new MessageBox(shlObjectName, SWT.ERROR);
+					messageBox.setText("Error");
+					messageBox.setMessage("No name entered!");
+					return;
+				}
+				objectName = text.getText();
+				shlObjectName.dispose();
+			}
+		});
+		btnOk.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
+		btnOk.setText("Ok");
+		
+		Button btnAbort = new Button(shlObjectName, SWT.NONE);
+		btnAbort.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				shlObjectName.dispose();
+			}
+		});
+		btnAbort.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
+		btnAbort.setText("Abort");
+
+	}
+	
+	public String getObjectName() {
+		return objectName;
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/InsertAssertionDialog.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/InsertAssertionDialog.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/InsertAssertionDialog.java	(revision 540)
@@ -0,0 +1,106 @@
+package de.ugoe.cs.quest.ui.swt;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.SortedSet;
+
+import org.eclipse.swt.widgets.Dialog;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.TabItem;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+
+import de.ugoe.cs.quest.eventcore.Event;
+
+public class InsertAssertionDialog extends Dialog {
+
+	protected Event<?> result;
+	protected Shell shell;
+	
+	private TabFolder tabFolder;
+	
+	List<AbstractInsertEventComposite> insertEventComposites;
+	SortedSet<String> targets;
+
+	/**
+	 * Create the dialog.
+	 * @param parent
+	 * @param style
+	 */
+	public InsertAssertionDialog(Shell parent, int style, SortedSet<String> targets) {
+		super(parent, style);
+		setText("SWT Dialog");
+		this.targets = targets;
+	}
+
+	/**
+	 * Open the dialog.
+	 * @return the result
+	 */
+	public Event<?> open() {
+		result = null;
+		insertEventComposites = new ArrayList<AbstractInsertEventComposite>();
+		createContents();
+		shell.open();
+		shell.layout();
+		Display display = getParent().getDisplay();
+		while (!shell.isDisposed()) {
+			if (!display.readAndDispatch()) {
+				display.sleep();
+			}
+		}
+		return result;
+	}
+
+	/**
+	 * Create contents of the dialog.
+	 */
+	private void createContents() {
+		shell = new Shell(getParent(), SWT.SHELL_TRIM | SWT.BORDER | SWT.APPLICATION_MODAL);
+		shell.setSize(450, 300);
+		shell.setText(getText());
+		shell.setLayout(new GridLayout(2, false));
+		
+		tabFolder = new TabFolder(shell, SWT.NONE);
+		tabFolder.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
+		
+		
+		TabItem tbtmTextEquals = new TabItem(tabFolder, SWT.NONE);
+		tbtmTextEquals.setText("TextEquals");
+		AbstractInsertEventComposite compTextEquals = new InsertTextEquals(tabFolder, SWT.NO_BACKGROUND, targets);
+		tbtmTextEquals.setControl(compTextEquals);
+		insertEventComposites.add(compTextEquals);
+		
+		TabItem tbtmFileEquals = new TabItem(tabFolder, SWT.NONE);
+		tbtmFileEquals.setText("FileEquals");
+		AbstractInsertEventComposite compFileEquals = new InsertFileEquals(tabFolder, SWT.NO_BACKGROUND, targets);
+		tbtmFileEquals.setControl(compFileEquals);
+		insertEventComposites.add(compFileEquals);
+		
+		Button btnInsert = new Button(shell, SWT.NONE);
+		btnInsert.setText("Insert");
+		btnInsert.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				int index = tabFolder.getSelectionIndex();
+				result = insertEventComposites.get(index).getEvent();
+				shell.dispose();
+			}
+		});
+		
+		Button btnAbort = new Button(shell, SWT.NONE);
+		btnAbort.setText("Abort");
+		btnAbort.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				shell.dispose();
+			}
+		});
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/InsertFileEquals.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/InsertFileEquals.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/InsertFileEquals.java	(revision 540)
@@ -0,0 +1,83 @@
+package de.ugoe.cs.quest.ui.swt;
+
+import java.util.SortedSet;
+
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+
+import de.ugoe.cs.quest.assertions.AssertEvent;
+import de.ugoe.cs.quest.assertions.FileEqualsReplay;
+import de.ugoe.cs.quest.eventcore.Event;
+
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+
+public class InsertFileEquals extends AbstractInsertEventComposite {
+	private Text actualText;
+	private Text expectedText;
+
+	public InsertFileEquals(Composite parent, int style) {
+		this(parent, style, null);
+	}
+	
+	/**
+	 * Create the composite.
+	 * @param parent
+	 * @param style
+	 */
+	public InsertFileEquals(Composite parent, int style, SortedSet<String> targets) {
+		super(parent, style, targets);
+		setLayout(new GridLayout(3, false));
+		
+				
+				Label lblExpectedFile = new Label(this, SWT.NONE);
+				lblExpectedFile.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
+				lblExpectedFile.setText("Expected file:");
+		
+		expectedText = new Text(this, SWT.BORDER);
+		expectedText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
+		
+		Button btnSearch = new Button(this, SWT.NONE);
+		btnSearch.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				FileDialog fileDialog = new FileDialog(getShell(), SWT.OPEN);
+				String filename = fileDialog.open();
+				if( filename!= null ) {
+					expectedText.setText(filename);
+				}
+			}
+		});
+		btnSearch.setText("Search...");
+		
+		Label lblActualFile = new Label(this, SWT.NONE);
+		
+		lblActualFile.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
+		lblActualFile.setText("Actual file:");
+		
+		actualText = new Text(this, SWT.BORDER);
+		actualText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
+		new Label(this, SWT.NONE);
+
+	}
+
+	@Override
+	protected void checkSubclass() {
+		// Disable the check that prevents subclassing of SWT components
+	}
+
+	@Override
+	public Event<?> getEvent() {
+		FileEqualsReplay replay = new FileEqualsReplay(expectedText.getText(), actualText.getText());
+		AssertEvent<FileEqualsReplay> event = new AssertEvent<FileEqualsReplay>("FileEqualsAssertion");
+		event.addReplayEvent(replay);
+		return event;
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/InsertTextEquals.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/InsertTextEquals.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/InsertTextEquals.java	(revision 540)
@@ -0,0 +1,156 @@
+package de.ugoe.cs.quest.ui.swt;
+
+import java.util.SortedSet;
+
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.TreeItem;
+
+import de.ugoe.cs.quest.assertions.AssertEvent;
+import de.ugoe.cs.quest.assertions.TextEqualsReplay;
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.util.ArrayTools;
+
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+
+public class InsertTextEquals extends AbstractInsertEventComposite {
+	private Text expectedText;
+	private Tree targetTree;
+	private Text targetText;
+	
+	/**
+	 * Create the composite.
+	 * @param parent
+	 * @param style
+	 */
+	public InsertTextEquals(Composite parent, int style, SortedSet<String> targets) {
+		super(parent, style, targets);
+		setLayout(new GridLayout(3, false));
+		
+		Label lblExpectedValue = new Label(this, SWT.NONE);
+		lblExpectedValue.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
+		lblExpectedValue.setText("Expected Value:");
+		
+		expectedText = new Text(this, SWT.BORDER);
+		expectedText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
+		
+		Label lblTargetWidget = new Label(this, SWT.NONE);
+		lblTargetWidget.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
+		lblTargetWidget.setText("Target Widget:");
+		
+		targetText = new Text(this, SWT.BORDER);
+		targetText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
+		new Label(this, SWT.NONE);
+		
+		targetTree = new Tree(this, SWT.BORDER);
+		targetTree.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				TreeItem[] selection = targetTree.getSelection();
+				if( selection.length==1 ) {
+					TreeItem item = selection[0];
+					String targetString = item.getText();
+					item = item.getParentItem();
+					while( item!=null ) {
+						// TODO the "." is hard coded for the JFCMonitor. should be flexible 
+						targetString = item.getText()+"."+targetString;
+						item = item.getParentItem();
+					}
+					targetText.setText(targetString);
+				}
+			}
+		});
+		targetTree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
+		buildTargetTree();
+		new Label(this, SWT.NONE);
+		
+		Button btnExpandAll = new Button(this, SWT.NONE);
+		btnExpandAll.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				expandAll(targetTree, true);
+			}
+		});
+		btnExpandAll.setText("Expand all");
+		
+		Button btnCollapseAll = new Button(this, SWT.NONE);
+		btnCollapseAll.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				expandAll(targetTree, false);
+			}
+		});
+		btnCollapseAll.setText("Collapse all");
+
+	}
+
+	@Override
+	protected void checkSubclass() {
+		// Disable the check that prevents subclassing of SWT components
+	}
+
+	@Override
+	public Event<?> getEvent() {		
+		String target = targetText.getText();
+		TextEqualsReplay replay = new TextEqualsReplay(expectedText.getText(), target);
+		AssertEvent<TextEqualsReplay> event = new AssertEvent<TextEqualsReplay>("TextEqualsAssertion");
+		event.setTarget(target);
+		event.addReplayEvent(replay);
+		return event;
+	}
+	
+	private void buildTargetTree() {
+		for( String target : targets ) {
+			TreeItem currentParent = null;
+			TreeItem[] currentItems = targetTree.getItems();
+			
+			//TODO needs rule for target splitting. currently its hard coded for JFCEvent targets.
+			String[] targetParts = target.split("\\.\\[");
+			for( String targetPart : targetParts) {
+				String[] currentTexts = new String[currentItems.length];
+				for( int i=0; i<currentItems.length ; i++ ) {
+					currentTexts[i] = currentItems[i].getText();
+				}
+				if( currentParent!=null ) {
+					targetPart = "["+targetPart;
+				}
+				int index = ArrayTools.findIndex(currentTexts, targetPart);
+				if( index>= 0 ) {
+					currentParent = currentItems[index];
+				} else {
+					if( currentParent==null ) {
+						currentParent = new TreeItem(targetTree, SWT.NULL);
+						currentParent.setText(targetPart);
+					} else {
+						currentParent = new TreeItem(currentParent, SWT.NULL);
+						currentParent.setText(targetPart);
+					}
+				}
+				currentItems = currentParent.getItems();
+			}
+		}
+
+	}
+	
+	private void expandAll(Tree tree, boolean expanded) {
+		for( TreeItem item : tree.getItems() ) {
+			expandAll(item, expanded);
+		}
+	}
+	
+	private void expandAll(TreeItem item, boolean expanded) {
+		item.setExpanded(expanded);
+		for( TreeItem childItem : item.getItems() ) {
+			expandAll(childItem, expanded);
+		}
+	}
+	
+	
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/MainWindow.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/MainWindow.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/MainWindow.java	(revision 540)
@@ -0,0 +1,237 @@
+package de.ugoe.cs.quest.ui.swt;
+
+import java.util.List;
+
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.TabItem;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+
+import de.ugoe.cs.util.console.CommandExecuter;
+
+/**
+ * <p>
+ * Main window of the SWT GUI.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class MainWindow {
+	
+	private List<String> startupCommands;
+
+	protected Shell shlEventbenchConsole;
+
+	protected TabItem consoleTab;
+	protected TabItem sequencesTab;
+	protected TabItem modelsTab;
+	protected TabItem dataTab;
+	protected ConsoleTabComposite consoleTabComposite;
+	protected SequencesTabComposite sequencesTabComposite;
+	protected ModelsTabComposite modelsTabComposite;
+	protected DataTabComposite dataTabComposite;
+
+	protected CommandHistoryDialog historyDialog;
+
+	public MainWindow(List<String> startupCommands) {
+		this.startupCommands = startupCommands;
+	}
+	
+	/**
+	 * <p>
+	 * Open the window.
+	 * </p>
+	 * 
+	 * @wbp.parser.entryPoint
+	 */
+	public void open() {
+		Display display = Display.getDefault();
+		createContents();
+		new SWTConsole(consoleTabComposite.textConsoleOutput);
+		historyDialog = new CommandHistoryDialog(shlEventbenchConsole, SWT.NONE);
+		shlEventbenchConsole.open();
+		shlEventbenchConsole.layout();
+		for(String command : startupCommands ) {
+			CommandExecuter.getInstance().exec(command);
+		}
+		while (!shlEventbenchConsole.isDisposed()) {
+			if (!display.readAndDispatch()) {
+				display.sleep();
+			}
+		}
+	}
+
+	/**
+	 * <p>
+	 * Create contents of the window.
+	 * </p>
+	 */
+	protected void createContents() {
+		shlEventbenchConsole = new Shell();
+		shlEventbenchConsole.setSize(800, 600);
+		shlEventbenchConsole.setText("EventBench Console");
+		shlEventbenchConsole.setLayout(new GridLayout(1, false));
+
+		createMenu();
+		createTabs();
+	}
+
+	/**
+	 * </p> Creates the menu of the window. </p>
+	 */
+	private void createMenu() {
+		Menu menu = new Menu(shlEventbenchConsole, SWT.BAR);
+		shlEventbenchConsole.setMenuBar(menu);
+
+		MenuItem mntmFile = new MenuItem(menu, SWT.CASCADE);
+		mntmFile.setText("File");
+
+		Menu menu_1 = new Menu(mntmFile);
+		mntmFile.setMenu(menu_1);
+
+		MenuItem mntmShowHistory = new MenuItem(menu_1, SWT.NONE);
+		mntmShowHistory.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				if (!historyDialog.isOpen()) {
+					historyDialog.open();
+				}
+			}
+		});
+		mntmShowHistory.setText("Show History");
+
+		MenuItem mntmExecBatchFile = new MenuItem(menu_1, SWT.NONE);
+		mntmExecBatchFile.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				FileDialog fileDialog = new FileDialog(shlEventbenchConsole,
+						SWT.OPEN);
+				String filename = fileDialog.open();
+				if (filename != null) {
+					String command = "exec '" + filename + "'";
+					CommandExecuter.getInstance().exec(command);
+				}
+			}
+		});
+		mntmExecBatchFile.setText("Exec. Batch File");
+
+		new MenuItem(menu_1, SWT.SEPARATOR);
+
+		MenuItem mntmLoad = new MenuItem(menu_1, SWT.NONE);
+		mntmLoad.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				FileDialog fileDialog = new FileDialog(shlEventbenchConsole,
+						SWT.OPEN);
+				String filename = fileDialog.open();
+				if (filename != null) {
+					String command = "load '" + filename + "'";
+					CommandExecuter.getInstance().exec(command);
+				}
+			}
+		});
+		mntmLoad.setText("Load...");
+
+		MenuItem mntmSave = new MenuItem(menu_1, SWT.NONE);
+		mntmSave.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				FileDialog fileDialog = new FileDialog(shlEventbenchConsole,
+						SWT.SAVE);
+				String filename = fileDialog.open();
+				if (filename != null) {
+					String command = "save '" + filename + "'";
+					CommandExecuter.getInstance().exec(command);
+				}
+			}
+		});
+		mntmSave.setText("Save...");
+
+		new MenuItem(menu_1, SWT.SEPARATOR);
+
+		MenuItem mntmExit = new MenuItem(menu_1, SWT.NONE);
+		mntmExit.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				shlEventbenchConsole.dispose();
+			}
+		});
+		mntmExit.setText("Exit");
+
+		MenuItem mntmHelp = new MenuItem(menu, SWT.CASCADE);
+		mntmHelp.setText("Help");
+
+		Menu menu_2 = new Menu(mntmHelp);
+		mntmHelp.setMenu(menu_2);
+
+		MenuItem mntmAbout = new MenuItem(menu_2, SWT.NONE);
+		mntmAbout.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				AboutDialog aboutDialog = new AboutDialog(shlEventbenchConsole,
+						SWT.NONE);
+				aboutDialog.open();
+			}
+		});
+		mntmAbout.setText("About");
+	}
+
+	/**
+	 * <p>
+	 * Creates the central TabFolder of the window.
+	 * </p>
+	 */
+	private void createTabs() {
+		TabFolder tabFolder = new TabFolder(shlEventbenchConsole, SWT.NONE);
+		tabFolder.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				if (e.item == sequencesTab) {
+					sequencesTabComposite.updateSequenceList();
+				} else if (e.item == modelsTab) {
+					modelsTabComposite.updateModelList();
+				} else if (e.item == dataTab) {
+					dataTabComposite.updateDataList();
+				}
+			}
+		});
+		tabFolder.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1,
+				1));
+
+		consoleTab = new TabItem(tabFolder, SWT.NONE);
+		consoleTab.setText("Console");
+
+		consoleTabComposite = new ConsoleTabComposite(tabFolder,
+				SWT.NO_BACKGROUND);
+		consoleTab.setControl(consoleTabComposite);
+
+		sequencesTab = new TabItem(tabFolder, SWT.NONE);
+		sequencesTab.setText("Sequences");
+
+		sequencesTabComposite = new SequencesTabComposite(tabFolder,
+				SWT.NO_BACKGROUND);
+		sequencesTab.setControl(sequencesTabComposite);
+
+		modelsTab = new TabItem(tabFolder, SWT.NONE);
+		modelsTab.setText("Models");
+
+		modelsTabComposite = new ModelsTabComposite(tabFolder,
+				SWT.NO_BACKGROUND);
+		modelsTab.setControl(modelsTabComposite);
+
+		dataTab = new TabItem(tabFolder, SWT.NONE);
+		dataTab.setText("Data");
+
+		dataTabComposite = new DataTabComposite(tabFolder, SWT.NO_BACKGROUND);
+		dataTab.setControl(dataTabComposite);
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/ModelPropertiesDialog.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/ModelPropertiesDialog.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/ModelPropertiesDialog.java	(revision 540)
@@ -0,0 +1,138 @@
+package de.ugoe.cs.quest.ui.swt;
+
+import org.eclipse.swt.widgets.Dialog;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.MessageBox;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.List;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.FillLayout;
+
+import de.ugoe.cs.quest.usageprofiles.FirstOrderMarkovModel;
+import de.ugoe.cs.quest.usageprofiles.IStochasticProcess;
+
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+
+public class ModelPropertiesDialog extends Dialog {
+
+	private IStochasticProcess process;
+	
+	protected Shell shlModelProperties;
+
+	/**
+	 * Create the dialog.
+	 * @param parent
+	 * @param style
+	 */
+	public ModelPropertiesDialog(Shell parent, int style) {
+		super(parent, style);
+		setText("SWT Dialog");
+	}
+
+	/**
+	 * Open the dialog.
+	 */
+	public void open() {
+		createContents();
+		shlModelProperties.open();
+		shlModelProperties.layout();
+		Display display = getParent().getDisplay();
+		while (!shlModelProperties.isDisposed()) {
+			if (!display.readAndDispatch()) {
+				display.sleep();
+			}
+		}
+	}
+
+	/**
+	 * Create contents of the dialog.
+	 */
+	private void createContents() {
+		shlModelProperties = new Shell(getParent(), SWT.DIALOG_TRIM | SWT.RESIZE);
+		shlModelProperties.setSize(230, 318);
+		shlModelProperties.setText("Model Properties");
+		shlModelProperties.setLayout(new GridLayout(2, false));
+		
+		Group grpEvents = new Group(shlModelProperties, SWT.NONE);
+		FillLayout fl_grpEvents = new FillLayout(SWT.HORIZONTAL);
+		fl_grpEvents.marginHeight = 5;
+		fl_grpEvents.marginWidth = 5;
+		grpEvents.setLayout(fl_grpEvents);
+		grpEvents.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
+		grpEvents.setText("Events");
+		
+		List list = new List(grpEvents, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
+		for( String symbol : process.getSymbolStrings() ) {
+			if( symbol==null ) {
+				list.add("null");
+			} else {
+				list.add(symbol);
+			}
+		}
+		
+		Group grpStatistics = new Group(shlModelProperties, SWT.NONE);
+		grpStatistics.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1));
+		grpStatistics.setText("Statistics");
+		grpStatistics.setLayout(new GridLayout(2, false));
+		
+		Label lblNumEvents = new Label(grpStatistics, SWT.NONE);
+		lblNumEvents.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 1, 1));
+		lblNumEvents.setText("Num. Events");
+		
+		Label label = new Label(grpStatistics, SWT.RIGHT);
+		label.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false, 1, 1));
+		label.setText(""+process.getNumSymbols());
+		
+		Label lblNumTrieLeafs = new Label(grpStatistics, SWT.NONE);
+		lblNumTrieLeafs.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 1, 1));
+		lblNumTrieLeafs.setText("Size (Flattend FOM)");
+		
+		Label label_1 = new Label(grpStatistics, SWT.RIGHT);
+		label_1.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false, 1, 1));
+		label_1.setText(""+process.getNumFOMStates());
+		
+		Label lblEntropy = new Label(grpStatistics, SWT.NONE);
+		lblEntropy.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 1, 1));
+		lblEntropy.setText("Entropy");
+		
+		final Label label_2 = new Label(grpStatistics, SWT.RIGHT);
+		label_2.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 1, 1));
+		label_2.setText("####");
+		
+		Button btnCalculateEntropy = new Button(shlModelProperties, SWT.NONE);
+		btnCalculateEntropy.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				if( process instanceof FirstOrderMarkovModel) {
+					label_2.setText(""+((FirstOrderMarkovModel) process).calcEntropy());
+				} else {
+					MessageBox messageBox = new MessageBox(shlModelProperties, SWT.NONE);
+					messageBox.setText("Feature Not Available");
+					messageBox.setMessage("The feature is currently only available for first-order Markov models.");
+					messageBox.open();
+				}
+			}
+		});
+		btnCalculateEntropy.setText("Calculate Entropy");
+		
+		Button btnClose = new Button(shlModelProperties, SWT.NONE);
+		btnClose.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				shlModelProperties.dispose();
+			}
+		});
+		btnClose.setText("Close");
+
+	}
+	
+	public void setStochasticProcess(IStochasticProcess process) {
+		this.process = process;
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/ModelsTabComposite.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/ModelsTabComposite.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/ModelsTabComposite.java	(revision 540)
@@ -0,0 +1,144 @@
+package de.ugoe.cs.quest.ui.swt;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.List;
+import org.eclipse.swt.widgets.MessageBox;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.layout.GridData;
+
+import de.ugoe.cs.quest.ui.GlobalDataContainer;
+import de.ugoe.cs.quest.usageprofiles.FirstOrderMarkovModel;
+import de.ugoe.cs.quest.usageprofiles.IDotCompatible;
+import de.ugoe.cs.quest.usageprofiles.IStochasticProcess;
+import de.ugoe.cs.util.console.CommandExecuter;
+
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+
+public class ModelsTabComposite extends Composite {
+
+	List modelList;
+	
+	/**
+	 * Create the composite.
+	 * @param parent
+	 * @param style
+	 */
+	public ModelsTabComposite(Composite parent, int style) {
+		super(parent, style);
+		createContents();
+	}
+	
+	private void createContents() {
+		setLayout(new GridLayout(5, false));
+		
+		modelList = new List(this, SWT.BORDER | SWT.V_SCROLL);
+		modelList.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 5, 1));
+		
+		Button btnShow = new Button(this, SWT.NONE);
+		btnShow.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				String[] selectedStrings = modelList.getSelection();
+				if( selectedStrings.length==0 ) {
+					SWTHelpers.noSelectionError(getShell());
+					return;
+				}
+				IStochasticProcess process = (IStochasticProcess) GlobalDataContainer.getInstance().getData(selectedStrings[0]);
+				if( process instanceof FirstOrderMarkovModel ) {
+					String command = "showMarkovModel " + selectedStrings[0];
+					CommandExecuter.getInstance().exec(command);
+				} else {
+					MessageBox messageBox = new MessageBox(getShell(), SWT.NONE);
+					messageBox.setText("Feature Not Available");
+					messageBox.setMessage("The feature is currently only available for first-order Markov models.");
+					messageBox.open();
+				}
+			}
+		});
+		btnShow.setText("Visualize");
+		
+		Button btnDelete_1 = new Button(this, SWT.NONE);
+		btnDelete_1.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				if( SWTHelpers.deleteSelectedFromStorage(modelList) ) {
+					updateModelList();
+				} else {
+					SWTHelpers.noSelectionError(getShell());
+				}
+			}
+		});
+		btnDelete_1.setText("Delete");
+		
+		Button btnGenSequences = new Button(this, SWT.NONE);
+		btnGenSequences.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				String[] selectedStrings = modelList.getSelection();
+				if( selectedStrings.length==0 ) {
+					SWTHelpers.noSelectionError(getShell());
+					return;
+				}
+				GenerateSequencesDialog generateSequencesDialog = new GenerateSequencesDialog(getShell(), SWT.NONE);
+				generateSequencesDialog.setProcessName(selectedStrings[0]);
+				generateSequencesDialog.open();
+			}
+		});
+		btnGenSequences.setText("Gen. Sequences");
+		
+		Button btnProperties = new Button(this, SWT.NONE);
+		btnProperties.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				String[] selectedStrings = modelList.getSelection();
+				if( selectedStrings.length==0 ) {
+					SWTHelpers.noSelectionError(getShell());
+					return;
+				}
+				IStochasticProcess process = (IStochasticProcess) GlobalDataContainer.getInstance().getData(selectedStrings[0]);
+				ModelPropertiesDialog modelPropertiesDialog = new ModelPropertiesDialog(getShell(), SWT.NONE);
+				modelPropertiesDialog.setStochasticProcess(process);
+				modelPropertiesDialog.open();
+			}
+		});
+		btnProperties.setText("Properties");
+		
+		Button btnCreateDot = new Button(this, SWT.NONE);
+		btnCreateDot.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				String[] selectedStrings = modelList.getSelection();
+				if( selectedStrings.length==0 ) {
+					SWTHelpers.noSelectionError(getShell());
+					return;
+				}
+				IStochasticProcess process = (IStochasticProcess) GlobalDataContainer.getInstance().getData(selectedStrings[0]);
+				String command = "";
+				if( process instanceof IDotCompatible ) {
+					command = "printDot ";
+				} else {
+					command = "printTrieDot ";
+				}
+				command += selectedStrings[0];
+				CommandExecuter.getInstance().exec(command);
+			}
+		});
+		btnCreateDot.setText("Create DOT");
+	}
+
+	@Override
+	protected void checkSubclass() {
+		// Disable the check that prevents subclassing of SWT components
+	}
+	
+	public void updateModelList() {
+		modelList.removeAll();
+		for( String sequencesName : GlobalDataContainer.getInstance().getAllModelNames() ) {
+			modelList.add(sequencesName);
+		}
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/SWTConsole.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/SWTConsole.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/SWTConsole.java	(revision 540)
@@ -0,0 +1,54 @@
+package de.ugoe.cs.quest.ui.swt;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyleRange;
+import org.eclipse.swt.custom.StyledText;
+
+import de.ugoe.cs.util.StringTools;
+import de.ugoe.cs.util.console.Console;
+import de.ugoe.cs.util.console.listener.ICommandListener;
+import de.ugoe.cs.util.console.listener.IErrorListener;
+import de.ugoe.cs.util.console.listener.IOutputListener;
+import de.ugoe.cs.util.console.listener.ITraceListener;
+
+public class SWTConsole implements IOutputListener, IErrorListener, ITraceListener, ICommandListener {
+
+	StyledText output;
+	
+	public SWTConsole(StyledText styledText) {
+		Console.getInstance().registerOutputListener(this);
+		Console.getInstance().registerErrorListener(this);
+		Console.getInstance().registerTraceListener(this);
+		Console.getInstance().registerCommandListener(this);
+		this.output = styledText;
+	}
+	
+	@Override
+	public void outputMsg(String newMessage) {
+		output.append(newMessage);
+	}
+
+	@Override
+	public void errorMsg(String errMessage) {
+		appendColored(errMessage, SWT.COLOR_RED);
+	}
+
+	@Override
+	public void traceMsg(String traceMessage) {
+		appendColored(traceMessage, SWT.COLOR_BLUE);
+	}
+	
+	@Override
+	public void commandNotification(String command) {
+		output.append("> " + command + StringTools.ENDLINE);	
+	}
+	
+	private void appendColored(String str, int id) {
+		StyleRange styleRange = new StyleRange();
+		styleRange.start = output.getText().length();
+		styleRange.length = str.length();
+		styleRange.foreground = output.getDisplay().getSystemColor(id);
+		output.append(str);
+		output.setStyleRange(styleRange);
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/SWTHelpers.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/SWTHelpers.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/SWTHelpers.java	(revision 540)
@@ -0,0 +1,32 @@
+package de.ugoe.cs.quest.ui.swt;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.List;
+import org.eclipse.swt.widgets.MessageBox;
+import org.eclipse.swt.widgets.Shell;
+
+import de.ugoe.cs.util.console.CommandExecuter;
+
+public class SWTHelpers {
+	
+	public static boolean deleteSelectedFromStorage(final List list) {
+		String[] selectedStrings = list.getSelection();
+		if( selectedStrings.length==0 ) {
+			return false;
+		} else {
+			for( String selected : selectedStrings) {
+				String command = "deleteObject " + selected;
+				CommandExecuter.getInstance().exec(command);
+			}
+			return true;
+		}
+	}
+	
+	public static void noSelectionError(final Shell shell) {
+		MessageBox messageBox = new MessageBox(shell, SWT.ERROR);
+		messageBox.setMessage("No objects selected!");
+		messageBox.setText("Error");
+		messageBox.open();
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/SequencesDialog.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/SequencesDialog.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/SequencesDialog.java	(revision 540)
@@ -0,0 +1,154 @@
+package de.ugoe.cs.quest.ui.swt;
+
+import java.util.Collection;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.eclipse.swt.widgets.Dialog;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.MessageBox;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.List;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.layout.GridData;
+
+import de.ugoe.cs.quest.SequenceInstanceOf;
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.ui.GlobalDataContainer;
+
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+
+public class SequencesDialog extends Dialog {
+
+	private String sequencesName;
+	
+	private List sequenceList;
+	private Collection<java.util.List<Event<?>>> sequences;
+	private SortedSet<String> targets;
+	
+	protected Shell shell;
+
+	/**
+	 * Create the dialog.
+	 * @param parent
+	 * @param style
+	 */
+	public SequencesDialog(Shell parent, int style) {
+		super(parent, style);
+		setText("SWT Dialog");
+	}
+
+	/**
+	 * Open the dialog.
+	 */
+	public void open(String sequencesName) {
+		this.sequencesName = sequencesName;
+		sequences = null;
+		createContents();
+		shell.open();
+		shell.layout();
+		Display display = getParent().getDisplay();
+		while (!shell.isDisposed()) {
+			if (!display.readAndDispatch()) {
+				display.sleep();
+			}
+		}
+	}
+
+	/**
+	 * Create contents of the dialog.
+	 */
+	private void createContents() {
+		shell = new Shell(getParent(), SWT.SHELL_TRIM | SWT.BORDER | SWT.APPLICATION_MODAL);
+		shell.setSize(248, 299);
+		shell.setText(getText());
+		shell.setLayout(new GridLayout(2, false));
+		
+		sequenceList = new List(shell, SWT.BORDER | SWT.V_SCROLL);
+		sequenceList.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
+		updateSequenceList();
+		
+		Button btnShow = new Button(shell, SWT.NONE);
+		btnShow.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				int index = sequenceList.getSelectionIndex();
+				if( index==-1 ) {
+					MessageBox messageBox = new MessageBox(shell, SWT.ERROR);
+					messageBox.setMessage("No sequence selected!");
+					messageBox.setText("Error");
+					messageBox.open();
+				} else {
+					EditSequenceDialog editSequenceDialog = new EditSequenceDialog(shell, SWT.NONE, targets);
+					int counter = 0;
+					java.util.List<Event<?>> selectedSequence = null;
+					for( java.util.List<Event<?>> sequence : sequences ) {
+						if( counter==index ) {
+							selectedSequence = sequence;
+							break;
+						}
+						counter++;
+					}
+					editSequenceDialog.open(selectedSequence);
+					updateSequenceList();
+				}
+			}
+		});
+		btnShow.setText("Show");
+		
+		Button btnClose = new Button(shell, SWT.NONE);
+		btnClose.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				shell.dispose();
+			}
+		});
+		btnClose.setText("Close");
+
+	}
+	
+	@SuppressWarnings("unchecked")
+	private void updateSequenceList() {
+		sequenceList.removeAll();
+		Object dataObject = GlobalDataContainer.getInstance().getData(sequencesName);
+		if( SequenceInstanceOf.isCollectionOfSequences(dataObject)) {
+			sequences = (Collection<java.util.List<Event<?>>>) dataObject;
+			int seqDigits = Integer.toString(sequences.size()).length();
+			int counter = 1;
+			for( java.util.List<Event<?>> sequence : sequences ) {
+				String seqName = "#"+String.format("%0"+seqDigits+"d", counter)+": "+sequence.size();
+				sequenceList.add(seqName);
+				counter++;
+			}
+			Object targetObject = GlobalDataContainer.getInstance().getData(sequencesName+"_targets");
+			targets = null;
+			if( targetObject instanceof SortedSet ) {
+				if( !((SortedSet<?>) targetObject).isEmpty() ) {
+					if( ((SortedSet<?>) targetObject).first() instanceof String ) {
+						targets = (SortedSet<String>) targetObject;
+					}
+				}
+			}
+			if( targets==null ) {
+				targets = new TreeSet<String>();
+				for( java.util.List<Event<?>> sequence : sequences ) {
+					for( Event<?> event : sequence ) {
+						String target = event.getTarget();
+						if( target!=null ) {
+							targets.add(target);
+						}
+					}
+				}
+			}
+		} else {
+			MessageBox messageBox = new MessageBox(shell, SWT.ERROR);
+			messageBox.setMessage("Internal error. Sequences object not of expected type!");
+			messageBox.setText("Error");
+			messageBox.open();
+		}
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/SequencesTabComposite.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/SequencesTabComposite.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/SequencesTabComposite.java	(revision 540)
@@ -0,0 +1,137 @@
+package de.ugoe.cs.quest.ui.swt;
+
+import org.eclipse.swt.widgets.Composite;
+
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.List;
+import org.eclipse.swt.widgets.MessageBox;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+
+import de.ugoe.cs.quest.ui.GlobalDataContainer;
+import de.ugoe.cs.util.console.CommandExecuter;
+
+public class SequencesTabComposite extends Composite {
+	
+	protected List sequenceList;
+	
+	/**
+	 * Create the composite.
+	 * @param parent
+	 * @param style
+	 */
+	public SequencesTabComposite(Composite parent, int style) {
+		super(parent, style);
+		createContents();
+	}
+
+	private void createContents() {
+		setLayout(new GridLayout(5, false));
+		
+		sequenceList = new List(this, SWT.BORDER | SWT.V_SCROLL | SWT.MULTI);
+		sequenceList.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 5, 1));
+		sequenceList.setItems(new String[] {});
+		
+		Button btnEdit = new Button(this, SWT.NONE);
+		btnEdit.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				String[] selectedSequences = sequenceList.getSelection();
+				if( selectedSequences.length==0 ) {
+					SWTHelpers.noSelectionError(getShell());
+				} 
+				else if(selectedSequences.length>1) {
+					MessageBox messageBox = new MessageBox(getShell(), SWT.ERROR);
+					messageBox.setMessage("Only one sequence can be edited at a time!");
+					messageBox.setText("Error");
+					messageBox.open();
+				} else {
+					SequencesDialog sequencesDialog = new SequencesDialog(getShell(), SWT.NONE);
+					sequencesDialog.open(selectedSequences[0]);
+				}
+			}
+		});
+		btnEdit.setText("Edit");
+		
+		Button btnDelete = new Button(this, SWT.NONE);
+		btnDelete.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				if( SWTHelpers.deleteSelectedFromStorage(sequenceList)) {
+					updateSequenceList();
+				} else {
+					SWTHelpers.noSelectionError(getShell());
+				}
+			}
+		});
+		btnDelete.setText("Delete");
+		
+		Button btnReplay = new Button(this, SWT.NONE);
+		btnReplay.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				String[] selectedSequences = sequenceList.getSelection();
+				if( selectedSequences.length==0 ) {
+					SWTHelpers.noSelectionError(getShell());
+				} else {
+					StringBuilder commandString = new StringBuilder("generateReplayfile ");
+					FileDialog fileDialog = new FileDialog(getShell());
+					String filename = fileDialog.open();
+					commandString.append(filename + " ");
+					for( String selected : selectedSequences ) {
+						commandString.append(selected + " ");
+					}
+					CommandExecuter.getInstance().exec(commandString.toString().trim());
+				}
+			}
+		});
+		btnReplay.setText("Replay");
+		
+		Button btnTrainModel = new Button(this, SWT.NONE);
+		btnTrainModel.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				String[] selectedSequences = sequenceList.getSelection();
+				if( selectedSequences.length==0 ) {
+					SWTHelpers.noSelectionError(getShell());
+				} else {
+					TrainModelDialog trainDialog = new TrainModelDialog(getShell(), SWT.NONE);
+					trainDialog.setSequenceNames(selectedSequences);
+					trainDialog.open();
+				}
+			}
+		});
+		btnTrainModel.setText("Train Model");
+		
+		Button btnParse = new Button(this, SWT.NONE);
+		btnParse.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				// TODO implement parsing of sequences
+				MessageBox messageBox = new MessageBox(getShell(), SWT.ICON_INFORMATION);
+				messageBox.setText("Not implemented!");
+				messageBox.setMessage("Sorry! This functionality has not been implemented yet!");
+				messageBox.open();
+			}
+		});
+		btnParse.setText("Parse");
+	}
+	
+	public void updateSequenceList() {
+		sequenceList.removeAll();
+		for( String sequencesName : GlobalDataContainer.getInstance().getAllSequencesNames() ) {
+			sequenceList.add(sequencesName);
+		}
+	}
+	
+	@Override
+	protected void checkSubclass() {
+		// Disable the check that prevents subclassing of SWT components
+	}
+
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/TrainModelDialog.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/TrainModelDialog.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/TrainModelDialog.java	(revision 540)
@@ -0,0 +1,230 @@
+package de.ugoe.cs.quest.ui.swt;
+
+import java.util.Arrays;
+
+import org.eclipse.swt.widgets.Dialog;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.MessageBox;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.widgets.Spinner;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+
+import de.ugoe.cs.util.console.CommandExecuter;
+
+public class TrainModelDialog extends Dialog {
+
+	protected Shell shlTrainUsageModel;
+	
+	private Button btnFirstorderMarkovModel;
+	private Button btnHighorderMarkovModel;
+	private Button btnPredictionByPartial;
+	private Button btnDeterministicFiniteAutomaton;
+	
+	private Spinner minOrderSpinner;
+	private Spinner maxOrderSpinner;
+	private Text modelnameText;
+	
+	private String[] sequenceNames;
+	private Text probEscapeText;
+	private Label lblEscapeProbability;
+
+	/**
+	 * Create the dialog.
+	 * @param parent
+	 * @param style
+	 */
+	public TrainModelDialog(Shell parent, int style) {
+		super(parent, style);
+		setText("SWT Dialog");
+	}
+
+	/**
+	 * Open the dialog.
+	 */
+	public void open() {
+		createContents();
+		shlTrainUsageModel.open();
+		shlTrainUsageModel.layout();
+		Display display = getParent().getDisplay();
+		while (!shlTrainUsageModel.isDisposed()) {
+			if (!display.readAndDispatch()) {
+				display.sleep();
+			}
+		}
+	}
+
+	/**
+	 * Create contents of the dialog.
+	 */
+	private void createContents() {
+		shlTrainUsageModel = new Shell(getParent(), SWT.DIALOG_TRIM | SWT.MIN | SWT.APPLICATION_MODAL);
+		shlTrainUsageModel.setSize(219, 330);
+		shlTrainUsageModel.setText("Train Usage Model");
+		shlTrainUsageModel.setLayout(new GridLayout(2, false));
+		
+		Group grpGeneralInformation = new Group(shlTrainUsageModel, SWT.NONE);
+		grpGeneralInformation.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 2, 1));
+		grpGeneralInformation.setText("Name");
+		grpGeneralInformation.setLayout(new GridLayout(1, false));
+		
+		modelnameText = new Text(grpGeneralInformation, SWT.BORDER);
+		modelnameText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1));
+		
+		Group grpType = new Group(shlTrainUsageModel, SWT.NONE);
+		grpType.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 2, 1));
+		grpType.setText("Type");
+		grpType.setLayout(new GridLayout(2, false));
+		
+		btnFirstorderMarkovModel = new Button(grpType, SWT.RADIO);
+		btnFirstorderMarkovModel.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				minOrderSpinner.setEnabled(false);
+				maxOrderSpinner.setEnabled(false);
+				probEscapeText.setEnabled(false);
+			}
+		});
+		btnFirstorderMarkovModel.setLayoutData(new GridData(SWT.LEFT, SWT.FILL, false, false, 2, 1));
+		btnFirstorderMarkovModel.setText("First-Order Markov Model");
+		btnFirstorderMarkovModel.setSelection(true);
+		
+		btnHighorderMarkovModel = new Button(grpType, SWT.RADIO);
+		btnHighorderMarkovModel.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				minOrderSpinner.setEnabled(false);
+				maxOrderSpinner.setEnabled(true);
+				probEscapeText.setEnabled(false);
+			}
+		});
+		btnHighorderMarkovModel.setLayoutData(new GridData(SWT.LEFT, SWT.FILL, false, false, 2, 1));
+		btnHighorderMarkovModel.setText("High-Order Markov Model");
+		
+		btnPredictionByPartial = new Button(grpType, SWT.RADIO);
+		btnPredictionByPartial.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				minOrderSpinner.setEnabled(true);
+				maxOrderSpinner.setEnabled(true);
+				probEscapeText.setEnabled(true);
+			}
+		});
+		btnPredictionByPartial.setLayoutData(new GridData(SWT.LEFT, SWT.FILL, true, false, 2, 1));
+		btnPredictionByPartial.setText("Prediction by Partial Match");
+		
+		lblEscapeProbability = new Label(grpType, SWT.NONE);
+		lblEscapeProbability.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, true, false, 1, 1));
+		lblEscapeProbability.setText("Escape Probability:");
+		
+		probEscapeText = new Text(grpType, SWT.BORDER);
+		probEscapeText.setText("0.1");
+		probEscapeText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
+		probEscapeText.setEnabled(false);
+		
+		btnDeterministicFiniteAutomaton = new Button(grpType, SWT.RADIO);
+		btnDeterministicFiniteAutomaton.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				minOrderSpinner.setEnabled(false);
+				maxOrderSpinner.setEnabled(false);
+				probEscapeText.setEnabled(false);
+			}
+		});
+		btnDeterministicFiniteAutomaton.setLayoutData(new GridData(SWT.LEFT, SWT.FILL, false, false, 2, 1));
+		btnDeterministicFiniteAutomaton.setText("Deterministic Finite Automaton");
+		
+		Group grpModelProperties = new Group(shlTrainUsageModel, SWT.NONE);
+		grpModelProperties.setLayout(new GridLayout(4, false));
+		grpModelProperties.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true, 2, 1));
+		grpModelProperties.setText("Order");
+		
+		Label lblMin = new Label(grpModelProperties, SWT.NONE);
+		lblMin.setText("Min.");
+		
+		minOrderSpinner = new Spinner(grpModelProperties, SWT.BORDER);
+		minOrderSpinner.setEnabled(false);
+		
+		Label lblMax = new Label(grpModelProperties, SWT.NONE);
+		lblMax.setText("Max.");
+		
+		maxOrderSpinner = new Spinner(grpModelProperties, SWT.BORDER);
+		maxOrderSpinner.setEnabled(false);
+		maxOrderSpinner.setMinimum(2);
+		
+		Button btnTrain = new Button(shlTrainUsageModel, SWT.NONE);
+		btnTrain.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				String command = "";
+				String modelname = modelnameText.getText();
+				if( modelname.equals("")) {
+					MessageBox messageBox = new MessageBox(shlTrainUsageModel, SWT.ERROR);
+					messageBox.setText("Error");
+					messageBox.setMessage("No modelname defined!");
+					messageBox.open();
+					return;
+				}
+				if( btnFirstorderMarkovModel.getSelection() ) {
+					command = "trainMarkovModel " + modelname + " " + sequenceNames[0];
+					
+				}
+				else if( btnHighorderMarkovModel.getSelection() ) {
+					int modelOrder = maxOrderSpinner.getSelection();
+					command = "trainMarkovModel " + modelname + " " + sequenceNames[0] + " " + modelOrder;
+				}
+				else if( btnPredictionByPartial.getSelection() ) {
+					int minOrder = minOrderSpinner.getSelection();
+					int maxOrder = maxOrderSpinner.getSelection();
+					if( minOrder>maxOrder ) {
+						MessageBox messageBox = new MessageBox(shlTrainUsageModel, SWT.ERROR);
+						messageBox.setText("Error");
+						messageBox.setMessage("Min. Order must be smaller than or equal to max. order!");
+						messageBox.open();
+						return;
+					}
+					double probEscape = Double.parseDouble(probEscapeText.getText());
+					if( probEscape<0.0 || probEscape>1.0) {
+						MessageBox messageBox = new MessageBox(shlTrainUsageModel, SWT.ERROR);
+						messageBox.setText("Error");
+						messageBox.setMessage("Escape probability must be in [0,1]!");
+						messageBox.open();
+						return;
+					}
+					command = "trainPPM " + modelname + " " + sequenceNames[0] + " " + probEscape + " " + maxOrder + " " + minOrder;
+				}
+				else if( btnDeterministicFiniteAutomaton.getSelection() ) {
+					command = "trainDFA " + modelname + " " + sequenceNames[0];
+				}
+				CommandExecuter.getInstance().exec(command);
+				for( int i=1; i<sequenceNames.length; i++ ) {
+					command = "updateModel " + sequenceNames[i];
+					CommandExecuter.getInstance().exec(command);
+				}
+				shlTrainUsageModel.dispose();
+			}
+		});
+		btnTrain.setText("Train!");
+		
+		Button btnAbort = new Button(shlTrainUsageModel, SWT.NONE);
+		btnAbort.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				shlTrainUsageModel.dispose();
+			}
+		});
+		btnAbort.setText("Abort");
+
+	}
+	
+	public void setSequenceNames(String[] sequenceNames) {
+		this.sequenceNames = Arrays.copyOf(sequenceNames, sequenceNames.length);
+	}
+}
Index: /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/commands/CMDshowSequences.java
===================================================================
--- /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/commands/CMDshowSequences.java	(revision 540)
+++ /tags/quest-pre-eventrefactoring/quest-ui-swt/src/main/java/de/ugoe/cs/quest/ui/swt/commands/CMDshowSequences.java	(revision 540)
@@ -0,0 +1,69 @@
+package de.ugoe.cs.quest.ui.swt.commands;
+
+import java.security.InvalidParameterException;
+import java.util.List;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Shell;
+
+import de.ugoe.cs.quest.CommandHelpers;
+import de.ugoe.cs.quest.SequenceInstanceOf;
+import de.ugoe.cs.quest.ui.GlobalDataContainer;
+import de.ugoe.cs.quest.ui.swt.SequencesDialog;
+import de.ugoe.cs.util.console.Command;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * Command to show sequences.
+ * </p>
+ * 
+ * @author Jeffrey Hall, Steffen Herbold
+ */
+public class CMDshowSequences implements Command {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#help()
+	 */
+	@Override
+	public void help() {
+		Console.println("Usage: showSequences <sequencesName>");
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.util.console.Command#run(java.util.List)
+	 */
+	@Override
+	public void run(List<Object> parameters) {
+		String sequencesName;
+		try {
+			sequencesName = (String) parameters.get(0);
+		} catch (Exception e) {
+			throw new InvalidParameterException();
+		}
+
+		Object dataObject = GlobalDataContainer.getInstance().getData(
+				sequencesName);
+		if (dataObject == null) {
+			CommandHelpers.objectNotFoundMessage(sequencesName);
+			return;
+		}
+		if (!SequenceInstanceOf.isCollectionOfSequences(dataObject)) {
+			CommandHelpers.objectNotType(sequencesName,
+					"Collection<List<Event<?>>>");
+			return;
+		}
+
+		Shell shell = new Shell(SWT.NONE);
+		shell.open();
+		shell.layout();
+		shell.setSize(0, 0);
+		SequencesDialog sequencesDialog = new SequencesDialog(shell, SWT.NONE);
+		sequencesDialog.open(sequencesName);
+		shell.dispose();
+	}
+}
