Index: trunk/quest-core-events/src/main/java/de/ugoe/cs/quest/eventcore/gui/KeyInteractionCorrector.java
===================================================================
--- trunk/quest-core-events/src/main/java/de/ugoe/cs/quest/eventcore/gui/KeyInteractionCorrector.java	(revision 852)
+++ trunk/quest-core-events/src/main/java/de/ugoe/cs/quest/eventcore/gui/KeyInteractionCorrector.java	(revision 852)
@@ -0,0 +1,279 @@
+
+package de.ugoe.cs.quest.eventcore.gui;
+
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Set;
+import java.util.logging.Level;
+
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.tasktree.keyboardmaps.VirtualKey;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * This class provides the functionality to sort and clean up all key interactions in a log. In
+ * particular:
+ * <ol>
+ * <li>In case a combination key (e.g., shift, alt, control) is held down, multiple
+ * {@link KeyPressed} events are logged, even though only the first one is of importance. This class
+ * removes all {@link KeyPressed} events for combination keys except the first.</li>
+ * <li>In case a normal key is held down, multiple {@link KeyPressed} events are logged, but there
+ * is only one {@link KeyReleased} event. This class adds a {@link KeyReleased} event for all such
+ * {@link KeyPressed} events.</li>
+ * <li>Due to message filtering of applications, it is possible that a {@link KeyReleased} event
+ * without a preceding {@link KeyPressed} event is logged. This class either adds the missing
+ * {@link KeyPressed} right in front of the {@link KeyReleased} or removes the {@link KeyReleased}
+ * depending on the {@link #mode}.
+ * <li>As a result of steps 2-3, we have always a matching {@link KeyPressed}/{@link KeyReleased}
+ * pairs for all normal keys. This class replaces these pairs with a {@link KeyTyped} event at the
+ * position of the {@link KeyPressed} event.</li>
+ * <li>Sometimes combination keys are not released in the same order they have been pressed. This
+ * class ensures that the {@link KeyReleased} are in the opposite order of the {@link KeyPressed}
+ * events for all combination keys.</li>
+ * </ol>
+ * </p>
+ * 
+ * @version 1.0
+ * @author Steffen Herbold
+ */
+public class KeyInteractionCorrector {
+
+    /**
+     * <p>
+     * Describes the clean-up mode.
+     * </p>
+     * 
+     * @version 1.0
+     * @author Steffen Herbold
+     */
+    public static enum CleanupMode {
+        /**
+         * <p>
+         * Single {@link KeyReleased} are removed from the sequence.
+         * </p>
+         */
+        REMOVAL,
+
+        /**
+         * <p>
+         * {@link KeyPressed} events are added to single {@link KeyReleased} events
+         * </p>
+         */
+        ADDITION
+    };
+
+    /**
+     * <p>
+     * 
+     * </p>
+     */
+    private final CleanupMode mode;
+
+    /**
+     * <p>
+     * Constructor. Creates a new {@link KeyInteractionCorrector} with {@link #mode}=
+     * {@link CleanupMode#ADDITION}.
+     * </p>
+     */
+    public KeyInteractionCorrector() {
+        this(CleanupMode.ADDITION);
+    }
+
+    /**
+     * <p>
+     * Constructor. Creates a new {@link KeyInteractionCorrector}.
+     * </p>
+     * 
+     * @param mode
+     *            {@link #mode} of the instance
+     */
+    public KeyInteractionCorrector(CleanupMode mode) {
+        this.mode = mode;
+    }
+
+    /**
+     * <p>
+     * Sorts and cleans up key interactions according to the class specification (@see
+     * {@link KeyInteractionCorrector} class comment).
+     * </p>
+     * <p>
+     * This method returns a sorted copy of a sequence, the sequence itself is not changed.
+     * </p>
+     * 
+     * @param sequence
+     *            sequence which is sorted
+     * @return sorted copy of sequence
+     */
+    public List<Event> sortKeyInteractions(final List<Event> sequence) {
+        List<Event> sortedSequence = new LinkedList<Event>(sequence);
+
+        handleIncompleteKeyPairs(sortedSequence);
+        sortCombinationKeyPairs(sortedSequence);
+
+        return sortedSequence;
+    }
+
+    /**
+     * <p>
+     * Performs tasks 1-4 defined in the class description. Operations are performed in-place on the
+     * passed sequence.
+     * </p>
+     * 
+     * @param sequence
+     *            sequence which is sorted
+     */
+    private void sortCombinationKeyPairs(List<Event> sequence) {
+        LinkedList<VirtualKey> pressedCombinationKeys = new LinkedList<VirtualKey>();
+
+        for (int i = 0; i < sequence.size(); i++) {
+            Event event = sequence.get(i);
+            if (event.getType() instanceof KeyPressed) {
+                final VirtualKey key = ((KeyPressed) event.getType()).getKey();
+                if (key.isCombinationKey()) {
+                    pressedCombinationKeys.add(key);
+                }
+            }
+            if (event.getType() instanceof KeyReleased) {
+                final VirtualKey key = ((KeyReleased) event.getType()).getKey();
+                if (key.isCombinationKey()) {
+                    /*
+                     * if( pressedCombinationKeys.isEmpty() ) { Console.traceln(Level.INFO, "" + i);
+                     * for( int j=i-30 ; j<=i ; j++ ) { Console.traceln(Level.INFO,
+                     * sequence.get(i).toString()); } }
+                     */
+                    if (key.equals(pressedCombinationKeys.getLast())) {
+                        pressedCombinationKeys.removeLast();
+                    }
+                    else {
+                        // look-ahead to find new position
+                        int offset;
+                        for (offset = 1; offset + i < sequence.size(); offset++) {
+                            Event lookaheadEvent = sequence.get(i + offset);
+                            if (lookaheadEvent.getType() instanceof KeyReleased) {
+                                if (((KeyReleased) lookaheadEvent.getType()).getKey()
+                                    .equals(pressedCombinationKeys.getLast()))
+                                {
+                                    break;
+                                }
+                            }
+                        }
+                        sequence.add(i + offset + 1, event);
+                        sequence.remove(i);
+                        i--;
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * <p>
+     * Performs task 5 defined in the class description. Operations are performed in-place on the
+     * passed sequence.
+     * </p>
+     * 
+     * @param sequence
+     *            sequence which is sorted
+     */
+    private void handleIncompleteKeyPairs(List<Event> sequence) {
+        Set<VirtualKey> pressedKeys = new HashSet<VirtualKey>();
+        int firstPressedIndex = -1;
+
+        Set<VirtualKey> pressedCombinationKeysSession = new HashSet<VirtualKey>();
+
+        for (int i = 0; i < sequence.size(); i++) {
+            Event event = sequence.get(i);
+            if (event.getType() instanceof KeyboardFocusChange) {
+                if (firstPressedIndex != -1) {
+                    sequence.remove(i);
+                    sequence.add(firstPressedIndex, event);
+                }
+            }
+
+            if (event.getType() instanceof KeyPressed) {
+                if (pressedKeys.isEmpty()) {
+                    firstPressedIndex = i;
+                }
+                VirtualKey key = ((KeyPressed) event.getType()).getKey();
+                if (!key.isCombinationKey()) {
+                    ListIterator<Event> iter = sequence.listIterator(i);
+                    iter.next();
+                    iter.set(new Event(new KeyTyped(key), event.getTarget()));
+                }
+                else {
+                    pressedCombinationKeysSession.add(key);
+                    if (pressedKeys.contains(key)) {
+                        sequence.remove(i);
+                        i--;
+                    }
+                }
+                pressedKeys.add(key);
+            }
+            if (event.getType() instanceof KeyReleased) {
+                VirtualKey key = ((KeyReleased) event.getType()).getKey();
+                if (!key.isCombinationKey()) {
+                    if (pressedKeys.contains(key)) {
+                        sequence.remove(i);
+                        i--;
+                    }
+                    else {
+                        // found KeyReleased event without KeyPressed
+                        switch (mode)
+                        {
+                            case REMOVAL:
+                                sequence.remove(i);
+                                i--;
+                                break;
+                            case ADDITION:
+                                ListIterator<Event> iter = sequence.listIterator(i);
+                                iter.next();
+                                iter.set(new Event(new KeyTyped(key), event.getTarget()));
+                                break;
+                            default:
+                                throw new AssertionError(
+                                                         "reached source code that should be unreachable");
+                        }
+                    }
+                }
+                else {
+                    if (!pressedKeys.contains(key)) {
+                        if (pressedCombinationKeysSession.contains(key)) {
+                            Console.traceln(Level.SEVERE, "Found a " + key +
+                                " KeyReleased event without a KeyPressed event." +
+                                "The event will be dropped and the session is possibly faulty.");
+                            sequence.remove(i);
+                            i--;
+                        }
+                        else {
+                            Console
+                                .traceln(Level.SEVERE,
+                                         "Found a " +
+                                             key +
+                                             " KeyReleased event without a KeyPressed event." +
+                                             "Since no KeyPressed of key " +
+                                             key +
+                                             " has been part of the session " +
+                                             "till now, we assume that the key has been pressed since the beginning " +
+                                             "of the session and add a KeyPressed event for " +
+                                             key + " to the start " + "of the session.");
+                            sequence.add(0, new Event(new KeyPressed(key), event.getTarget()));
+                            i++;
+                        }
+                    }
+                }
+                pressedKeys.remove(key);
+                if (pressedKeys.isEmpty()) {
+                    firstPressedIndex = -1;
+                }
+            }
+        }
+        if (!pressedKeys.isEmpty()) {
+            Console
+                .traceln(Level.WARNING,
+                         "There was probably a failure during the handling of incomplete key event pairs.");
+        }
+    }
+}
Index: trunk/quest-core-events/src/main/java/de/ugoe/cs/quest/eventcore/gui/KeyInteractionSorter.java
===================================================================
--- trunk/quest-core-events/src/main/java/de/ugoe/cs/quest/eventcore/gui/KeyInteractionSorter.java	(revision 846)
+++ 	(revision )
@@ -1,279 +1,0 @@
-
-package de.ugoe.cs.quest.eventcore.gui;
-
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Set;
-import java.util.logging.Level;
-
-import de.ugoe.cs.quest.eventcore.Event;
-import de.ugoe.cs.tasktree.keyboardmaps.VirtualKey;
-import de.ugoe.cs.util.console.Console;
-
-/**
- * <p>
- * This class provides the functionality to sort and clean up all key interactions in a log. In
- * particular:
- * <ol>
- * <li>In case a combination key (e.g., shift, alt, control) is held down, multiple
- * {@link KeyPressed} events are logged, even though only the first one is of importance. This class
- * removes all {@link KeyPressed} events for combination keys except the first.</li>
- * <li>In case a normal key is held down, multiple {@link KeyPressed} events are logged, but there
- * is only one {@link KeyReleased} event. This class adds a {@link KeyReleased} event for all such
- * {@link KeyPressed} events.</li>
- * <li>Due to message filtering of applications, it is possible that a {@link KeyReleased} event
- * without a preceding {@link KeyPressed} event is logged. This class either adds the missing
- * {@link KeyPressed} right in front of the {@link KeyReleased} or removes the {@link KeyReleased}
- * depending on the {@link #mode}.
- * <li>As a result of steps 2-3, we have always a matching {@link KeyPressed}/{@link KeyReleased}
- * pairs for all normal keys. This class replaces these pairs with a {@link KeyTyped} event at the
- * position of the {@link KeyPressed} event.</li>
- * <li>Sometimes combination keys are not released in the same order they have been pressed. This
- * class ensures that the {@link KeyReleased} are in the opposite order of the {@link KeyPressed}
- * events for all combination keys.</li>
- * </ol>
- * </p>
- * 
- * @version 1.0
- * @author Steffen Herbold
- */
-public class KeyInteractionSorter {
-
-    /**
-     * <p>
-     * Describes the clean-up mode.
-     * </p>
-     * 
-     * @version 1.0
-     * @author Steffen Herbold
-     */
-    public static enum CleanupMode {
-        /**
-         * <p>
-         * Single {@link KeyReleased} are removed from the sequence.
-         * </p>
-         */
-        REMOVAL,
-
-        /**
-         * <p>
-         * {@link KeyPressed} events are added to single {@link KeyReleased} events
-         * </p>
-         */
-        ADDITION
-    };
-
-    /**
-     * <p>
-     * 
-     * </p>
-     */
-    private final CleanupMode mode;
-
-    /**
-     * <p>
-     * Constructor. Creates a new {@link KeyInteractionSorter} with {@link #mode}=
-     * {@link CleanupMode#ADDITION}.
-     * </p>
-     */
-    public KeyInteractionSorter() {
-        this(CleanupMode.ADDITION);
-    }
-
-    /**
-     * <p>
-     * Constructor. Creates a new {@link KeyInteractionSorter}.
-     * </p>
-     * 
-     * @param mode
-     *            {@link #mode} of the instance
-     */
-    public KeyInteractionSorter(CleanupMode mode) {
-        this.mode = mode;
-    }
-
-    /**
-     * <p>
-     * Sorts and cleans up key interactions according to the class specification (@see
-     * {@link KeyInteractionSorter} class comment).
-     * </p>
-     * <p>
-     * This method returns a sorted copy of a sequence, the sequence itself is not changed.
-     * </p>
-     * 
-     * @param sequence
-     *            sequence which is sorted
-     * @return sorted copy of sequence
-     */
-    public List<Event> sortKeyInteractions(final List<Event> sequence) {
-        List<Event> sortedSequence = new LinkedList<Event>(sequence);
-
-        handleIncompleteKeyPairs(sortedSequence);
-        sortCombinationKeyPairs(sortedSequence);
-
-        return sortedSequence;
-    }
-
-    /**
-     * <p>
-     * Performs tasks 1-4 defined in the class description. Operations are performed in-place on the
-     * passed sequence.
-     * </p>
-     * 
-     * @param sequence
-     *            sequence which is sorted
-     */
-    private void sortCombinationKeyPairs(List<Event> sequence) {
-        LinkedList<VirtualKey> pressedCombinationKeys = new LinkedList<VirtualKey>();
-
-        for (int i = 0; i < sequence.size(); i++) {
-            Event event = sequence.get(i);
-            if (event.getType() instanceof KeyPressed) {
-                final VirtualKey key = ((KeyPressed) event.getType()).getKey();
-                if (key.isCombinationKey()) {
-                    pressedCombinationKeys.add(key);
-                }
-            }
-            if (event.getType() instanceof KeyReleased) {
-                final VirtualKey key = ((KeyReleased) event.getType()).getKey();
-                if (key.isCombinationKey()) {
-                    /*
-                     * if( pressedCombinationKeys.isEmpty() ) { Console.traceln(Level.INFO, "" + i);
-                     * for( int j=i-30 ; j<=i ; j++ ) { Console.traceln(Level.INFO,
-                     * sequence.get(i).toString()); } }
-                     */
-                    if (key.equals(pressedCombinationKeys.getLast())) {
-                        pressedCombinationKeys.removeLast();
-                    }
-                    else {
-                        // look-ahead to find new position
-                        int offset;
-                        for (offset = 1; offset + i < sequence.size(); offset++) {
-                            Event lookaheadEvent = sequence.get(i + offset);
-                            if (lookaheadEvent.getType() instanceof KeyReleased) {
-                                if (((KeyReleased) lookaheadEvent.getType()).getKey()
-                                    .equals(pressedCombinationKeys.getLast()))
-                                {
-                                    break;
-                                }
-                            }
-                        }
-                        sequence.add(i + offset + 1, event);
-                        sequence.remove(i);
-                        i--;
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * <p>
-     * Performs task 5 defined in the class description. Operations are performed in-place on the
-     * passed sequence.
-     * </p>
-     * 
-     * @param sequence
-     *            sequence which is sorted
-     */
-    private void handleIncompleteKeyPairs(List<Event> sequence) {
-        Set<VirtualKey> pressedKeys = new HashSet<VirtualKey>();
-        int firstPressedIndex = -1;
-
-        Set<VirtualKey> pressedCombinationKeysSession = new HashSet<VirtualKey>();
-
-        for (int i = 0; i < sequence.size(); i++) {
-            Event event = sequence.get(i);
-            if (event.getType() instanceof KeyboardFocusChange) {
-                if (firstPressedIndex != -1) {
-                    sequence.remove(i);
-                    sequence.add(firstPressedIndex, event);
-                }
-            }
-
-            if (event.getType() instanceof KeyPressed) {
-                if (pressedKeys.isEmpty()) {
-                    firstPressedIndex = i;
-                }
-                VirtualKey key = ((KeyPressed) event.getType()).getKey();
-                if (!key.isCombinationKey()) {
-                    ListIterator<Event> iter = sequence.listIterator(i);
-                    iter.next();
-                    iter.set(new Event(new KeyTyped(key), event.getTarget()));
-                }
-                else {
-                    pressedCombinationKeysSession.add(key);
-                    if (pressedKeys.contains(key)) {
-                        sequence.remove(i);
-                        i--;
-                    }
-                }
-                pressedKeys.add(key);
-            }
-            if (event.getType() instanceof KeyReleased) {
-                VirtualKey key = ((KeyReleased) event.getType()).getKey();
-                if (!key.isCombinationKey()) {
-                    if (pressedKeys.contains(key)) {
-                        sequence.remove(i);
-                        i--;
-                    }
-                    else {
-                        // found KeyReleased event without KeyPressed
-                        switch (mode)
-                        {
-                            case REMOVAL:
-                                sequence.remove(i);
-                                i--;
-                                break;
-                            case ADDITION:
-                                ListIterator<Event> iter = sequence.listIterator(i);
-                                iter.next();
-                                iter.set(new Event(new KeyTyped(key), event.getTarget()));
-                                break;
-                            default:
-                                throw new AssertionError(
-                                                         "reached source code that should be unreachable");
-                        }
-                    }
-                }
-                else {
-                    if (!pressedKeys.contains(key)) {
-                        if (pressedCombinationKeysSession.contains(key)) {
-                            Console.traceln(Level.SEVERE, "Found a " + key +
-                                " KeyReleased event without a KeyPressed event." +
-                                "The event will be dropped and the session is possibly faulty.");
-                            sequence.remove(i);
-                            i--;
-                        }
-                        else {
-                            Console
-                                .traceln(Level.SEVERE,
-                                         "Found a " +
-                                             key +
-                                             " KeyReleased event without a KeyPressed event." +
-                                             "Since no KeyPressed of key " +
-                                             key +
-                                             " has been part of the session " +
-                                             "till now, we assume that the key has been pressed since the beginning " +
-                                             "of the session and add a KeyPressed event for " +
-                                             key + " to the start " + "of the session.");
-                            sequence.add(0, new Event(new KeyPressed(key), event.getTarget()));
-                            i++;
-                        }
-                    }
-                }
-                pressedKeys.remove(key);
-                if (pressedKeys.isEmpty()) {
-                    firstPressedIndex = -1;
-                }
-            }
-        }
-        if (!pressedKeys.isEmpty()) {
-            Console
-                .traceln(Level.WARNING,
-                         "There was probably a failure during the handling of incomplete key event pairs.");
-        }
-    }
-}
