Index: trunk/autoquest-plugin-uml/src/main/java/de/ugoe/cs/autoquest/plugin/uml/UMLInteractionCreator.java
===================================================================
--- trunk/autoquest-plugin-uml/src/main/java/de/ugoe/cs/autoquest/plugin/uml/UMLInteractionCreator.java	(revision 2009)
+++ trunk/autoquest-plugin-uml/src/main/java/de/ugoe/cs/autoquest/plugin/uml/UMLInteractionCreator.java	(revision 2010)
@@ -23,8 +23,12 @@
 
 import org.apache.commons.lang.mutable.MutableInt;
+import org.eclipse.emf.common.util.EList;
 import org.eclipse.uml2.uml.CallConcurrencyKind;
 import org.eclipse.uml2.uml.Component;
 import org.eclipse.uml2.uml.Connector;
 import org.eclipse.uml2.uml.DataType;
+import org.eclipse.uml2.uml.Element;
+import org.eclipse.uml2.uml.Enumeration;
+import org.eclipse.uml2.uml.Generalization;
 import org.eclipse.uml2.uml.InstanceSpecification;
 import org.eclipse.uml2.uml.InstanceValue;
@@ -45,7 +49,8 @@
 import org.eclipse.uml2.uml.PrimitiveType;
 import org.eclipse.uml2.uml.Property;
+import org.eclipse.uml2.uml.Relationship;
 import org.eclipse.uml2.uml.Slot;
+import org.eclipse.uml2.uml.Type;
 import org.eclipse.uml2.uml.UMLPackage;
-import org.w3c.dom.Element;
 
 import de.ugoe.cs.autoquest.eventcore.Event;
@@ -78,10 +83,10 @@
      */
     private final boolean useRandomMsgBodies;
-    
-    /**
-     * TODO
+
+    /**
+     * a cache of the already created instance specification; used to create the overall number of generated specifications
      */
     private final Map<String, InstanceSpecification> instanceSpecificationCache;
-    
+
     /**
      * <p>
@@ -116,4 +121,5 @@
      */
     public Interaction createInteraction(List<Event> sequence, String interactionName) {
+        Console.traceln(Level.FINEST, "creating interaction: " + interactionName);
         final Component testContext = UMLUtils.fetchTestContext(model, testContextName);
         if (testContext == null) {
@@ -151,4 +157,5 @@
         int i = 0;
         for (Event event : sequence) {
+            Console.traceln(Level.FINEST, "creating message for event: " + event.toString());
             if (!(event.equals(Event.STARTEVENT) || event.equals(Event.ENDEVENT))) {
                 String serviceName = SOAPUtils.getServiceNameFromEvent(event);
@@ -325,5 +332,6 @@
                                       String prefix)
     {
-        Element requestBody;
+        // printParameters(calledOperation); // FOR DEBUGGING
+        org.w3c.dom.Element requestBody;
         if (SOAPUtils.isSOAPRequest(event)) {
             requestBody =
@@ -343,5 +351,5 @@
             }
 
-            String path = calledOperation.getName() + ":" + param.getType().getName();
+            String path = calledOperation.getName() + ":" + getNormalizedTypeName(param.getType());
             if ((UMLUtils.isInParameter(param) && SOAPUtils.isSOAPRequest(event)) ||
                 (UMLUtils.isOutParameter(param) && SOAPUtils.isSOAPResponse(event)))
@@ -356,5 +364,5 @@
                     (InstanceSpecification) instSpecPkg
                         .createPackagedElement(prefix + "instspec" + instSpecNumber.intValue() +
-                                                   "_" + param.getType().getName(),
+                                                   "_" + getNormalizedTypeName(param.getType()),
                                                UMLPackage.Literals.INSTANCE_SPECIFICATION);
                 instSpecParameters.getClassifiers().add((DataType) param.getType());
@@ -368,6 +376,6 @@
                     if (internalParameter.getType() instanceof DataType) {
                         List<org.w3c.dom.Element> paramNodes =
-                            SOAPUtils.getMatchingChildNode(internalParameter.getType().getName(),
-                                                           requestBody);
+                            SOAPUtils.getMatchingChildNode(getNormalizedTypeName(internalParameter
+                                .getType()), requestBody);
                         int multiplicityChosen = paramNodes.size();
 
@@ -397,9 +405,8 @@
                                                  internalParameter.getType(),
                                                  UMLPackage.Literals.INSTANCE_VALUE);
-                            InstanceSpecification instSpec = createInstanceSpecification((DataType) internalParameter
-                                                                                        .getType(),
-                                                                                        instSpecPkg, prefix,
-                                                                                        instSpecNumber, paramNode,
-                                                                                        path);
+                            InstanceSpecification instSpec =
+                                createInstanceSpecification((DataType) internalParameter.getType(),
+                                                            instSpecPkg, prefix, instSpecNumber,
+                                                            paramNode, path);
                             value.setInstance(instSpec);
                             /*
@@ -452,5 +459,5 @@
                                                               String path)
     {
-        if( instanceSpecificationCache.containsKey(SOAPUtils.getSerialization(currentNode)) ) {
+        if (instanceSpecificationCache.containsKey(SOAPUtils.getSerialization(currentNode))) {
             return instanceSpecificationCache.get(SOAPUtils.getSerialization(currentNode));
         }
@@ -470,41 +477,122 @@
                 createSlotPrimitiveType(instSpec, prop, currentNode, path);
             }
+            else if (prop.getType() instanceof Enumeration ) {
+                createSlotEnumeration(instSpec, prop, currentNode, path);
+            }
             else if (prop.getType() instanceof DataType) {
-                List<org.w3c.dom.Element> attributeNodes = null;
-                int multiplicityChosen = 0;
-                if (currentNode != null) {
-                    attributeNodes = SOAPUtils.getMatchingChildNode(prop.getName(), currentNode);
-                    multiplicityChosen = attributeNodes.size();
-                }
-
-                if (multiplicityChosen == 0 && prop.getLower() > 0) {
+                if( isXSDSequence(prop.getType()) ) { // XSD sequence, no real type
+                    System.out.println(SOAPUtils.getChildNodeNames(currentNode));
+                    List<String> childNames = SOAPUtils.getChildNodeNames(currentNode);
+                    List<org.w3c.dom.Element> childNodes = SOAPUtils.getChildElements(currentNode);
+                    EList<Property> sequenceProperties = ((DataType) prop.getType()).getAllAttributes();
+                    boolean sequenceIsMatch = true;
+                    if( sequenceProperties.size()==childNames.size()) {
+                        for(int i=0; sequenceIsMatch && i<sequenceProperties.size() ; i++) {
+                            Property propSeq = sequenceProperties.get(i);
+                            String currentChildName = childNames.get(i);
+                            if( isXSDChoice(propSeq.getType() ) ) {
+                                boolean choiceMatchFound = false;
+                                for( Property propChoice : ((DataType) propSeq.getType()).getAllAttributes() ) {
+                                    if( currentChildName.equals(propChoice.getName()) ) {
+                                        choiceMatchFound = true;
+                                    }
+                                }
+                                sequenceIsMatch &= choiceMatchFound;
+                            } else {
+                                sequenceIsMatch &= currentChildName.equals(propSeq.getName());
+                            }
+                        }
+                        if( sequenceIsMatch ) {
+                            // this is the correct sequence, it matches; now appropriate data must be created
+                            
+                            // first we create the slot and instance specification for the sequence
+                            Slot slot = instSpec.createSlot();
+                            slot.setDefiningFeature(prop);
+                            InstanceValue value =
+                                (InstanceValue) slot.createValue(prop.getName(), prop.getType(), UMLPackage.Literals.INSTANCE_VALUE);
+                            InstanceSpecification instSpecSequence =
+                                    (InstanceSpecification) pkg
+                                        .createPackagedElement(prefix + prop.getName() + "_instspec" + instSpecNumber.intValue() + "_" +
+                                                                   type.getName(),
+                                                               UMLPackage.Literals.INSTANCE_SPECIFICATION);
+                            instSpecSequence.getClassifiers().add((DataType) prop.getType());
+                            instSpecNumber.setValue(instSpecNumber.intValue() + 1);
+                            value.setInstance(instSpecSequence);
+                            
+                            // now we create the slots and instance specifications for the elements of the sequence
+                            for(int i=0; i<sequenceProperties.size() ; i++) {
+                                Property propSeq = sequenceProperties.get(i);
+                                String currentChildName = childNames.get(i);
+                                slot = instSpecSequence.createSlot();
+                                slot.setDefiningFeature(propSeq);
+                                value = (InstanceValue) slot.createValue(propSeq.getName(), propSeq.getType(), UMLPackage.Literals.INSTANCE_VALUE);
+                                if( isXSDChoice(propSeq.getType() ) ) {
+                                    // create the inner choice instance spec
+                                    InstanceSpecification instSpecSequenceChoice = (InstanceSpecification) pkg
+                                            .createPackagedElement(prefix + propSeq.getName() + "_instspec" + instSpecNumber.intValue() + "_" +
+                                                    propSeq.getType().getName(),
+                                                UMLPackage.Literals.INSTANCE_SPECIFICATION);
+                                    instSpecSequenceChoice.getClassifiers().add((DataType) propSeq.getType());
+                                    instSpecNumber.setValue(instSpecNumber.intValue()+1);
+                                    value.setInstance(instSpecSequenceChoice);
+                                    for( Property propChoice : ((DataType) propSeq.getType()).getAllAttributes() ) {
+                                        if( currentChildName.equals(propChoice.getName()) ) {
+                                            slot = instSpecSequenceChoice.createSlot();
+                                            slot.setDefiningFeature(propChoice);
+                                            value = (InstanceValue) slot.createValue(propChoice.getName(), propChoice.getType(), UMLPackage.Literals.INSTANCE_VALUE);
+                                            value.setInstance(createInstanceSpecification((DataType) propChoice.getType(), pkg, prefix, instSpecNumber, childNodes.get(i), path+"."+propChoice.getName()));
+                                            break;
+                                        }
+                                    }
+                                } else {
+                                    value.setInstance(createInstanceSpecification((DataType) propSeq.getType(), pkg, prefix, instSpecNumber, childNodes.get(i), path+"."+propSeq.getName()));
+                                }
+                            } 
+                        }
+                        System.out.println(prop.getName() + " " + sequenceIsMatch);
+                    }
+                }
+                else if( isXSDChoice(prop.getType()) ) { 
+                    // TODO implement handling of choices, if required for the MIDAS pilots
+                    Console.traceln(Level.SEVERE, "cannot handle choices that are the child elements of normal data types yet!");
+                    Console.traceln(Level.SEVERE, "choice is ignored and no data is created.");
+                } else {
+                    List<org.w3c.dom.Element> attributeNodes = null;
+                    int multiplicityChosen = 0;
                     if (currentNode != null) {
-                        Console.traceln(Level.WARNING,
-                                        "required attribute not found in SOAP message: " + path +
-                                            "." + prop.getName());
-                        Console
-                            .traceln(Level.WARNING,
-                                     "setting default values for this attribute and all its children");
-                        Console.traceln(Level.FINE, "XML structure of path:" + StringTools.ENDLINE +
-                            SOAPUtils.getSerialization(currentNode));
+                        attributeNodes = SOAPUtils.getMatchingChildNode(prop.getName(), currentNode);
+                        multiplicityChosen = attributeNodes.size();
                     }
-                    multiplicityChosen = prop.getLower();
-                }
-                for (int i = 0; i < multiplicityChosen; i++) {
-                    org.w3c.dom.Element attributeNode = null;
-                    if (attributeNodes != null && !attributeNodes.isEmpty()) {
-                        attributeNode = attributeNodes.get(i);
+    
+                    if (multiplicityChosen == 0 && prop.getLower() > 0) {
+                        if (currentNode != null) {
+                            Console.traceln(Level.WARNING,
+                                            "required attribute not found in SOAP message: " + path +
+                                                "." + prop.getName());
+                            Console
+                                .traceln(Level.WARNING,
+                                         "setting default values for this attribute and all its children");
+                            Console.traceln(Level.FINE, "XML structure of path:" + StringTools.ENDLINE +
+                                SOAPUtils.getSerialization(currentNode));
+                        }
+                        multiplicityChosen = prop.getLower();
                     }
-
-                    Slot slot = instSpec.createSlot();
-                    slot.setDefiningFeature(prop);
-
-                    InstanceValue value =
-                        (InstanceValue) slot.createValue(prop.getName() + "_" + i, prop.getType(),
-                                                         UMLPackage.Literals.INSTANCE_VALUE);
-                    value.setInstance(createInstanceSpecification((DataType) prop.getType(), pkg,
-                                                                  prefix, instSpecNumber,
-                                                                  attributeNode,
-                                                                  path + "." + prop.getName()));
+                    for (int i = 0; i < multiplicityChosen; i++) {
+                        org.w3c.dom.Element attributeNode = null;
+                        if (attributeNodes != null && !attributeNodes.isEmpty()) {
+                            attributeNode = attributeNodes.get(i);
+                        }
+    
+                        Slot slot = instSpec.createSlot();
+                        slot.setDefiningFeature(prop);
+    
+                        InstanceValue value =
+                            (InstanceValue) slot.createValue(prop.getName() + "_" + i, prop.getType(),
+                                                             UMLPackage.Literals.INSTANCE_VALUE);
+                        value.setInstance(createInstanceSpecification((DataType) prop.getType(), pkg,
+                                                                      prefix, instSpecNumber,
+                                                                      attributeNode,
+                                                                      path + "." + prop.getName()));
+                    }
                 }
             }
@@ -535,8 +623,8 @@
      *            used for warnings and debug information
      */
-    private static void createSlotPrimitiveType(InstanceSpecification instSpec,
-                                                Property prop,
-                                                org.w3c.dom.Element currentNode,
-                                                String path)
+    private void createSlotPrimitiveType(InstanceSpecification instSpec,
+                                         Property prop,
+                                         org.w3c.dom.Element currentNode,
+                                         String path)
     {
         List<String> attributeValues = SOAPUtils.getValuesFromElement(prop.getName(), currentNode);
@@ -562,5 +650,5 @@
             Slot slot = instSpec.createSlot();
             slot.setDefiningFeature(prop);
-            if ("String".equals(prop.getType().getName())) {
+            if (isPrimitiveTypeOf(prop.getType(), "String")) {
                 LiteralString value =
                     (LiteralString) slot.createValue(prop.getName(), null,
@@ -573,5 +661,5 @@
                 }
             }
-            else if ("Integer".equals(prop.getType().getName())) {
+            else if (isPrimitiveTypeOf(prop.getType(), "Integer")) {
                 LiteralInteger value =
                     (LiteralInteger) slot.createValue(prop.getName(), null,
@@ -584,5 +672,5 @@
                 }
             }
-            else if ("Boolean".equals(prop.getType().getName())) {
+            else if (isPrimitiveTypeOf(prop.getType(), "Boolean")) {
                 LiteralBoolean value =
                     (LiteralBoolean) slot.createValue(prop.getName(), null,
@@ -595,5 +683,5 @@
                 }
             }
-            else if ("Real".equals(prop.getType().getName())) {
+            else if (isPrimitiveTypeOf(prop.getType(), "Real")) {
                 LiteralReal value =
                     (LiteralReal) slot.createValue(prop.getName(), null,
@@ -610,4 +698,56 @@
                     prop.getType().getName());
                 throw new RuntimeException("unknown primitive type: " + prop.getType().getName());
+            }
+        }
+    }
+    
+    /**
+     * <p>
+     * Creates a {@link Slot} in an {@link InstanceSpecification} for an enumeration.
+     * </p>
+     * 
+     * @param instSpec
+     *            instance specification to which the slot is added
+     * @param prop
+     *            property that describes the slot
+     * @param currentNode
+     *            DOM node from which is value for the slot is inferred
+     * @param path
+     *            used for warnings and debug information
+     */
+    private void createSlotEnumeration(InstanceSpecification instSpec,
+                                         Property prop,
+                                         org.w3c.dom.Element currentNode,
+                                         String path)
+    {
+        List<String> attributeValues = SOAPUtils.getValuesFromElement(prop.getName(), currentNode);
+
+        if (attributeValues.isEmpty()) {
+            if (prop.getLower() == 0) {
+                // ignoring optional attribute
+                return;
+            }
+            else {
+                if (currentNode != null) {
+                    Console.traceln(Level.WARNING,
+                                    "required attribute not found in SOAP message: " + path + "." +
+                                        prop.getName());
+                    Console.traceln(Level.WARNING, "setting default values for this attribute");
+                    Console.traceln(Level.FINE, "XML structure of path:" + StringTools.ENDLINE +
+                        SOAPUtils.getSerialization(currentNode));
+                }
+                attributeValues.add(null);
+            }
+        }
+        for (String attributeValue : attributeValues) {
+            Slot slot = instSpec.createSlot();
+            slot.setDefiningFeature(prop);
+            
+            InstanceValue value = (InstanceValue) slot.createValue(prop.getName(), null, UMLPackage.Literals.INSTANCE_VALUE);
+            if( attributeValue!=null ) {
+                value.setInstance(((Enumeration) prop.getType()).getOwnedLiteral(attributeValue));
+                System.out.println("foo");
+            } else {
+                throw new RuntimeException("cannot create enumeration literal with dummy value");
             }
         }
@@ -642,3 +782,124 @@
     }
 
+    /**
+     * <p>
+     * Checks if a type is a instance of a primitive type defined by its name, e.g., String,
+     * Integer, or Boolean. The functions also checks whether the type is a generalization.
+     * </p>
+     * 
+     * @param type
+     *            type that is checked
+     * @param typeNam
+     *            name of the primitive type
+     * @return true if the type is of the specified primitive type; false otherwise
+     */
+    private boolean isPrimitiveTypeOf(Type type, String typeName) {
+        if (typeName == null) {
+            throw new RuntimeException("typename must not be null");
+        }
+        if (!(type instanceof PrimitiveType)) {
+            return false;
+        }
+        if (typeName.equals(type.getName())) {
+            return true;
+        }
+        for (Relationship relationship : type.getRelationships()) {
+            if (relationship instanceof Generalization) {
+                Element target = ((Generalization) relationship).getTargets().get(0);
+                if (target instanceof PrimitiveType) {
+                    return typeName.equals(((PrimitiveType) target).getName());
+                }
+            }
+        }
+        return false;
+    }
+    
+    /**
+     * <p>
+     * Checks if a type is an anonymous inner type that represents an XSD sequence
+     * </p>
+     *
+     * @param type type that is checked
+     * @return true if XSD sequence; false otherwise
+     */
+    private boolean isXSDSequence(Type type) {
+        if( type==null || type.getName()==null ) {
+            return false;
+        }
+        return type.getName().matches("sequence\\d*");
+    }
+    
+    /**
+     * <p>
+     * Checks if a type is an anonymous inner type that represents an XSD choice
+     * </p>
+     *
+     * @param type type that is checked
+     * @return true if XSD choice; false otherwise
+     */
+    private boolean isXSDChoice(Type type) {
+        if( type==null || type.getName()==null ) {
+            return false;
+        }
+        return type.getName().matches("choice\\d*");
+    }
+
+    /**
+     * <p>
+     * Returns the name of a type and removes the suffix _._type.
+     * </p>
+     * 
+     * @param the
+     *            type
+     * @return type name of the type without the possible suffix
+     */
+    private String getNormalizedTypeName(Type type) {
+        if (type == null) {
+            throw new RuntimeException("type must not be null");
+        }
+        String typeName = type.getName();
+        if (typeName != null && typeName.endsWith("_._type")) {
+            typeName = typeName.substring(0, typeName.length() - 7);
+        }
+        return typeName;
+    }
+
+    // /////////////////////
+    // DEBUGGING METHODS //
+    // /////////////////////
+
+    @SuppressWarnings("unused")
+    private void printParameters(Operation operation) {
+        System.out.println("operation name: " + operation.getName());
+        for (Parameter param : operation.getOwnedParameters()) {
+            printParameters(param, 0);
+        }
+    }
+
+    private void printParameters(Parameter param, int depth) {
+        for (int i = 0; i < depth; i++) {
+            System.out.print(" ");
+        }
+        System.out.println(param.getName() + " - " + getNormalizedTypeName(param.getType()));
+        if (param.getType() instanceof DataType) {
+            for (Property prop : ((DataType) param.getType()).getAllAttributes()) {
+                printParameters(prop, depth + 2);
+            }
+        }
+    }
+
+    private void printParameters(Property prop, int depth) {
+        if (depth > 10)
+            return;
+        for (int i = 0; i < depth; i++) {
+            System.out.print(" ");
+        }
+        System.out.println(prop.getName() + " - " + getNormalizedTypeName(prop.getType()));
+        if (prop.getType() instanceof DataType) {
+            for (Property prop2 : ((DataType) prop.getType()).getAllAttributes()) {
+                printParameters(prop2, depth + 2);
+            }
+        }
+    }
+
 }
