Merge Kepler changes
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/RootElementComparator.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/RootElementComparator.java
new file mode 100644
index 0000000..6dacde6
--- /dev/null
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/RootElementComparator.java
@@ -0,0 +1,58 @@
+/******************************************************************************* 
+ * Copyright (c) 2011, 2012 Red Hat, Inc. 
+ *  All rights reserved. 
+ * This program is made available under the terms of the 
+ * Eclipse Public License v1.0 which accompanies this distribution, 
+ * and is available at http://www.eclipse.org/legal/epl-v10.html 
+ * 
+ * Contributors: 
+ * Red Hat, Inc. - initial API and implementation 
+ *
+ * @author Ivar Meikas
+ ******************************************************************************/
+package org.eclipse.bpmn2.modeler.core;
+
+import java.util.Comparator;
+
+import org.eclipse.bpmn2.DataStore;
+import org.eclipse.bpmn2.Escalation;
+import org.eclipse.bpmn2.Error;
+import org.eclipse.bpmn2.EventDefinition;
+import org.eclipse.bpmn2.Interface;
+import org.eclipse.bpmn2.ItemDefinition;
+import org.eclipse.bpmn2.Message;
+import org.eclipse.bpmn2.Resource;
+import org.eclipse.bpmn2.RootElement;
+import org.eclipse.bpmn2.Signal;
+
+public final class RootElementComparator implements Comparator<RootElement> {
+	@Override
+	public int compare(RootElement a, RootElement b) {
+		int aOrder = getOrder(a);
+		int bOrder = getOrder(b);
+		return aOrder - bOrder;
+	}
+	
+	private int getOrder(RootElement element) {
+		if (element instanceof ItemDefinition)
+			return 0;
+		if (element instanceof Error)
+			return 1;
+		if (element instanceof Signal)
+			return 2;
+		if (element instanceof Escalation)
+			return 3;
+		if (element instanceof Resource)
+			return 4;
+		if (element instanceof Message)
+			return 5;
+		if (element instanceof EventDefinition)
+			return 6;
+		if (element instanceof DataStore)
+			return 7;
+		if (element instanceof Interface)
+			return 8;
+		
+		return Integer.MAX_VALUE;
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/adapters/ExtendedPropertiesAdapter.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/adapters/ExtendedPropertiesAdapter.java
index ef0ea62..196fc09 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/adapters/ExtendedPropertiesAdapter.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/adapters/ExtendedPropertiesAdapter.java
@@ -265,11 +265,10 @@
 			if (getObjectDescriptor().object.eClass() == object.eClass()) {
 				if (feature==null)
 					return true;
-				FeatureDescriptor<T> fd = (FeatureDescriptor<T>) getProperty(feature,PROPERTY_DESCRIPTOR);
-				if (fd!=null) {
-					// only TRUE if this adapter is not using a default FeatureDescriptor
-					if (fd.getClass()!=FeatureDescriptor.class)
-						return true;
+				// only TRUE if this adapter already has a FeatureDescriptor for this feature 
+				Hashtable<String,Object> props = featureProperties.get(feature);
+				if (props!=null) {
+					return true;
 				}
 			}
 		}
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/model/Bpmn2ModelerResourceImpl.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/model/Bpmn2ModelerResourceImpl.java
index 9cc400f..259d8ea 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/model/Bpmn2ModelerResourceImpl.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/model/Bpmn2ModelerResourceImpl.java
@@ -40,6 +40,7 @@
 import org.eclipse.bpmn2.di.BPMNShape;
 import org.eclipse.bpmn2.di.BpmnDiPackage;
 import org.eclipse.bpmn2.modeler.core.Activator;
+import org.eclipse.bpmn2.modeler.core.RootElementComparator;
 import org.eclipse.bpmn2.modeler.core.DIZorderComparator;
 import org.eclipse.bpmn2.modeler.core.adapters.AdapterUtil;
 import org.eclipse.bpmn2.modeler.core.adapters.ExtendedPropertiesAdapter;
@@ -277,6 +278,8 @@
 			fixZOrder(bpmnDiagram);
 		}
 
+		fixRootElementOrder(definitions.getRootElements());
+
 		super.save(options);
 	}
 	
@@ -333,6 +336,10 @@
 		ECollections.sort(elements, new DIZorderComparator());
 	}
 
+	private void fixRootElementOrder(List<RootElement> elements) {
+		ECollections.sort((EList<RootElement>)elements, new RootElementComparator());
+	}
+
 	/**
 	 * Generate an ID attribute for the given BPMN2 element if not already set.
 	 * 
diff --git a/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/plugin.xml b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/plugin.xml
index 9ecd290..a881f92 100644
--- a/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/plugin.xml
+++ b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/plugin.xml
@@ -482,6 +482,7 @@
 			name="SequenceFlow Extensions"
 			type="SequenceFlow">
 			<property name="priority" value="1" type="EInt"/>
+			<property name="name" value=""/>
 		</modelExtension>
 		
 		<modelExtension
diff --git a/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/ProcessVariableNameChangeAdapter.java b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/ProcessVariableNameChangeAdapter.java
index bd8d6d4..6b1221f 100644
--- a/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/ProcessVariableNameChangeAdapter.java
+++ b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/ProcessVariableNameChangeAdapter.java
@@ -5,10 +5,12 @@
 import org.eclipse.emf.common.notify.Adapter;
 import org.eclipse.emf.common.notify.Notification;
 import org.eclipse.emf.common.notify.Notifier;
+import org.eclipse.emf.common.util.TreeIterator;
 import org.eclipse.emf.ecore.EObject;
 import org.eclipse.emf.ecore.EStructuralFeature;
 import org.eclipse.emf.ecore.InternalEObject;
 import org.eclipse.emf.ecore.impl.ENotificationImpl;
+import org.eclipse.emf.ecore.resource.Resource;
 import org.eclipse.emf.validation.model.EvaluationMode;
 import org.eclipse.emf.validation.service.IValidator;
 import org.eclipse.emf.validation.service.ModelValidationService;
@@ -20,24 +22,33 @@
 		if (notification.getNotifier() instanceof EObject) {
 			EObject object = (EObject)notification.getNotifier();
             if (notification.getEventType()==Notification.SET) {
-				Object o = notification.getFeature();
-				if (o instanceof EStructuralFeature) {
-					EStructuralFeature feature = (EStructuralFeature)o;
+				Object f = notification.getFeature();
+				if (f instanceof EStructuralFeature) {
+					EStructuralFeature feature = (EStructuralFeature)f;
+					EStructuralFeature idFeature = object.eClass().getEStructuralFeature("id");
+					EStructuralFeature nameFeature = object.eClass().getEStructuralFeature("name");
                     if ("name".equals(feature.getName())) {
 						Object newValue = notification.getNewValue();
 						Object oldValue = notification.getOldValue();
 						if (newValue!=oldValue && newValue!=null && !newValue.equals(oldValue))
 						{
-							EStructuralFeature id = object.eClass().getEStructuralFeature("id");
-							if (id!=null) {
+							if (idFeature!=null) {
 								newValue = SyntaxCheckerUtils.toNCName((String)newValue);
 								boolean deliver = object.eDeliver();
-								if (deliver)
-									object.eSetDeliver(false);
-								object.eSet(id, newValue);
-								if (deliver)
-									object.eSetDeliver(true);
-								
+								try {
+									if (deliver)
+										object.eSetDeliver(false);
+									
+									Object uniqueId = makeUniqueId(object,newValue);
+									object.eSet(nameFeature, uniqueId);
+									object.eSet(idFeature, uniqueId);
+								}
+								catch (Exception e) {
+									
+								}
+								finally {
+									object.eSetDeliver(deliver);
+								}								
 								validate(notification);
 							}
 						}
@@ -47,15 +58,22 @@
 						Object oldValue = notification.getOldValue();
 						if (newValue!=oldValue && newValue!=null && !newValue.equals(oldValue)) 
 						{
-							EStructuralFeature name = object.eClass().getEStructuralFeature("name");
-							if (name!=null) {
+							if (nameFeature!=null) {
 								boolean deliver = object.eDeliver();
-								if (deliver)
-									object.eSetDeliver(false);
-								object.eSet(name, newValue);
-								if (deliver)
-									object.eSetDeliver(true);
-								
+								try {
+									if (deliver)
+										object.eSetDeliver(false);
+									
+									Object uniqueId = makeUniqueId(object,newValue);
+									object.eSet(nameFeature, uniqueId);
+									object.eSet(idFeature, uniqueId);
+								}
+								catch (Exception e) {
+									
+								}
+								finally {
+									object.eSetDeliver(deliver);
+								}								
 								validate(notification);
 							}
 						}
@@ -68,6 +86,40 @@
 		}
 	}
 
+	private Object makeUniqueId(EObject object, Object id) {
+		int i = 1;
+		Object uniqueId = id;
+		EObject dup = null;
+		do {
+			dup = findDuplicateId(object,uniqueId);
+			if (dup!=null) {
+				uniqueId = id + "_" + i++;
+			}
+		}
+		while (dup!=null);
+		return uniqueId;
+	}
+	
+	private EObject findDuplicateId(EObject object, Object id) {
+		if (object!=null && id!=null) {
+			Resource resource = object.eResource();
+			
+			TreeIterator<EObject> iter = resource.getAllContents();
+			while (iter.hasNext()) {
+				EObject o = iter.next();
+				if (o!=object) {
+					EStructuralFeature f = o.eClass().getEStructuralFeature("id");
+					if (f!=null) {
+						Object existingId = o.eGet(f);
+						if (id.equals(existingId))
+							return o;
+					}
+				}
+			}
+		}
+		return null;
+	}
+	
 	@Override
 	public Notifier getTarget() {
 		// TODO Auto-generated method stub
diff --git a/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/GatewayConstraint.java b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/GatewayConstraint.java
index 1828bf9..ff8d1cd 100644
--- a/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/GatewayConstraint.java
+++ b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/GatewayConstraint.java
@@ -33,6 +33,8 @@
 
 			List<SequenceFlow> outgoingGwSequenceFlows = gw.getOutgoing();
 			if (outgoingGwSequenceFlows != null && outgoingGwSequenceFlows.size() > 0) {
+				// TODO: fix this
+				/*
 				int sum = 0;
 				for (SequenceFlow sf : outgoingGwSequenceFlows) {
 					// simulation validation
@@ -69,6 +71,7 @@
 				if (sum != 100) {
 					ctx.createFailureStatus("The sum of probability values of all outgoing Sequence Flows must be equal 100.");
 				}
+				*/
 			}
 		}
 		return ctx.createSuccessStatus();
diff --git a/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/TaskConstraint.java b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/TaskConstraint.java
index 6c31565..6022731 100644
--- a/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/TaskConstraint.java
+++ b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/TaskConstraint.java
@@ -28,6 +28,8 @@
 		if (eObj instanceof Task) {
 			Task ta = (Task) eObj;
 
+			// TODO: fix this
+			/*
 			if (ta.getExtensionValues() != null && ta.getExtensionValues().size() > 0) {
 				boolean foundDistributionType = false;
 				String distributionTypeValue = "";
@@ -113,6 +115,7 @@
 					}
 				}
 			}
+			*/
 		}
 		return ctx.createSuccessStatus();
 	}
diff --git a/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/UserTaskConstraint.java b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/UserTaskConstraint.java
index 6f49236..8262e9e 100644
--- a/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/UserTaskConstraint.java
+++ b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/UserTaskConstraint.java
@@ -13,7 +13,12 @@
 import java.util.Iterator;
 import java.util.List;
 
+import org.eclipse.bpmn2.Assignment;
+import org.eclipse.bpmn2.DataInput;
+import org.eclipse.bpmn2.DataInputAssociation;
 import org.eclipse.bpmn2.ExtensionAttributeValue;
+import org.eclipse.bpmn2.FormalExpression;
+import org.eclipse.bpmn2.ItemAwareElement;
 import org.eclipse.bpmn2.UserTask;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.emf.ecore.EObject;
@@ -31,59 +36,78 @@
 		if (eObj instanceof UserTask) {
 			UserTask ut = (UserTask)eObj;
 			
-			String taskName = null;
-			Iterator<FeatureMap.Entry> utiter = ut.getAnyAttribute().iterator();
-			boolean foundTaskName = false;
-			while (utiter.hasNext()) {
-				FeatureMap.Entry entry = utiter.next();
-				if (entry.getEStructuralFeature().getName().equals("taskName")) {
-					foundTaskName = true;
-					taskName = (String) entry.getValue();
-					if (taskName==null || taskName.isEmpty()) {
-						return ctx.createFailureStatus("User Task has no task name");
-					}
-				}
-			}
-			if (!foundTaskName) {
-				return ctx.createFailureStatus("User Task has no task name");
-			} else {
-				// TODO:
-				if (taskName != null) {
-					String[] packageAssetInfo = ServletUtil.findPackageAndAssetInfo(uuid, profile);
-					String taskFormName = taskName + "-taskform";
-					if (!ServletUtil.assetExistsInGuvnor(packageAssetInfo[0], taskFormName, profile)) {
-						ctx.createFailureStatus("User Task has no task form defined");
-					}
-				}
-			}
-
-			// simulation validation
-			if (ut.getExtensionValues() != null && ut.getExtensionValues().size() > 0) {
-				boolean foundStaffAvailability = false;
-				for (ExtensionAttributeValue extattrval : ut.getExtensionValues()) {
-					FeatureMap extensionElements = extattrval.getValue();
-					@SuppressWarnings("unchecked")
-					List<MetadataType> metadataTypeExtensions = (List<MetadataType>) extensionElements.get(
-							DroolsPackage.Literals.DOCUMENT_ROOT__METADATA, true);
-					if (metadataTypeExtensions != null && metadataTypeExtensions.size() > 0) {
-						MetadataType metaType = metadataTypeExtensions.get(0);
-						for (Object metaEntryObj : metaType.getMetaentry()) {
-							MetaentryType entry = (MetaentryType) metaEntryObj;
-							if (entry.getName() != null && entry.getName().equals("staffavailability")) {
-								Float f = new Float(entry.getValue());
-								if (f.floatValue() < 0) {
-									ctx.createFailureStatus("Staff Availability value must be positive");
+			try {
+				String taskName = null;
+				Iterator<FeatureMap.Entry> utiter = ut.getAnyAttribute().iterator();
+				for (DataInput di : ut.getIoSpecification().getDataInputs()) {
+					if ("TaskName".equalsIgnoreCase(di.getName())) {
+						for (DataInputAssociation dia : ut.getDataInputAssociations()) {
+							if (dia.getTargetRef() == di) {
+								if (dia.getAssignment().size()!=0) {
+									Assignment a = dia.getAssignment().get(0);
+									if (a.getFrom() instanceof FormalExpression) {
+										String body = ((FormalExpression)a.getFrom()).getBody();
+										if (body!=null && !body.isEmpty()) {
+											taskName = body;
+											break;
+										}
+									}
 								}
-								foundStaffAvailability = true;
 							}
 						}
 					}
-					if (!foundStaffAvailability) {
-						return ctx.createFailureStatus("User Task has no staff availability defined");
+				}
+				if (taskName==null) {
+					return ctx.createFailureStatus("User Task has no task name");
+				}
+				else {
+					// TODO:
+					if (taskName != null) {
+						String[] packageAssetInfo = ServletUtil.findPackageAndAssetInfo(uuid, profile);
+						String taskFormName = taskName + "-taskform";
+						if (!ServletUtil.assetExistsInGuvnor(packageAssetInfo[0], taskFormName, profile)) {
+							ctx.createFailureStatus("User Task has no task form defined");
+						}
 					}
 				}
+	
+				// simulation validation
+				// TODO: fix this
+				/*
+				if (ut.getExtensionValues() != null && ut.getExtensionValues().size() > 0) {
+					boolean foundStaffAvailability = false;
+					for (ExtensionAttributeValue extattrval : ut.getExtensionValues()) {
+						FeatureMap extensionElements = extattrval.getValue();
+						if (extensionElements!=null) {
+							@SuppressWarnings("unchecked")
+							List<MetadataType> metadataTypeExtensions = (List<MetadataType>) extensionElements.get(
+									DroolsPackage.Literals.DOCUMENT_ROOT__METADATA, true);
+							if (metadataTypeExtensions != null && metadataTypeExtensions.size() > 0) {
+								MetadataType metaType = metadataTypeExtensions.get(0);
+								for (Object metaEntryObj : metaType.getMetaentry()) {
+									MetaentryType entry = (MetaentryType) metaEntryObj;
+									if (entry.getName() != null && entry.getName().equals("staffavailability")) {
+										Float f = new Float(entry.getValue());
+										if (f.floatValue() < 0) {
+											ctx.createFailureStatus("User Task Simulation Parameter \"Staff Availability\" must be positive");
+										}
+										foundStaffAvailability = true;
+									}
+								}
+							}
+							if (!foundStaffAvailability) {
+								return ctx.createFailureStatus("User Task Simulation Parameter \"Staff Availability\" is not defined");
+							}
+						}
+					}
+				}
+				*/
 			}
-		}	
+			catch (Exception e) {
+				e.printStackTrace();
+				return ctx.createFailureStatus("Internal Validation Error for User Task: "+e.getMessage());
+			}	
+		}
 		return ctx.createSuccessStatus();
 	}
 
diff --git a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/property/connectors/SequenceFlowDetailComposite.java b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/property/connectors/SequenceFlowDetailComposite.java
index 5c028bf..bfaf5dd 100644
--- a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/property/connectors/SequenceFlowDetailComposite.java
+++ b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/property/connectors/SequenceFlowDetailComposite.java
@@ -28,6 +28,7 @@
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.SelectionAdapter;
 import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Point;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.widgets.Button;
 import org.eclipse.swt.widgets.Composite;
@@ -106,6 +107,12 @@
 				addRemoveConditionButton.setText("Remove Condition");
 				AbstractDetailComposite composite = PropertiesCompositeFactory.createDetailComposite(Expression.class, this, SWT.BORDER);
 				composite.setBusinessObject(exp);
+				// force the property page to resize to adjust for new expression section
+				Point size = composite.computeSize(-1, -1);
+				GridData gd = (GridData)composite.getLayoutData();
+				gd.widthHint = size.x;
+				gd.heightHint = size.y;
+				composite.setBusinessObject(exp);
 				composite.setTitle("Condition Expression");
 			}
 			else {
diff --git a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/views/outline/BaseElementTreeEditPart.java b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/views/outline/BaseElementTreeEditPart.java
index f75d03d..f061936 100644
--- a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/views/outline/BaseElementTreeEditPart.java
+++ b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/views/outline/BaseElementTreeEditPart.java
@@ -15,6 +15,7 @@
 import org.eclipse.bpmn2.DataInputAssociation;
 import org.eclipse.bpmn2.DataOutput;
 import org.eclipse.bpmn2.DataOutputAssociation;
+import org.eclipse.bpmn2.modeler.core.utils.ModelUtil;
 
 public class BaseElementTreeEditPart extends AbstractGraphicsTreeEditPart {
 
@@ -44,14 +45,14 @@
 			DataOutputAssociation doa = (DataOutputAssociation) getModel();
 			if (doa.getSourceRef().size()>0 && doa.getSourceRef().get(0) instanceof DataOutput) {
 				DataOutput d = (DataOutput) doa.getSourceRef().get(0);
-				return d.getName();
+				return ModelUtil.getDisplayName(d);
 			}
 		}
 		if (getModel() instanceof DataInputAssociation) {
 			DataInputAssociation doa = (DataInputAssociation) getModel();
 			if (doa.getTargetRef() instanceof DataInput) {
 				DataInput d = (DataInput) doa.getTargetRef();
-				return d.getName();
+				return ModelUtil.getDisplayName(d);
 			}
 		}