Index: /trunk/quest-plugin-mfc/data/ruleDoctype.dtd
===================================================================
--- /trunk/quest-plugin-mfc/data/ruleDoctype.dtd	(revision 581)
+++ /trunk/quest-plugin-mfc/data/ruleDoctype.dtd	(revision 581)
@@ -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: /trunk/quest-plugin-mfc/data/ruleSchema.xsd
===================================================================
--- /trunk/quest-plugin-mfc/data/ruleSchema.xsd	(revision 581)
+++ /trunk/quest-plugin-mfc/data/ruleSchema.xsd	(revision 581)
@@ -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: /trunk/quest-plugin-mfc/data/rules.xml
===================================================================
--- /trunk/quest-plugin-mfc/data/rules.xml	(revision 581)
+++ /trunk/quest-plugin-mfc/data/rules.xml	(revision 581)
@@ -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: /trunk/quest-plugin-mfc/pom.xml
===================================================================
--- /trunk/quest-plugin-mfc/pom.xml	(revision 580)
+++ /trunk/quest-plugin-mfc/pom.xml	(revision 581)
@@ -20,4 +20,29 @@
 			<version>0.0.1-SNAPSHOT</version>
 		</dependency>
+		<dependency>
+			<groupId>commons-codec</groupId>
+			<artifactId>commons-codec</artifactId>
+			<version>1.6</version>
+		</dependency>
+		<dependency>
+			<groupId>net.sourceforge.collections</groupId>
+			<artifactId>collections-generic</artifactId>
+			<version>4.01</version>
+		</dependency>
+		<dependency>
+			<groupId>jdom</groupId>
+			<artifactId>jdom</artifactId>
+			<version>1.1</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-ui-core</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+		</dependency>
 	</dependencies>
 	<build>
@@ -31,4 +56,22 @@
 				</configuration>
 			</plugin>
+			<plugin>
+				<artifactId>maven-assembly-plugin</artifactId>
+				<version>2.2-beta-2</version>
+				<configuration>
+					<descriptors>
+						<descriptor>src/main/assembly/config.xml</descriptor>
+					</descriptors>
+				</configuration>
+				<executions>
+					<execution>
+						<id>make-assembly</id>
+						<phase>package</phase>
+						<goals>
+							<goal>single</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
 		</plugins>
 	</build>
Index: /trunk/quest-plugin-mfc/src/main/assembly/config.xml
===================================================================
--- /trunk/quest-plugin-mfc/src/main/assembly/config.xml	(revision 581)
+++ /trunk/quest-plugin-mfc/src/main/assembly/config.xml	(revision 581)
@@ -0,0 +1,19 @@
+<assembly
+    xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
+  <id>config</id>
+  <formats>
+    <format>zip</format>
+  </formats>
+  <includeBaseDirectory>false</includeBaseDirectory>
+  <fileSets>
+    <fileSet>
+      <directory>data</directory>
+      <outputDirectory></outputDirectory>
+      <includes>
+        <include>*</include>
+      </includes>
+    </fileSet>
+  </fileSets>
+</assembly>
Index: /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/EventGenerator.java
===================================================================
--- /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/EventGenerator.java	(revision 581)
+++ /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/EventGenerator.java	(revision 581)
@@ -0,0 +1,1001 @@
+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.MFCEventTarget;
+import de.ugoe.cs.quest.plugin.mfc.eventcore.MFCEventType;
+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.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 Event currentToken;
+	
+	/**
+	 * <p>
+	 * Event type of the current token. Stored as a member to be able to update it during the parsing of the idinfo tag.
+	 * </p>
+	 */
+	private MFCEventType currentType;
+
+	/**
+	 * <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 "data/rules.xml" as default file for
+	 * the rules.
+	 * </p>
+	 */
+	public EventGenerator() {
+		rulesFile = "data/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 Event 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");
+			currentType = new MFCEventType(currentRuleName);
+			currentToken = new Event(currentType);
+			
+			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());
+							// TODO currentToken.invalidateReplay();
+						}
+					} else if (genMsgElement.getName().equals("genMsgSeq")) {
+						try {
+							generateReplaySequence(genMsgElement);
+							// TODO currentToken.invalidateReplay();
+						} catch (InvalidParameterException e) {
+							Console.printerrln(e.getMessage());
+							// TODO currentToken.invalidateReplay();
+						}
+					}
+				}
+				Element idinfoElement = currentRule.getChild("idinfo",
+						rulesNamespace);
+				if (idinfoElement != null) {
+					// cannot be empty if document is valid
+					List<Element> valueElements = idinfoElement.getChildren();
+					currentType.setInfo(getTermValue(null,
+							valueElements.get(0)));
+				}
+				Console.traceln(currentToken.getType().toString() + " 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(new MFCEventTarget(currentMessage
+							.getXmlWindowDescription()));
+					// TODO 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(new MFCEventTarget(currentMessage
+							.getXmlWindowDescription()));
+					// TODO 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 {
+			// TODO currentToken.invalidateReplay();
+		}
+		currentToken.addReplayable(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.addReplayableSequence(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: /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/HandlerCreate.java
===================================================================
--- /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/HandlerCreate.java	(revision 581)
+++ /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/HandlerCreate.java	(revision 581)
@@ -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: /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/HandlerDestroy.java
===================================================================
--- /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/HandlerDestroy.java	(revision 581)
+++ /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/HandlerDestroy.java	(revision 581)
@@ -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: /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/HandlerSetText.java
===================================================================
--- /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/HandlerSetText.java	(revision 581)
+++ /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/HandlerSetText.java	(revision 581)
@@ -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: /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/LogPreprocessor.java
===================================================================
--- /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/LogPreprocessor.java	(revision 581)
+++ /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/LogPreprocessor.java	(revision 581)
@@ -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: /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/MFCLogParser.java
===================================================================
--- /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/MFCLogParser.java	(revision 581)
+++ /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/MFCLogParser.java	(revision 581)
@@ -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.eventcore.Event;
+import de.ugoe.cs.quest.plugin.mfc.eventcore.WindowTree;
+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<Event>> 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<Event>>();
+		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<Event>> 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<Event> 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: /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/MFCReplayDecorator.java
===================================================================
--- /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/MFCReplayDecorator.java	(revision 581)
+++ /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/MFCReplayDecorator.java	(revision 581)
@@ -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: /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/MessageDefs.java
===================================================================
--- /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/MessageDefs.java	(revision 581)
+++ /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/MessageDefs.java	(revision 581)
@@ -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: /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/MessageHandler.java
===================================================================
--- /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/MessageHandler.java	(revision 581)
+++ /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/MessageHandler.java	(revision 581)
@@ -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: /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/SequenceSplitter.java
===================================================================
--- /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/SequenceSplitter.java	(revision 581)
+++ /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/SequenceSplitter.java	(revision 581)
@@ -0,0 +1,286 @@
+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.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<Event> 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<Event>();
+		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) {
+				Event 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<Event> 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() {
+		Event 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: /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/commands/CMDconvertDirToXml.java
===================================================================
--- /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/commands/CMDconvertDirToXml.java	(revision 581)
+++ /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/commands/CMDconvertDirToXml.java	(revision 581)
@@ -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: /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/commands/CMDconvertToXml.java
===================================================================
--- /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/commands/CMDconvertToXml.java	(revision 581)
+++ /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/commands/CMDconvertToXml.java	(revision 581)
@@ -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: /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/commands/CMDparseXML.java
===================================================================
--- /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/commands/CMDparseXML.java	(revision 581)
+++ /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/commands/CMDparseXML.java	(revision 581)
@@ -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.eventcore.Event;
+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.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<Event>> 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
+		Event dummyEvent = Event.STARTEVENT;
+		for (List<Event> sequence : sequences) {
+			for (Event 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: /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/eventcore/MFCEventTarget.java
===================================================================
--- /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/eventcore/MFCEventTarget.java	(revision 581)
+++ /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/eventcore/MFCEventTarget.java	(revision 581)
@@ -0,0 +1,46 @@
+
+package de.ugoe.cs.quest.plugin.mfc.eventcore;
+
+import de.ugoe.cs.quest.eventcore.IEventTarget;
+
+/**
+ * 
+ * <p>
+ * TODO comment
+ * </p>
+ * 
+ * @version $Revision: $ $Date: Aug 17, 2012$
+ * @author 2012, last modified by $Author: sherbold$
+ */
+public class MFCEventTarget implements IEventTarget {
+
+    /**  */
+    private static final long serialVersionUID = 1L;
+
+    private String targetString;
+
+    public MFCEventTarget(String targetString) {
+        this.targetString = targetString;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.ugoe.cs.quest.eventcore.IEventTarget#getPlatform()
+     */
+    @Override
+    public String getPlatform() {
+        return "MFC";
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        return targetString;
+    }
+
+}
Index: /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/eventcore/MFCEventType.java
===================================================================
--- /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/eventcore/MFCEventType.java	(revision 581)
+++ /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/eventcore/MFCEventType.java	(revision 581)
@@ -0,0 +1,55 @@
+
+package de.ugoe.cs.quest.plugin.mfc.eventcore;
+
+import de.ugoe.cs.quest.eventcore.IEventType;
+
+/**
+ * <p>
+ * TODO comment
+ * </p>
+ * 
+ * @version $Revision: $ $Date: Aug 17, 2012$
+ * @author 2012, last modified by $Author: sherbold$
+ */
+public class MFCEventType implements IEventType {
+
+    /**  */
+    private static final long serialVersionUID = 1L;
+
+    private final String typeString;
+    
+    private String info = null;
+
+    public MFCEventType(String typeString) {
+        this.typeString = typeString;
+    }
+    
+    public void setInfo(String info) {
+        this.info = info;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.ugoe.cs.quest.eventcore.IEventType#getName()
+     */
+    @Override
+    public String getName() {
+        return "MFCEventType";
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        String str = typeString;
+        if( info!=null ) {
+            str += "." + info;
+        }
+        return str;
+    }
+
+}
Index: /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/eventcore/MFCTargetComparator.java
===================================================================
--- /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/eventcore/MFCTargetComparator.java	(revision 581)
+++ /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/eventcore/MFCTargetComparator.java	(revision 581)
@@ -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: /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/eventcore/WindowTree.java
===================================================================
--- /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/eventcore/WindowTree.java	(revision 581)
+++ /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/eventcore/WindowTree.java	(revision 581)
@@ -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: /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/eventcore/WindowTreeNode.java
===================================================================
--- /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/eventcore/WindowTreeNode.java	(revision 581)
+++ /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/eventcore/WindowTreeNode.java	(revision 581)
@@ -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: /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/eventcore/WindowsEvent.java
===================================================================
--- /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/eventcore/WindowsEvent.java	(revision 581)
+++ /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/eventcore/WindowsEvent.java	(revision 581)
@@ -0,0 +1,88 @@
+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.Event;
+
+
+/**
+ * <p>
+ * Convenience class for working with Windows MFC events.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ * @deprecated This class is deprecated and only kept for now for documentation - some features still need to be extracted and reconstructed elsewhere
+ */
+public class WindowsEvent extends Event {
+
+	/**
+	 * <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(new MFCEventType("foo"));
+	}
+
+	//@Override
+	protected boolean targetEquals(String otherTarget) {
+		return MFCTargetComparator.compare(target.toString(), 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: /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/eventcore/WindowsMessage.java
===================================================================
--- /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/eventcore/WindowsMessage.java	(revision 581)
+++ /trunk/quest-plugin-mfc/src/main/java/de/ugoe/cs/quest/plugin/mfc/eventcore/WindowsMessage.java	(revision 581)
@@ -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.IReplayDecorator;
+import de.ugoe.cs.quest.eventcore.IReplayable;
+import de.ugoe.cs.quest.plugin.mfc.MFCReplayDecorator;
+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#getDecorator()
+     */
+    @Override
+    public IReplayDecorator getDecorator() {
+        return MFCReplayDecorator.getInstance();
+    }
+}
Index: /trunk/quest-runner/pom.xml
===================================================================
--- /trunk/quest-runner/pom.xml	(revision 580)
+++ /trunk/quest-runner/pom.xml	(revision 581)
@@ -141,5 +141,5 @@
               <artifactId>quest-plugin-guitar</artifactId>
               <version>0.0.1-SNAPSHOT</version>
-              <destination>${project.build.directory}/plugins/quest-plugin-guitar.jar</destination>
+              <destination>${project.build.directory}/plugins/quest-plugin-guitar-0.0.1.jar</destination>
             </configuration>
           </execution>
@@ -154,5 +154,5 @@
               <artifactId>quest-plugin-jfc</artifactId>
               <version>0.0.1-SNAPSHOT</version>
-              <destination>${project.build.directory}/plugins/quest-plugin-jfc.jar</destination>
+              <destination>${project.build.directory}/plugins/quest-plugin-jfc-0.0.1.jar</destination>
             </configuration>
           </execution>
@@ -167,5 +167,24 @@
               <artifactId>quest-plugin-mfc</artifactId>
               <version>0.0.1-SNAPSHOT</version>
-              <destination>${project.build.directory}/plugins/quest-plugin-mfc.jar</destination>
+              <destination>${project.build.directory}/plugins/quest-plugin-mfc-0.0.1.jar</destination>
+            </configuration>
+          </execution>
+          <execution>
+            <id>get-mfc-plugin-config</id>
+            <phase>process-classes</phase>
+            <goals>
+              <goal>unpack</goal>
+            </goals>
+            <configuration>
+              <artifactItems>
+                <artifactItem>
+                  <groupId>de.ugoe.cs.quest</groupId>
+                  <artifactId>quest-plugin-mfc</artifactId>
+                  <version>0.0.1-SNAPSHOT</version>
+                  <classifier>config</classifier>
+                  <type>zip</type>
+                  <outputDirectory>${project.build.directory}/data</outputDirectory>
+                </artifactItem>
+              </artifactItems>
             </configuration>
           </execution>
@@ -180,5 +199,5 @@
               <artifactId>quest-plugin-php</artifactId>
               <version>0.0.1-SNAPSHOT</version>
-              <destination>${project.build.directory}/plugins/quest-plugin-php.jar</destination>
+              <destination>${project.build.directory}/plugins/quest-plugin-php-0.0.1.jar</destination>
             </configuration>
           </execution>
Index: /trunk/quest-runner/src/main/assembly/bin.xml
===================================================================
--- /trunk/quest-runner/src/main/assembly/bin.xml	(revision 580)
+++ /trunk/quest-runner/src/main/assembly/bin.xml	(revision 581)
@@ -6,4 +6,5 @@
   <formats>
     <format>tar.gz</format>
+    <format>dir</format>
     <!-- format>tar.bz2</format>
     <format>zip</format-->
Index: /trunk/quest-runner/src/main/java/de/ugoe/cs/quest/ui/Runner.java
===================================================================
--- /trunk/quest-runner/src/main/java/de/ugoe/cs/quest/ui/Runner.java	(revision 580)
+++ /trunk/quest-runner/src/main/java/de/ugoe/cs/quest/ui/Runner.java	(revision 581)
@@ -1,2 +1,3 @@
+
 package de.ugoe.cs.quest.ui;
 
@@ -30,117 +31,103 @@
 public class Runner {
 
-	public enum UITYPE {
-		text, swt
-	};
+    public enum UITYPE {
+        text, swt
+    };
 
-	public enum LOG4JTYPE {
-		enable, disable
-	}
+    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) {
+    /**
+     * <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");
+        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;
-		}
-		
-		new java.util.Date().getDate();
+        // 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");
+         */
 
-		/*
-		 * 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); } }
-		 */
+        PluginLoader pluginLoader = new PluginLoader(new File("plugins"));
+        pluginLoader.load();
 
-		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);
+        for (QuestPlugin plugin : pluginLoader.getPlugins()) {
+            for (String commandPackage : plugin.getCommandPackages()) {
+                CommandExecuter.getInstance().addCommandPackage(commandPackage);
+            }
+        }
 
-		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");
-			}
+        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);
 
-			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.
-			}
-		}
-	}
+        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: /trunk/quest-ui-core/pom.xml
===================================================================
--- /trunk/quest-ui-core/pom.xml	(revision 580)
+++ /trunk/quest-ui-core/pom.xml	(revision 581)
@@ -65,14 +65,4 @@
     </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>
Index: unk/quest-ui-core/rules/ruleDoctype.dtd
===================================================================
--- /trunk/quest-ui-core/rules/ruleDoctype.dtd	(revision 580)
+++ 	(revision )
@@ -1,160 +1,0 @@
-<!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: unk/quest-ui-core/rules/ruleSchema.xsd
===================================================================
--- /trunk/quest-ui-core/rules/ruleSchema.xsd	(revision 580)
+++ 	(revision )
@@ -1,209 +1,0 @@
-﻿<?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: unk/quest-ui-core/rules/rules.xml
===================================================================
--- /trunk/quest-ui-core/rules/rules.xml	(revision 580)
+++ 	(revision )
@@ -1,1079 +1,0 @@
-<?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>
