Index: trunk/autoquest-plugin-genericevents/src/main/java/de/ugoe/cs/autoquest/plugin/genericevents/GenericEventLogParser.java
===================================================================
--- trunk/autoquest-plugin-genericevents/src/main/java/de/ugoe/cs/autoquest/plugin/genericevents/GenericEventLogParser.java	(revision 2153)
+++ trunk/autoquest-plugin-genericevents/src/main/java/de/ugoe/cs/autoquest/plugin/genericevents/GenericEventLogParser.java	(revision 2165)
@@ -15,5 +15,8 @@
 package de.ugoe.cs.autoquest.plugin.genericevents;
 
+import java.time.Duration;
+import java.util.GregorianCalendar;
 import java.util.Map;
+import java.util.Set;
 
 import org.xml.sax.SAXException;
@@ -39,4 +42,20 @@
 public class GenericEventLogParser extends AbstractDefaultLogParser {
     
+    /** types of events to be ignored */
+    private Set<String> ignoredEvents;
+    
+    
+    /**
+     * <p>
+     * used to provide the parser with a set of ignored event types.
+     * </p>
+     *
+     * @param ignoredEvents
+     */
+    public GenericEventLogParser(Set<String> ignoredEvents) {
+        super();
+        this.ignoredEvents = ignoredEvents;
+    }
+
     /* (non-Javadoc)
      * @see de.ugoe.cs.autoquest.plugin.html.AbstractDefaultLogParser#handleGUIElement(String, Map)
@@ -47,4 +66,12 @@
     {
         String parentId = parameters.get("parent");
+        
+        if (parentId != null) {
+            // check, if the parent is already in the tree
+            if (super.getTargetTree().find(parentId) == null) {
+                // element cannot yet be processed as parent is not existing yet
+                return false;
+            }
+        }
         
         GenericEventTargetSpec specification = new GenericEventTargetSpec(id, parameters);
@@ -66,5 +93,15 @@
     @Override
     protected boolean handleEvent(String type, Map<String, String> parameters) throws SAXException {
+        // ignore the event based on its type if requested
+        if (ignoredEvents.contains(type)) {
+            return true;
+        }
+        
         String targetId = parameters.get("targetId");
+        
+        // ignore the event based on type and target id if requested
+        if (ignoredEvents.contains(type + "." + targetId)) {
+            return true;
+        }
         
         if (targetId == null) {
@@ -82,5 +119,13 @@
         
             if (timestampStr != null) {
-                event.setTimestamp(Long.parseLong(timestampStr));
+                event.setTimestamp(determineTimestamp(timestampStr));
+            }
+            
+            for (Map.Entry<String, String> parameter : parameters.entrySet()) {
+                if (!"targetId".equals(parameter.getKey()) &&
+                    !"timestamp".equals(parameter.getKey()))
+                {
+                    event.setParameter(parameter.getKey(), parameter.getValue());
+                }
             }
         
@@ -92,3 +137,33 @@
     }
 
+    /**
+     * convenience method to align different timestamp formats
+     */
+    private long determineTimestamp(String timestampStr) {
+        long val = Long.parseLong(timestampStr);
+        
+        // We expect any recording to have taken place in years with at most 4 digits. Hence,
+        // divide the val until we reach such a year
+        long max = new GregorianCalendar(10000, 1, 1).getTimeInMillis();
+        
+        while (max < val) {
+            val /= 10; 
+        }
+        
+        // now, it can still be the case, that the base line is wrong. I.e., the remaining value
+        // may be milliseconds, but not starting from 1970, as we expect it, but starting from
+        // year 1 of the gregorian calendar. If this is the case, the date is still in the future.
+        // Hence, we substract the milliseconds between year 1 of the gregorian calendar and 1970.
+        // (We took these magic number, as they provide correct results. It's not fully clear,
+        //  why the January 1st 1970 does not work correctly but provides an offset of two days)
+        if (val > System.currentTimeMillis()) {
+            Duration duration = Duration.between(new GregorianCalendar(1, 1, 1).toInstant(),
+                                                 new GregorianCalendar(1969, 12, 30).toInstant());
+            
+            val -= duration.toMillis();
+        }
+        
+        return val;
+    }
+
 }
Index: trunk/autoquest-plugin-genericevents/src/main/java/de/ugoe/cs/autoquest/plugin/genericevents/GenericEventLogSplitter.java
===================================================================
--- trunk/autoquest-plugin-genericevents/src/main/java/de/ugoe/cs/autoquest/plugin/genericevents/GenericEventLogSplitter.java	(revision 2165)
+++ trunk/autoquest-plugin-genericevents/src/main/java/de/ugoe/cs/autoquest/plugin/genericevents/GenericEventLogSplitter.java	(revision 2165)
@@ -0,0 +1,317 @@
+//   Copyright 2015 Georg-August-Universität Göttingen, Germany
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+
+package de.ugoe.cs.autoquest.plugin.genericevents;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.io.FileUtils;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+import de.ugoe.cs.util.StringTools;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * TODO comment
+ * </p>
+ * 
+ * @author Patrick Harms
+ */
+public class GenericEventLogSplitter extends AbstractDefaultLogParser {
+
+    /** */
+    private Attributes sessionAttributes = null;
+    
+    /** */
+    private Map<String, Map<String, String>> targets = new HashMap<>();
+    
+    /** */
+    private List<Event> events = new LinkedList<>();
+    
+    /**
+     * 
+     */
+    public void splitLogFile(File file, File destinationFolder, long timediff)
+        throws SAXException, IOException
+    {
+        super.parseFile(file);
+        
+        List<List<Event>> splittedEvents = new LinkedList<>();
+        LinkedList<Event> currentList = new LinkedList<>();
+        splittedEvents.add(currentList);
+        
+        for (Event event : events) {
+            if ((currentList.size() > 0) &&
+                ((event.getTimestamp() - currentList.getLast().getTimestamp()) > timediff))
+            {
+                currentList = new LinkedList<>();
+                splittedEvents.add(currentList);
+            }
+            
+            currentList.add(event);
+        }
+        
+        if (splittedEvents.size() == 1) {
+            // simply copy the file
+            FileUtils.copyFileToDirectory(file, destinationFolder);
+        }
+        else {
+            Console.println("splitting " + file.getAbsolutePath());
+            
+            int index = 0;
+            for (List<Event> session : splittedEvents) {
+                PrintWriter out = null;
+                try {
+                    String fileName = file.getName().substring(0, file.getName().lastIndexOf('.')) +
+                        "_" + index++ + file.getName().substring(file.getName().lastIndexOf('.'));
+                    File destFile = new File(destinationFolder, fileName);
+                    Console.println("writing " + destFile.getAbsolutePath());
+                    
+                    FileOutputStream fis = new FileOutputStream(destFile);
+                    out = new PrintWriter(new OutputStreamWriter(fis, "UTF-8"));
+                    out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+                    out.print("<session");
+                    
+                    for (int i = 0; i < sessionAttributes.getLength(); i++) {
+                        out.print(' ');
+                        out.print(sessionAttributes.getLocalName(i));
+                        out.print("=\"");
+                        out.print(StringTools.xmlEntityReplacement(sessionAttributes.getValue(i)));
+                        out.print("\"");
+                    }
+                    
+                    out.println(">");
+                    
+                    Set<String> loggedTargets = new HashSet<>();
+                    for (Event event : session) {
+                        String targetId = event.getParameter("targetId");
+                        if (!loggedTargets.contains(targetId)) {
+                            logTarget(targetId, out);
+                            loggedTargets.add(targetId);
+                        }
+                        logEvent(event, out);
+                    }
+                    
+                    
+                    out.println("</session>");
+                }
+                finally {
+                    if (out != null) {
+                        out.close();
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * <p>
+     * TODO: comment
+     * </p>
+     *
+     * @param event
+     * @param out
+     */
+    private void logEvent(Event event, PrintWriter out) {
+        out.print("<event type=\"");
+        out.print(event.getType());
+        out.println("\">");
+        
+        for (Map.Entry<String, String> parameter : event.getParameters().entrySet()) {
+            logParam(parameter.getKey(), parameter.getValue(), out);
+        }
+        
+        out.println("</event>");
+    }
+
+    /**
+     * <p>
+     * TODO: comment
+     * </p>
+     *
+     * @param targetId
+     * @param out
+     */
+    private void logTarget(String targetId, PrintWriter out) {
+        Map<String, String> parameters = targets.get(targetId);
+        
+        if (parameters.containsKey("parent")) {
+            logTarget(parameters.get("parent"), out);
+        }
+        
+        out.print("<target id=\"");
+        out.print(targetId);
+        out.println("\">");
+    
+        for (Map.Entry<String, String> param : targets.get(targetId).entrySet()) {
+            logParam(param.getKey(), param.getValue(), out);
+        }
+    
+        out.println("</target>");
+    }
+
+    /**
+     * <p>
+     * TODO: comment
+     * </p>
+     *
+     * @param key
+     * @param value
+     * @param out
+     */
+    private void logParam(String key, String value, PrintWriter out) {
+        out.print(" <param name=\"");
+        out.print(key);
+        out.print("\" value=\"");
+        out.print(StringTools.xmlEntityReplacement(value));
+        out.println("\"/>");
+    }
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.plugin.genericevents.AbstractDefaultLogParser#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
+    {
+        super.startElement(uri, localName, qName, atts);
+        
+        if (qName.equals("session")) {
+            sessionAttributes = atts;
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.plugin.genericevents.AbstractDefaultLogParser#handleTarget(java.lang.String, java.util.Map)
+     */
+    @Override
+    protected boolean handleTarget(String id, Map<String, String> parameters) throws SAXException {
+        targets.put(id, parameters);
+        return true;
+    }
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.plugin.genericevents.AbstractDefaultLogParser#handleEvent(java.lang.String, java.util.Map)
+     */
+    @Override
+    protected boolean handleEvent(String type, Map<String, String> parameters) throws SAXException {
+        Event event = new Event(type, parameters);
+        
+        ListIterator<Event> iterator = events.listIterator();
+        boolean added = false;
+        
+        while (iterator.hasNext()) {
+            Event candidate = iterator.next();
+            if (candidate.getTimestamp() > event.getTimestamp()) {
+                iterator.previous();
+                iterator.add(event);
+                added = true;
+                break;
+            }
+        }
+        
+        if (!added) {
+            events.add(event);
+        }
+        
+        return true;
+    }
+
+    
+    /**
+     * <p>
+     * TODO comment
+     * </p>
+     * 
+     * @author Patrick Harms
+     */
+    public class Event {
+
+        private String type;
+        private Map<String, String> parameters;
+
+        /**
+         * <p>
+         * TODO: comment
+         * </p>
+         *
+         * @param type
+         * @param parameters
+         */
+        public Event(String type, Map<String, String> parameters) {
+            this.type = type;
+            this.parameters = parameters;
+        }
+
+        /**
+         * <p>
+         * TODO: comment
+         * </p>
+         *
+         * @return
+         */
+        public long getTimestamp() {
+            return Long.parseLong(parameters.get("timestamp"));
+        }
+
+        /**
+         * <p>
+         * TODO: comment
+         * </p>
+         *
+         * @return
+         */
+        public Map<String, String> getParameters() {
+            return parameters;
+        }
+
+        /**
+         * <p>
+         * TODO: comment
+         * </p>
+         *
+         * @return
+         */
+        public String getType() {
+            return type;
+        }
+
+        /**
+         * <p>
+         * TODO: comment
+         * </p>
+         *
+         * @param string
+         * @return
+         */
+        public String getParameter(String key) {
+            return parameters.get(key);
+        }
+
+    }
+    
+}
Index: trunk/autoquest-plugin-genericevents/src/main/java/de/ugoe/cs/autoquest/plugin/genericevents/commands/CMDparseDirGenericEvents.java
===================================================================
--- trunk/autoquest-plugin-genericevents/src/main/java/de/ugoe/cs/autoquest/plugin/genericevents/commands/CMDparseDirGenericEvents.java	(revision 2153)
+++ trunk/autoquest-plugin-genericevents/src/main/java/de/ugoe/cs/autoquest/plugin/genericevents/commands/CMDparseDirGenericEvents.java	(revision 2165)
@@ -18,5 +18,7 @@
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 import java.util.logging.Level;
 
@@ -50,5 +52,7 @@
         String path = null;
         String sequencesName = null;
-
+        
+        Set<String> ignoredEvents = new HashSet<>();
+        
         try {
             for (int i = 0; i < parameters.size(); i++) {
@@ -59,4 +63,7 @@
                 else if (sequencesName == null) {
                     sequencesName = param;
+                }
+                else {
+                    ignoredEvents.add(param);
                 }
             }
@@ -76,5 +83,5 @@
         }
 
-        GenericEventLogParser parser = new GenericEventLogParser();
+        GenericEventLogParser parser = new GenericEventLogParser(ignoredEvents);
 
         parseFile(folder, parser);
@@ -121,4 +128,5 @@
             catch (Exception e) {
                 Console.printerrln("Could not parse " + source + ": " + e.getMessage());
+                e.printStackTrace();
             }
         }
@@ -132,5 +140,5 @@
     @Override
     public String help() {
-        return "parseDirGenericEvents <directory> [<sequencesName>]";
+        return "parseDirGenericEvents <directory> [<sequencesName>] [<ignoredEventType>*] [<ignoredEventType.ignoredEventTargetId>*]";
     }
 
Index: trunk/autoquest-plugin-genericevents/src/main/java/de/ugoe/cs/autoquest/plugin/genericevents/commands/CMDparseGenericEvents.java
===================================================================
--- trunk/autoquest-plugin-genericevents/src/main/java/de/ugoe/cs/autoquest/plugin/genericevents/commands/CMDparseGenericEvents.java	(revision 2165)
+++ trunk/autoquest-plugin-genericevents/src/main/java/de/ugoe/cs/autoquest/plugin/genericevents/commands/CMDparseGenericEvents.java	(revision 2165)
@@ -0,0 +1,107 @@
+//   Copyright 2012 Georg-August-Universität Göttingen, Germany
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+
+package de.ugoe.cs.autoquest.plugin.genericevents.commands;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import de.ugoe.cs.autoquest.CommandHelpers;
+import de.ugoe.cs.autoquest.eventcore.Event;
+import de.ugoe.cs.autoquest.eventcore.IHierarchicalEventTargetModel;
+import de.ugoe.cs.autoquest.plugin.genericevents.GenericEventLogParser;
+import de.ugoe.cs.util.console.Command;
+import de.ugoe.cs.util.console.Console;
+import de.ugoe.cs.util.console.GlobalDataContainer;
+
+/**
+ * <p>
+ * Command to parse a file with sessions generated by the generic event monitor.
+ * </p>
+ * 
+ * @author Patrick Harms
+ * @version 1.0
+ */
+public class CMDparseGenericEvents implements Command {
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.ugoe.cs.util.console.Command#run(java.util.List)
+     */
+    @Override
+    public void run(List<Object> parameters) {
+        String filename = null;
+        String sequencesName = null;
+
+        Set<String> ignoredEvents = new HashSet<>();
+        
+        try {
+            for (int i = 0; i < parameters.size(); i++) {
+                String param = (String) parameters.get(i);
+                if (filename == null) {
+                    filename = param;
+                }
+                else if (sequencesName == null) {
+                    sequencesName = param;
+                }
+                else {
+                    ignoredEvents.add(param);
+                }
+            }
+        }
+        catch (Exception e) {
+            throw new IllegalArgumentException("illegal parameters provided: " + e);
+        }
+
+        if (sequencesName == null) {
+            sequencesName = "sequences";
+        }
+
+        GenericEventLogParser parser = new GenericEventLogParser(ignoredEvents);
+
+        try {
+            parser.parseFile(filename);
+        }
+        catch (Exception e) {
+            Console.printerrln("Could not parse " + filename + ": " + e.getMessage());
+            return;
+        }
+
+        Collection<List<Event>> sequences = parser.getSequences();
+
+        IHierarchicalEventTargetModel<?> targets = parser.getHierarchicalEventTargetModel();
+
+        if (GlobalDataContainer.getInstance().addData(sequencesName, sequences)) {
+            CommandHelpers.dataOverwritten(sequencesName);
+        }
+
+        if (GlobalDataContainer.getInstance().addData(sequencesName + "_targets", targets)) {
+            CommandHelpers.dataOverwritten(sequencesName + "_targets");
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.ugoe.cs.util.console.Command#help()
+     */
+    @Override
+    public String help() {
+        return "parseGenericEvents <filename> [<sequencesName>] [<ignoredEventType>*] [<ignoredEventType.ignoredEventTargetId>*]";
+    }
+
+}
Index: trunk/autoquest-plugin-genericevents/src/main/java/de/ugoe/cs/autoquest/plugin/genericevents/commands/CMDsplitDirGenericEvents.java
===================================================================
--- trunk/autoquest-plugin-genericevents/src/main/java/de/ugoe/cs/autoquest/plugin/genericevents/commands/CMDsplitDirGenericEvents.java	(revision 2165)
+++ trunk/autoquest-plugin-genericevents/src/main/java/de/ugoe/cs/autoquest/plugin/genericevents/commands/CMDsplitDirGenericEvents.java	(revision 2165)
@@ -0,0 +1,127 @@
+//   Copyright 2012 Georg-August-Universität Göttingen, Germany
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+
+package de.ugoe.cs.autoquest.plugin.genericevents.commands;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.List;
+import java.util.logging.Level;
+
+import de.ugoe.cs.autoquest.plugin.genericevents.GenericEventLogSplitter;
+import de.ugoe.cs.util.console.Command;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * TODO comment
+ * </p>
+ * 
+ * @author Patrick Harms
+ * @version 1.0
+ */
+public class CMDsplitDirGenericEvents implements Command {
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.ugoe.cs.util.console.Command#run(java.util.List)
+     */
+    @Override
+    public void run(List<Object> parameters) {
+        String source = null;
+        String dest = null;
+        long timediff = 0;
+        
+        try {
+            for (int i = 0; i < parameters.size(); i++) {
+                String param = (String) parameters.get(i);
+                if (source == null) {
+                    source = param;
+                }
+                else if (dest == null) {
+                    dest = param;
+                }
+                else {
+                    timediff = Long.parseLong(param);
+                }
+            }
+        }
+        catch (Exception e) {
+            throw new IllegalArgumentException("illegal parameters provided: " + e);
+        }
+
+        File sourceFolder = new File(source);
+        if (!sourceFolder.isDirectory()) {
+            Console.printerrln(sourceFolder + " is not a directory");
+            return;
+        }
+
+        File destFolder = new File(dest);
+        if (destFolder.exists() && !destFolder.isDirectory()) {
+            Console.printerrln(destFolder + " is not a directory");
+            return;
+        }
+        
+        if (sourceFolder.equals(destFolder)) {
+            Console.printerrln("source and destination must not be the same");
+            return;
+        }
+
+        splitFile(sourceFolder, destFolder, timediff);
+    }
+
+    /**
+     * <p>
+     * recursive method for parsing a directory structures
+     * </p>
+     *
+     * @param file   the file object to be parsed. If the file is a folder, the method calls itself
+     *               for all children
+     * @param parser the parser to use for parsing the files.
+     */
+    private void splitFile(File source, File dest, long timediff) {
+        if (source.isDirectory()) {
+            String[] children = source.list();
+            Arrays.sort(children);
+            
+            for (String child : children) {
+                File childFile = new File(source, child);
+                File childDestination = new File(dest, child);
+                splitFile(childFile, childDestination, timediff);
+            }
+        }
+        else if (source.isFile()) {
+            Console.traceln(Level.INFO, "Processing file: " + source.getAbsolutePath());
+
+            try {
+                new GenericEventLogSplitter().splitLogFile(source, dest.getParentFile(), timediff);
+            }
+            catch (Exception e) {
+                Console.printerrln("Could not split " + source.getAbsolutePath() + ": " + e.getMessage());
+            }
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.ugoe.cs.util.console.Command#help()
+     */
+    @Override
+    public String help() {
+        return "splitDirGenericEvents <directory>";
+    }
+
+}
