Index: /trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITask.java
===================================================================
--- /trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITask.java	(revision 1399)
+++ /trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITask.java	(revision 1400)
@@ -71,4 +71,14 @@
     /**
      * <p>
+     * returns a collection of collections of all different execution variants of this task. This
+     * is a grouping of all instances where each group contains structurally identical instances.
+     * </p>
+     * 
+     * @return as described
+     */
+    public Collection<Collection<ITaskInstance>> getExecutionVariants();
+
+    /**
+     * <p>
      * checks whether this task is equal to another one. Task equality is only given, if two
      * tasks have the same id. This means, that this method must only return true if the other
Index: /trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/Task.java
===================================================================
--- /trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/Task.java	(revision 1399)
+++ /trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/Task.java	(revision 1400)
@@ -18,7 +18,14 @@
 import java.util.Collections;
 import java.util.HashSet;
-
+import java.util.LinkedList;
+
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTaskInstance;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IIterationInstance;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IOptionalInstance;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelectionInstance;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequenceInstance;
 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceList;
 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskVisitor;
 
@@ -31,5 +38,5 @@
  * @author Patrick Harms
  */
-class Task implements ITask {
+abstract class Task implements ITask {
 
     /**
@@ -75,4 +82,11 @@
      */
     private Collection<ITaskInstance> instances = new HashSet<ITaskInstance>();
+    
+    /**
+     * <p>
+     * the execution variants of this task
+     * </p>
+     */
+    private Collection<Collection<ITaskInstance>> executionVariants;
 
     /**
@@ -141,4 +155,17 @@
     public Collection<ITaskInstance> getInstances() {
         return Collections.unmodifiableCollection(instances);
+    }
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITask#getExecutionVariants()
+     */
+    @Override
+    public synchronized Collection<Collection<ITaskInstance>> getExecutionVariants() {
+        if (executionVariants == null) {
+            executionVariants = new LinkedList<Collection<ITaskInstance>>();
+            determineExecutionVariants(executionVariants);
+        }
+        
+        return executionVariants;
     }
 
@@ -215,6 +242,7 @@
      * @param instance the instance to be removed from this task
      */
-    void removeInstance(ITaskInstance instance) {
+    synchronized void removeInstance(ITaskInstance instance) {
         this.instances.remove(instance);
+        this.executionVariants = null;
     }
 
@@ -226,6 +254,7 @@
      * @param instance the instance belonging to this task
      */
-    void addInstance(ITaskInstance instance) {
+    synchronized void addInstance(ITaskInstance instance) {
         this.instances.add(instance);
+        this.executionVariants = null;
     }
     
@@ -238,3 +267,101 @@
     }
 
+    /**
+     *
+     */
+    private void determineExecutionVariants(Collection<Collection<ITaskInstance>> executionVariants)
+    {
+        for (ITaskInstance instance : instances) {
+            boolean added = false;
+            for (Collection<ITaskInstance> variant : executionVariants) {
+                if (!variant.isEmpty() && (isSameExecution(variant.iterator().next(), instance))) {
+                    variant.add(instance);
+                    added = true;
+                }
+            }
+            
+            if (!added) {
+                Collection<ITaskInstance> variant = new HashSet<ITaskInstance>();
+                variant.add(instance);
+                executionVariants.add(variant);
+            }
+        }
+    }
+
+    /**
+     *
+     */
+    private boolean isSameExecution(ITaskInstance instance1, ITaskInstance instance2) {
+        if (instance1 instanceof IIterationInstance) {
+            if (!(instance2 instanceof IIterationInstance)) {
+                return false;
+            }
+            
+            ITaskInstanceList iteration1 = (ITaskInstanceList) instance1;
+            ITaskInstanceList iteration2 = (ITaskInstanceList) instance2;
+            
+            return isSameExecutionList(iteration1, iteration2);
+        }
+        else if (instance1 instanceof ISequenceInstance) {
+            if (!(instance2 instanceof ISequenceInstance)) {
+                return false;
+            }
+            
+            ITaskInstanceList selection1 = (ITaskInstanceList) instance1;
+            ITaskInstanceList selection2 = (ITaskInstanceList) instance2;
+            
+            return isSameExecutionList(selection1, selection2);
+        }
+        else if (instance1 instanceof ISelectionInstance) {
+            if (!(instance2 instanceof ISelectionInstance)) {
+                return false;
+            }
+            else {
+                return isSameExecution(((ISelectionInstance) instance1).getChild(),
+                                       ((ISelectionInstance) instance2).getChild());
+            }
+        }
+        else if (instance1 instanceof IOptionalInstance) {
+            if (!(instance2 instanceof IOptionalInstance)) {
+                return false;
+            }
+            else {
+                return isSameExecution(((IOptionalInstance) instance1).getChild(),
+                                       ((IOptionalInstance) instance2).getChild());
+            }
+        }
+        else if (instance1 instanceof IEventTaskInstance) {
+            if (!(instance2 instanceof IEventTaskInstance)) {
+                return false;
+            }
+            else {
+                return ((IEventTaskInstance) instance1).getTask().equals
+                    (((IEventTaskInstance) instance2).getTask());
+            }
+        }
+        else if (instance1 == null) {
+            return instance2 == null;
+        }
+        else {
+            throw new IllegalArgumentException("unknown type of task instance: " + instance1);
+        }
+    }
+
+    /**
+     *
+     */
+    private boolean isSameExecutionList(ITaskInstanceList list1, ITaskInstanceList list2) {
+        if (list1.size() == list2.size()) {
+            for (int i = 0; i < list1.size(); i++) {
+                if (!isSameExecution(list1.get(i), list2.get(i))) {
+                    return false;
+                }
+            }
+            
+            return true;
+        }
+        else {
+            return false;
+        }
+    }
 }
