Index: /trunk/autoquest-plugin-http-test/src/test/java/de/ugoe/cs/autoquest/http/SOAPUtilsTest.java
===================================================================
--- /trunk/autoquest-plugin-http-test/src/test/java/de/ugoe/cs/autoquest/http/SOAPUtilsTest.java	(revision 2002)
+++ /trunk/autoquest-plugin-http-test/src/test/java/de/ugoe/cs/autoquest/http/SOAPUtilsTest.java	(revision 2003)
@@ -20,13 +20,20 @@
 import java.util.Collection;
 import java.util.Iterator;
+import java.util.LinkedList;
 import java.util.List;
-
+import java.util.logging.Level;
+
+import org.junit.BeforeClass;
 import org.junit.Test;
 
 import de.ugoe.cs.autoquest.eventcore.Event;
+import de.ugoe.cs.autoquest.eventcore.EventUtils;
 import de.ugoe.cs.autoquest.plugin.http.HTTPLogParser;
 import de.ugoe.cs.autoquest.plugin.http.SOAPUtils;
 import de.ugoe.cs.autoquest.plugin.http.eventcore.SOAPEventType;
 import de.ugoe.cs.autoquest.plugin.http.eventcore.SimpleSOAPEventType;
+import de.ugoe.cs.autoquest.plugin.http.eventcore.SimpleSOAPEventType.CallType;
+import de.ugoe.cs.util.console.Console;
+import de.ugoe.cs.util.console.TextConsole;
 
 /**
@@ -38,4 +45,9 @@
  */
 public class SOAPUtilsTest {
+    
+    @BeforeClass
+    public static void setupBeforeClass() {
+        new TextConsole(Level.FINEST);
+    }
 
     @Test
@@ -82,6 +94,158 @@
             }
         }
-
-    }
-
+    }
+    
+    @Test
+    public void testDropInvalidResponseRequestPairs_1() throws Exception {
+        List<Event> sequence = new LinkedList<Event>();
+        sequence.add(new Event(new SimpleSOAPEventType("op1", "foo", "bar", null, null, CallType.REQUEST)));
+        sequence.add(new Event(new SimpleSOAPEventType("op1", "foo", "bar", null, null, CallType.RESPONSE)));
+        sequence.add(new Event(new SimpleSOAPEventType("op1", "foo", "bar", null, null, CallType.REQUEST)));
+        sequence.add(new Event(new SimpleSOAPEventType("op2", "foo", "bar", null, null, CallType.REQUEST)));
+        sequence.add(new Event(new SimpleSOAPEventType("op2", "foo", "bar", null, null, CallType.RESPONSE)));
+        sequence.add(new Event(new SimpleSOAPEventType("op1", "foo", "bar", null, null, CallType.RESPONSE)));
+        
+        List<Event> expectedSequence = new LinkedList<>(sequence);
+        
+        List<Event> originalSequence = new LinkedList<>(sequence);
+        
+        List<Event> validSequence = SOAPUtils.dropInvalidResponseRequestPairs(sequence);
+        Console.traceln(Level.INFO, getCurrentMethodName());
+        EventUtils.traceSequence(Level.INFO, validSequence);
+        
+        assertEquals(expectedSequence, validSequence);
+        assertEquals(originalSequence, sequence);
+    }
+    
+    @Test
+    public void testDropInvalidResponseRequestPairs_2() throws Exception {
+        List<Event> sequence = new LinkedList<Event>();
+        sequence.add(new Event(new SimpleSOAPEventType("op1", "foo", "bar", null, null, CallType.REQUEST)));
+        sequence.add(new Event(new SimpleSOAPEventType("op1", "foo", "bar", null, null, CallType.RESPONSE)));
+        sequence.add(new Event(new SimpleSOAPEventType("op1", "foo", "bar", null, null, CallType.REQUEST)));
+        sequence.add(new Event(new SimpleSOAPEventType("op2", "foo", "bar", null, null, CallType.REQUEST)));
+        sequence.add(new Event(new SimpleSOAPEventType("op1", "foo", "bar", null, null, CallType.RESPONSE)));
+        sequence.add(new Event(new SimpleSOAPEventType("op2", "foo", "bar", null, null, CallType.RESPONSE)));
+        
+        List<Event> expectedSequence = new LinkedList<Event>();
+        expectedSequence.add(new Event(new SimpleSOAPEventType("op1", "foo", "bar", null, null, CallType.REQUEST)));
+        expectedSequence.add(new Event(new SimpleSOAPEventType("op1", "foo", "bar", null, null, CallType.RESPONSE)));
+        
+        List<Event> originalSequence = new LinkedList<>(sequence);
+        
+        List<Event> validSequence = SOAPUtils.dropInvalidResponseRequestPairs(sequence);
+        Console.traceln(Level.INFO, getCurrentMethodName());
+        EventUtils.traceSequence(Level.INFO, validSequence);
+        
+        assertEquals(expectedSequence, validSequence);
+        assertEquals(originalSequence, sequence);
+    }
+    
+    @Test
+    public void testDropInvalidResponseRequestPairs_3() throws Exception {
+        List<Event> sequence = new LinkedList<Event>();
+        sequence.add(new Event(new SimpleSOAPEventType("op1", "foo", "bar", null, null, CallType.REQUEST)));
+        sequence.add(new Event(new SimpleSOAPEventType("op1", "foo", "bar", null, null, CallType.RESPONSE)));
+        sequence.add(new Event(new SimpleSOAPEventType("op1", "foo", "bar", null, null, CallType.REQUEST)));
+        sequence.add(new Event(new SimpleSOAPEventType("op2", "foo", "bar", null, null, CallType.REQUEST)));
+        sequence.add(new Event(new SimpleSOAPEventType("op2", "foo", "bar", null, null, CallType.RESPONSE)));
+        
+        List<Event> expectedSequence = new LinkedList<Event>();
+        expectedSequence.add(new Event(new SimpleSOAPEventType("op1", "foo", "bar", null, null, CallType.REQUEST)));
+        expectedSequence.add(new Event(new SimpleSOAPEventType("op1", "foo", "bar", null, null, CallType.RESPONSE)));
+        
+        List<Event> originalSequence = new LinkedList<>(sequence);
+        
+        List<Event> validSequence = SOAPUtils.dropInvalidResponseRequestPairs(sequence);
+        Console.traceln(Level.INFO, getCurrentMethodName());
+        EventUtils.traceSequence(Level.INFO, validSequence);
+        
+        assertEquals(expectedSequence, validSequence);
+        assertEquals(originalSequence, sequence);
+    }
+    
+    @Test
+    public void testDropInvalidResponseRequestPairs_4() throws Exception {
+        List<Event> sequence = new LinkedList<Event>();
+        sequence.add(Event.STARTEVENT);
+        sequence.add(new Event(new SimpleSOAPEventType("op1", "foo", "bar", null, null, CallType.REQUEST)));
+        sequence.add(new Event(new SimpleSOAPEventType("op1", "foo", "bar", null, null, CallType.RESPONSE)));
+        sequence.add(new Event(new SimpleSOAPEventType("op1", "foo", "bar", null, null, CallType.REQUEST)));
+        sequence.add(new Event(new SimpleSOAPEventType("op2", "foo", "bar", null, null, CallType.REQUEST)));
+        sequence.add(new Event(new SimpleSOAPEventType("op2", "foo", "bar", null, null, CallType.RESPONSE)));
+        sequence.add(new Event(new SimpleSOAPEventType("op1", "foo", "bar", null, null, CallType.RESPONSE)));
+        sequence.add(Event.ENDEVENT);
+        
+        List<Event> expectedSequence = new LinkedList<>(sequence);
+        
+        List<Event> originalSequence = new LinkedList<>(sequence);
+        
+        List<Event> validSequence = SOAPUtils.dropInvalidResponseRequestPairs(sequence);
+        Console.traceln(Level.INFO, getCurrentMethodName());
+        EventUtils.traceSequence(Level.INFO, validSequence);
+        
+        assertEquals(expectedSequence, validSequence);
+        assertEquals(originalSequence, sequence);
+    }
+    
+    @Test
+    public void testDropInvalidResponseRequestPairs_5() throws Exception {
+        List<Event> sequence = new LinkedList<Event>();
+        sequence.add(Event.STARTEVENT);
+        sequence.add(new Event(new SimpleSOAPEventType("op1", "foo", "bar", null, null, CallType.REQUEST)));
+        sequence.add(new Event(new SimpleSOAPEventType("op1", "foo", "bar", null, null, CallType.RESPONSE)));
+        sequence.add(new Event(new SimpleSOAPEventType("op1", "foo", "bar", null, null, CallType.REQUEST)));
+        sequence.add(new Event(new SimpleSOAPEventType("op2", "foo", "bar", null, null, CallType.REQUEST)));
+        sequence.add(new Event(new SimpleSOAPEventType("op1", "foo", "bar", null, null, CallType.RESPONSE)));
+        sequence.add(new Event(new SimpleSOAPEventType("op2", "foo", "bar", null, null, CallType.RESPONSE)));
+        sequence.add(Event.ENDEVENT);
+        
+        List<Event> expectedSequence = new LinkedList<Event>();
+        expectedSequence.add(Event.STARTEVENT);
+        expectedSequence.add(new Event(new SimpleSOAPEventType("op1", "foo", "bar", null, null, CallType.REQUEST)));
+        expectedSequence.add(new Event(new SimpleSOAPEventType("op1", "foo", "bar", null, null, CallType.RESPONSE)));
+        expectedSequence.add(Event.ENDEVENT);
+        
+        List<Event> originalSequence = new LinkedList<>(sequence);
+        
+        List<Event> validSequence = SOAPUtils.dropInvalidResponseRequestPairs(sequence);
+        Console.traceln(Level.INFO, getCurrentMethodName() );
+        EventUtils.traceSequence(Level.INFO, validSequence);
+        
+        assertEquals(expectedSequence, validSequence);
+        assertEquals(originalSequence, sequence);
+    }
+    
+    @Test
+    public void testDropInvalidResponseRequestPairs_6() throws Exception {
+        List<Event> sequence = new LinkedList<Event>();
+        sequence.add(Event.STARTEVENT);
+        sequence.add(new Event(new SimpleSOAPEventType("op1", "foo", "bar", null, null, CallType.REQUEST)));
+        sequence.add(new Event(new SimpleSOAPEventType("op1", "foo", "bar", null, null, CallType.RESPONSE)));
+        sequence.add(new Event(new SimpleSOAPEventType("op1", "foo", "bar", null, null, CallType.REQUEST)));
+        sequence.add(new Event(new SimpleSOAPEventType("op2", "foo", "bar", null, null, CallType.REQUEST)));
+        sequence.add(new Event(new SimpleSOAPEventType("op2", "foo", "bar", null, null, CallType.RESPONSE)));
+        sequence.add(Event.ENDEVENT);
+        
+        List<Event> expectedSequence = new LinkedList<Event>();
+        expectedSequence.add(Event.STARTEVENT);
+        expectedSequence.add(new Event(new SimpleSOAPEventType("op1", "foo", "bar", null, null, CallType.REQUEST)));
+        expectedSequence.add(new Event(new SimpleSOAPEventType("op1", "foo", "bar", null, null, CallType.RESPONSE)));
+        expectedSequence.add(Event.ENDEVENT);
+        
+        List<Event> originalSequence = new LinkedList<>(sequence);
+        
+        List<Event> validSequence = SOAPUtils.dropInvalidResponseRequestPairs(sequence);
+        Console.traceln(Level.INFO, getCurrentMethodName());
+        EventUtils.traceSequence(Level.INFO, validSequence);
+        
+        assertEquals(expectedSequence, validSequence);
+        assertEquals(originalSequence, sequence);
+    }
+
+    private  String getCurrentMethodName() {
+         StackTraceElement stackTraceElements[] = (new Throwable()).getStackTrace();
+         return stackTraceElements[1].toString();
+    }
+    
 }
Index: /trunk/autoquest-plugin-http/src/main/java/de/ugoe/cs/autoquest/plugin/http/SOAPUtils.java
===================================================================
--- /trunk/autoquest-plugin-http/src/main/java/de/ugoe/cs/autoquest/plugin/http/SOAPUtils.java	(revision 2002)
+++ /trunk/autoquest-plugin-http/src/main/java/de/ugoe/cs/autoquest/plugin/http/SOAPUtils.java	(revision 2003)
@@ -23,4 +23,6 @@
 import java.util.List;
 import java.util.Set;
+import java.util.Stack;
+import java.util.logging.Level;
 
 import javax.xml.transform.Transformer;
@@ -41,4 +43,5 @@
 import de.ugoe.cs.autoquest.plugin.http.eventcore.SimpleSOAPEventType;
 import de.ugoe.cs.autoquest.plugin.http.eventcore.SimpleSOAPEventType.CallType;
+import de.ugoe.cs.util.console.Console;
 
 /**
@@ -690,4 +693,112 @@
     /**
      * <p>
+     * Drops all requests without responses as well as invalid request/response orders. Only the
+     * part of the sequence before the first invalid occurrence is kept.
+     * </p>
+     * 
+     * @param sequences
+     *            sequences where the invalid pairs are dropped
+     * @return sequences with only valid and complete interactions
+     */
+    public static Collection<List<Event>> dropInvalidResponseRequestPairs(Collection<List<Event>> sequences)
+    {
+        Collection<List<Event>> validSequences = new LinkedList<>();
+        int i = 0;
+        for (List<Event> sequence : sequences) {
+            List<Event> validSequence = dropInvalidResponseRequestPairs(sequence);
+            if (validSequence.isEmpty() ||
+                (validSequence.size() <= 2 && validSequence.get(0) == Event.STARTEVENT))
+            {
+                Console.traceln(Level.INFO, "dropped sequence " + i +
+                    ": empty after removal of invalid request/response pairs");
+            }
+            validSequences.add(validSequence);
+            i++;
+        }
+        return validSequences;
+    }
+
+    /**
+     * <p>
+     * Drops all requests without responses as well as invalid request/response orders. Only the
+     * part of the sequence before the first invalid occurrence is kept.
+     * </p>
+     * 
+     * @param sequence
+     *            sequence where the invalid pairs are dropped
+     * @return sequence with only valid and complete interactions
+     */
+    public static List<Event> dropInvalidResponseRequestPairs(List<Event> sequence) {
+        Stack<SimpleSOAPEventType> unrespondedRequests = new Stack<>();
+        boolean hasStartEvent = false;
+        int lastValidIndex = 0;
+        int i = 0;
+        for (Event event : sequence) {
+            if (event == Event.STARTEVENT) {
+                hasStartEvent = true;
+                lastValidIndex = i;
+            }
+            else if (event.getType() instanceof SimpleSOAPEventType) {
+                SimpleSOAPEventType currentEventType = (SimpleSOAPEventType) event.getType();
+                if (SOAPUtils.isSOAPRequest(event)) {
+                    unrespondedRequests.push(currentEventType);
+                }
+                else if (SOAPUtils.isSOAPResponse(event)) {
+                    if (unrespondedRequests.empty()) {
+                        break; // found a response without previous request; sequence invalid from
+                               // here
+                    }
+                    else {
+                        SimpleSOAPEventType lastRequest = unrespondedRequests.peek();
+                        if (isRequestResponseMatch(lastRequest, currentEventType)) {
+                            unrespondedRequests.pop();
+                            if (unrespondedRequests.empty()) {
+                                lastValidIndex = i;
+                            }
+                        }
+                    }
+
+                }
+            }
+            i++;
+        }
+        List<Event> validSequence = new LinkedList<>(sequence.subList(0, lastValidIndex + 1));
+        if (hasStartEvent) {
+            validSequence.add(Event.ENDEVENT);
+        }
+        return validSequence;
+    }
+
+    /**
+     * <p>
+     * Checks if two {@link SimpleSOAPEventType} types are equal except their {@link CallType},
+     * which must be {@value CallType#REQUEST} for the first parameter and {@link CallType#RESPONSE}
+     * for the second parameter.
+     * </p>
+     * 
+     * @param request
+     *            request soap event
+     * @param response
+     *            response soap event
+     * @return true if they are a matching request/response pair
+     */
+    public static boolean isRequestResponseMatch(SimpleSOAPEventType request,
+                                                 SimpleSOAPEventType response)
+    {
+        if (request == null && response == null) {
+            return true;
+        }
+        if ((request != null && response == null) || (request == null && response != null)) {
+            return false;
+        }
+        return request.getCallType().equals(CallType.REQUEST) &&
+            response.getCallType().equals(CallType.RESPONSE) &&
+            HTTPUtils.equals(request.getCalledMethod(), response.getCalledMethod()) &&
+            HTTPUtils.equals(request.getServiceName(), response.getServiceName()) &&
+            HTTPUtils.equals(request.getClientName(), response.getClientName());
+    }
+
+    /**
+     * <p>
      * prevent instantiation
      * </p>
