Index: trunk/autoquest-plugin-html/src/main/java/de/ugoe/cs/autoquest/plugin/html/HTMLLogQueryDeleter.java
===================================================================
--- trunk/autoquest-plugin-html/src/main/java/de/ugoe/cs/autoquest/plugin/html/HTMLLogQueryDeleter.java	(revision 2125)
+++ trunk/autoquest-plugin-html/src/main/java/de/ugoe/cs/autoquest/plugin/html/HTMLLogQueryDeleter.java	(revision 2125)
@@ -0,0 +1,229 @@
+//   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.html;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
+import java.util.Map;
+
+import org.xml.sax.SAXException;
+
+import de.ugoe.cs.util.StringTools;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * deletes queries from URLs belonging to GUI elements contained in an HTML log file. For this, it
+ * parses a given file and dumps a replacement, in which all are removed.
+ * </p>
+ * 
+ * @author Patrick Harms
+ * @version 1.0
+ * 
+ */
+public class HTMLLogQueryDeleter extends AbstractDefaultLogParser {
+    
+    /**
+     * <p>
+     * The output writer into which the new variant of the log file without queries is written
+     * </p>
+     */
+    private PrintWriter outputWriter;
+
+    /**
+     * <p>
+     * called to delete queries in the given log file. The method reuses 
+     * {@link #deleteQueries(File)}.
+     * </p>
+     * 
+     * @param file the log file in which the queries shall be deleted
+     */
+    public void deleteQueries(String file) {
+        if (file == null) {
+            throw new IllegalArgumentException("file must not be null");
+        }
+
+        deleteQueries(new File(file));
+    }
+
+    /**
+     * <p>
+     * called to delete the queries in the given log file. The given file is read
+     * completely. All events are written to an output file as they are. All GUI elements are
+     * written to an output file as they are, as well, as long as they do not have a query
+     * parameter. If they have a query parameter, it is removed. Finally, the original log file is
+     * deleted and replaced by the adapted variant. Log files, which do not contain query parameters
+     * stay untouched.
+     * </p>
+     * 
+     * @param file the log file in which the query parameters shall be removed
+     */
+    public void deleteQueries(File file) {
+        if (file == null) {
+            throw new IllegalArgumentException("file must not be null");
+        }
+        
+        if (!file.exists()) {
+            throw new IllegalArgumentException("file must denote an existing file");
+        }
+        
+        if (!file.isFile()) {
+            throw new IllegalArgumentException("file must denote a file");
+        }
+        
+        File outFile = new File(file.getParentFile(), file.getName() + "_tmp");
+        boolean parsingFailed = false;
+        
+        try {
+            FileOutputStream fis = new FileOutputStream(outFile);
+            outputWriter = new PrintWriter(new OutputStreamWriter(fis, "UTF-8"));
+            outputWriter.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+            outputWriter.println("<session>");
+
+            try {
+                super.parseFile(file);
+            }
+            catch (SAXException e) {
+                parsingFailed = true;
+            }
+            
+            outputWriter.println("</session>");
+            outputWriter.flush();
+        }
+        catch (FileNotFoundException e) {
+            Console.printerrln("could not create adapted file " + outFile);
+        }
+        catch (UnsupportedEncodingException e) {
+            // this should never happen
+            e.printStackTrace();
+        }
+        finally {
+            if (outputWriter != null) {
+                outputWriter.close();
+                outputWriter = null;
+            }
+        }
+        
+        if (!parsingFailed && outFile.exists()) {
+            if (!file.delete()) {
+                Console.printerrln("could not delete adapted file " + file);
+            }
+            else if (!outFile.renameTo(file)) {
+                Console.printerrln
+                    ("could not rename adapted file to original file name " + file);
+            }            
+            else {
+                Console.println("removed queries from file " + file);
+            }
+        }
+        else {
+            if (!outFile.delete()) {
+                Console.printerrln("could not delete temporary file " + outFile);
+            }
+        }
+    }
+    
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.plugin.html.AbstractDefaultLogParser#parseFile(java.lang.String)
+     */
+    @Override
+    public void parseFile(String filename) {
+        throw new IllegalStateException("this method must not be called externally");
+    }
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.plugin.html.AbstractDefaultLogParser#parseFile(java.io.File)
+     */
+    @Override
+    public void parseFile(File file) {
+        throw new IllegalStateException("this method must not be called externally");
+    }
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.plugin.html.AbstractDefaultLogParser#handleGUIElement(String, Map)
+     */
+    @Override
+    protected boolean handleGUIElement(String id, Map<String, String> parameters)
+        throws SAXException
+    {
+        outputWriter.print("<component id=\"");
+        outputWriter.print(id);
+        outputWriter.println("\">");
+        
+        for (Map.Entry<String, String> param : parameters.entrySet()) {
+            if (!"query".equals(param.getKey())) {
+                dumpParam(param.getKey(), param.getValue());
+            }
+        }
+            
+        outputWriter.println("</component>");
+        
+        return true;
+    }
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.plugin.html.AbstractDefaultLogParser#handleEvent(String,Map)
+     */
+    @Override
+    protected boolean handleEvent(String type, Map<String, String> parameters) throws SAXException {
+        outputWriter.print("<event type=\"");
+        outputWriter.print(type);
+        outputWriter.println("\">");
+        
+        for (Map.Entry<String, String> param : parameters.entrySet()) {
+            dumpParam(param.getKey(), param.getValue());
+        }
+            
+        outputWriter.println("</event>");
+        
+        return true;
+    }
+
+    /**
+     * <p>
+     * dumps a parameter with the given name and value to the log file. The result is a
+     * tag named param with a name attribute and a value attribute. The value is transformed
+     * to a String if it is no String already. Furthermore, an XML entity replacement is performed
+     * if required.
+     * </p>
+     *
+     * @param name  the name of the parameter to be dumped
+     * @param value the value of the parameter to be dumped
+     */
+    private void dumpParam(String name, Object value) {
+        if (value == null) {
+            return;
+        }
+        
+        String val;
+        
+        if (value instanceof String) {
+            val = (String) value;
+        }
+        else {
+            val = String.valueOf(value);
+        }
+        
+        outputWriter.print(" <param name=\"");
+        outputWriter.print(name);
+        outputWriter.print("\" value=\"");
+        outputWriter.print(StringTools.xmlEntityReplacement(val));
+        outputWriter.println("\"/>");
+    }
+}
Index: trunk/autoquest-plugin-html/src/main/java/de/ugoe/cs/autoquest/plugin/html/HTMLLogTextInputPseudomizer.java
===================================================================
--- trunk/autoquest-plugin-html/src/main/java/de/ugoe/cs/autoquest/plugin/html/HTMLLogTextInputPseudomizer.java	(revision 2029)
+++ trunk/autoquest-plugin-html/src/main/java/de/ugoe/cs/autoquest/plugin/html/HTMLLogTextInputPseudomizer.java	(revision 2125)
@@ -234,5 +234,6 @@
             
             if ("tagname".equals(param.getKey())) {
-                if ("input_text".equals(param.getValue()) ||
+                if ("input_text".equals(param.getValue()) || "textarea".equals(param.getValue()) ||
+                    "input_password".equals(param.getValue()) ||
                     (pseudomizeSearchInputs && "input_search".equals(param.getValue())) ||
                     (pseudomizeFileInputs && "input_file".equals(param.getValue())))
@@ -253,47 +254,4 @@
     @Override
     protected boolean handleEvent(String type, Map<String, String> parameters) throws SAXException {
-        String timestampStr = parameters.get("timestamp");
-        
-        long timestamp = Long.MAX_VALUE;
-        
-        if (timestampStr != null) {
-            timestamp = Long.parseLong(timestampStr);
-        }
-        
-        EventEntry newEvent = new EventEntry(type, parameters, timestamp);
-        
-        int start = 0;
-        int end = sortedEvents.size();
-        int center = 0;
-        long centerTimestamp;
-        
-        while (start != end) {
-            center = start + ((end - start) / 2);
-            
-            if ((center != start) || (center != end)) {
-                centerTimestamp = sortedEvents.get(center).timestamp;
-            
-                if (centerTimestamp < newEvent.timestamp) {
-                    start = Math.max(center, start + 1);
-                }
-                else if (centerTimestamp > newEvent.timestamp) {
-                    end = Math.min(center, end - 1);
-                }
-                else {
-                    // add the event directly where the center is, as the timestamps of the center
-                    // and the new event are equal
-                    end = center;
-                    start = end;
-                    break;
-                }
-            }
-            else {
-                // add the event to the position denoted by the add index
-                break;
-            }
-        }
-        
-        sortedEvents.add(start, newEvent);
-        
         if ("onchange".equals(type)) {
             String targetId = parameters.get("target");
@@ -319,4 +277,6 @@
             }
         }
+        
+        sortedEvents.add(new EventEntry(type, parameters));
 
         return true;
@@ -377,21 +337,13 @@
          */
         private Map<String, String> parameters;
-        
+
         /**
          * <p>
-         * the timestamp of the event
+         * creates a new event entry with event type and parameters
          * </p>
          */
-        private long timestamp;
-
-        /**
-         * <p>
-         * creates a new event entry with event type, parameters and the timestamp
-         * </p>
-         */
-        private EventEntry(String type, Map<String, String> parameters, long timestamp) {
+        private EventEntry(String type, Map<String, String> parameters) {
             this.type = type;
             this.parameters = parameters;
-            this.timestamp = timestamp;
         }
         
Index: trunk/autoquest-plugin-html/src/main/java/de/ugoe/cs/autoquest/plugin/html/commands/CMDdeleteHTMLQueries.java
===================================================================
--- trunk/autoquest-plugin-html/src/main/java/de/ugoe/cs/autoquest/plugin/html/commands/CMDdeleteHTMLQueries.java	(revision 2125)
+++ trunk/autoquest-plugin-html/src/main/java/de/ugoe/cs/autoquest/plugin/html/commands/CMDdeleteHTMLQueries.java	(revision 2125)
@@ -0,0 +1,92 @@
+//   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.html.commands;
+
+import java.io.File;
+import java.util.List;
+
+import de.ugoe.cs.autoquest.plugin.html.HTMLLogQueryDeleter;
+import de.ugoe.cs.util.console.Command;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * removes all queries in URL paths from a set of HTML recordings. For this, the command traverses
+ * a given directory structure. In each directory it treats the contained files as HTML log files.
+ * It parses them, copies all GUI elements and events and but removes query paramters from those
+ * GUI elements that contain them. The result is a copy of each treated log file. The origins are
+ * deleted. The copies are named as the origins.
+ * </p>
+ * 
+ * @author Patrick Harms
+ * @version 1.0
+ */
+public class CMDdeleteHTMLQueries implements Command {
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.util.console.Command#run(java.util.List)
+     */
+    @Override
+    public void run(List<Object> parameters) {
+        String path;
+        
+        try {
+            path = (String) parameters.get(0);
+        }
+        catch (Exception e) {
+            throw new IllegalArgumentException("illegal parameters provided: " + e);
+        }
+
+        File directory = new File(path);
+        if (!directory.isDirectory()) {
+            Console.printerrln(path + " is not a directory");
+            return;
+        }
+
+        deleteHTMLQueriesInDirectory(directory);
+
+    }
+
+    /**
+     * <p>
+     * convenience method to traverse the directory structure
+     * </p>
+     * 
+     * @param directory the directory to be treated next
+     */
+    private void deleteHTMLQueriesInDirectory(File directory) {
+        if (directory.isDirectory()) {
+            File[] children = directory.listFiles();
+            
+            for (File child : children) {
+                deleteHTMLQueriesInDirectory(child);
+            }
+        }
+        else if (directory.isFile()) {
+            new HTMLLogQueryDeleter().deleteQueries(directory);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.ugoe.cs.util.console.Command#help()
+     */
+    @Override
+    public String help() {
+        return "deleteHTMLQueries <directory>";
+    }
+
+}
