Starting to make some changes to parse nested BPMNPlanes, got hung up on what appears to be a bpmn2 metamodel problem: BPMNShapes can not contain BPMNPlanes
diff --git a/org.eclipse.bpmn2.modeler.core/META-INF/MANIFEST.MF b/org.eclipse.bpmn2.modeler.core/META-INF/MANIFEST.MF
index d412f0b..a733de7 100644
--- a/org.eclipse.bpmn2.modeler.core/META-INF/MANIFEST.MF
+++ b/org.eclipse.bpmn2.modeler.core/META-INF/MANIFEST.MF
@@ -1,70 +1,70 @@
-Manifest-Version: 1.0

-Bundle-ManifestVersion: 2

-Bundle-Name: BPMN2 Editor Core

-Bundle-SymbolicName: org.eclipse.bpmn2.modeler.core;singleton:=true

-Bundle-Version: 0.0.1.qualifier

-Bundle-Activator: org.eclipse.bpmn2.modeler.core.Activator

-Bundle-Vendor: Eclipse.org

-Require-Bundle: org.eclipse.emf.transaction,

- org.eclipse.emf.edit.ui,

- org.eclipse.emf.validation.ocl,

- org.eclipse.osgi,

- org.eclipse.graphiti;bundle-version="0.9.0",

- org.eclipse.graphiti.ui;bundle-version="0.9.0",

- org.eclipse.gef,

- org.eclipse.bpmn2.edit,

- org.eclipse.bpmn2.editor,

- org.eclipse.xsd,

- org.eclipse.wst.wsdl;bundle-version="[1.1.200,2.0.0)",

- org.eclipse.wst.xml.core;bundle-version="[1.1.300,2.0.0)",

- org.eclipse.xsd;bundle-version="[2.4.0,3.0.0)",

- org.eclipse.wst.sse.ui;bundle-version="[1.1.0,2.0.0)",

- org.eclipse.wst.sse.core;bundle-version="[1.1.300,2.0.0)",

- javax.wsdl;bundle-version="[1.5.0,1.6.0)";visibility:=reexport,

- org.eclipse.wst.xsd.ui;bundle-version="[1.2.101,2.0.0)",

- org.eclipse.wst.xml.ui;bundle-version="[1.0.400,2.0.0)",

- org.eclipse.jst.j2ee,

- org.eclipse.ui.ide,

- org.eclipse.core.commands,

- org.eclipse.jdt;bundle-version="3.7.1",

- org.eclipse.jdt.core;bundle-version="3.7.1",

- org.eclipse.jdt.launching;bundle-version="3.6.1",

- org.eclipse.ui.views.properties.tabbed;bundle-version="3.5.200",

- org.eclipse.jface.databinding;bundle-version="1.5.0",

- org.eclipse.core.databinding;bundle-version="1.4.0"

-Bundle-RequiredExecutionEnvironment: JavaSE-1.6

-Bundle-ActivationPolicy: lazy

-Export-Package: org.eclipse.bpmn2.modeler.core,

- org.eclipse.bpmn2.modeler.core.adapters,

- org.eclipse.bpmn2.modeler.core.di,

- org.eclipse.bpmn2.modeler.core.features,

- org.eclipse.bpmn2.modeler.core.features.activity,

- org.eclipse.bpmn2.modeler.core.features.activity.task,

- org.eclipse.bpmn2.modeler.core.features.artifact,

- org.eclipse.bpmn2.modeler.core.features.bendpoint,

- org.eclipse.bpmn2.modeler.core.features.choreography,

- org.eclipse.bpmn2.modeler.core.features.conversation,

- org.eclipse.bpmn2.modeler.core.features.data,

- org.eclipse.bpmn2.modeler.core.features.event,

- org.eclipse.bpmn2.modeler.core.features.event.definitions,

- org.eclipse.bpmn2.modeler.core.features.flow,

- org.eclipse.bpmn2.modeler.core.features.gateway,

- org.eclipse.bpmn2.modeler.core.features.lane,

- org.eclipse.bpmn2.modeler.core.features.participant,

- org.eclipse.bpmn2.modeler.core.merrimac.clad,

- org.eclipse.bpmn2.modeler.core.merrimac.dialogs,

- org.eclipse.bpmn2.modeler.core.merrimac.providers,

- org.eclipse.bpmn2.modeler.core.model,

- org.eclipse.bpmn2.modeler.core.preferences,

- org.eclipse.bpmn2.modeler.core.runtime,

- org.eclipse.bpmn2.modeler.core.utils,

- org.eclipse.bpmn2.modeler.core.validation

-Import-Package: org.eclipse.bpel.wsil.model.inspection,

- org.eclipse.graphiti.ui.features,

- org.eclipse.jface.util,

- org.eclipse.jface.viewers,

- org.eclipse.jface.preference,

- org.eclipse.swt.graphics,

- org.eclipse.ui,

- org.eclipse.ui.plugin,

- org.eclipse.ui.views.properties.tabbed

+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: BPMN2 Editor Core
+Bundle-SymbolicName: org.eclipse.bpmn2.modeler.core;singleton:=true
+Bundle-Version: 0.0.1.qualifier
+Bundle-Activator: org.eclipse.bpmn2.modeler.core.Activator
+Bundle-Vendor: Eclipse.org
+Require-Bundle: org.eclipse.emf.transaction,
+ org.eclipse.emf.edit.ui,
+ org.eclipse.emf.validation.ocl,
+ org.eclipse.osgi,
+ org.eclipse.graphiti;bundle-version="0.9.0",
+ org.eclipse.graphiti.ui;bundle-version="0.9.0",
+ org.eclipse.gef,
+ org.eclipse.bpmn2.edit,
+ org.eclipse.bpmn2.editor,
+ org.eclipse.xsd,
+ org.eclipse.wst.wsdl;bundle-version="[1.1.200,2.0.0)",
+ org.eclipse.wst.xml.core;bundle-version="[1.1.300,2.0.0)",
+ org.eclipse.xsd;bundle-version="[2.4.0,3.0.0)",
+ org.eclipse.wst.sse.ui;bundle-version="[1.1.0,2.0.0)",
+ org.eclipse.wst.sse.core;bundle-version="[1.1.300,2.0.0)",
+ javax.wsdl;bundle-version="[1.5.0,1.6.0)";visibility:=reexport,
+ org.eclipse.wst.xsd.ui;bundle-version="[1.2.101,2.0.0)",
+ org.eclipse.wst.xml.ui;bundle-version="[1.0.400,2.0.0)",
+ org.eclipse.jst.j2ee,
+ org.eclipse.ui.ide,
+ org.eclipse.core.commands,
+ org.eclipse.jdt;bundle-version="3.7.1",
+ org.eclipse.jdt.core;bundle-version="3.7.1",
+ org.eclipse.jdt.launching;bundle-version="3.6.1",
+ org.eclipse.ui.views.properties.tabbed;bundle-version="3.5.200",
+ org.eclipse.jface.databinding;bundle-version="1.5.0",
+ org.eclipse.core.databinding;bundle-version="1.4.0"
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Bundle-ActivationPolicy: lazy
+Export-Package: org.eclipse.bpmn2.modeler.core,
+ org.eclipse.bpmn2.modeler.core.adapters,
+ org.eclipse.bpmn2.modeler.core.di,
+ org.eclipse.bpmn2.modeler.core.features,
+ org.eclipse.bpmn2.modeler.core.features.activity,
+ org.eclipse.bpmn2.modeler.core.features.activity.task,
+ org.eclipse.bpmn2.modeler.core.features.artifact,
+ org.eclipse.bpmn2.modeler.core.features.bendpoint,
+ org.eclipse.bpmn2.modeler.core.features.choreography,
+ org.eclipse.bpmn2.modeler.core.features.conversation,
+ org.eclipse.bpmn2.modeler.core.features.data,
+ org.eclipse.bpmn2.modeler.core.features.event,
+ org.eclipse.bpmn2.modeler.core.features.event.definitions,
+ org.eclipse.bpmn2.modeler.core.features.flow,
+ org.eclipse.bpmn2.modeler.core.features.gateway,
+ org.eclipse.bpmn2.modeler.core.features.lane,
+ org.eclipse.bpmn2.modeler.core.features.participant,
+ org.eclipse.bpmn2.modeler.core.merrimac.clad,
+ org.eclipse.bpmn2.modeler.core.merrimac.dialogs,
+ org.eclipse.bpmn2.modeler.core.merrimac.providers,
+ org.eclipse.bpmn2.modeler.core.model,
+ org.eclipse.bpmn2.modeler.core.preferences,
+ org.eclipse.bpmn2.modeler.core.runtime,
+ org.eclipse.bpmn2.modeler.core.utils,
+ org.eclipse.bpmn2.modeler.core.validation
+Import-Package: org.eclipse.bpel.wsil.model.inspection,
+ org.eclipse.graphiti.ui.features,
+ org.eclipse.jface.util,
+ org.eclipse.jface.viewers,
+ org.eclipse.jface.preference,
+ org.eclipse.swt.graphics,
+ org.eclipse.ui,
+ org.eclipse.ui.plugin,
+ org.eclipse.ui.views.properties.tabbed
diff --git a/org.eclipse.bpmn2.modeler.core/plugin.xml b/org.eclipse.bpmn2.modeler.core/plugin.xml
index 7d567b2..326d751 100644
--- a/org.eclipse.bpmn2.modeler.core/plugin.xml
+++ b/org.eclipse.bpmn2.modeler.core/plugin.xml
@@ -1,111 +1,111 @@
-<?xml version="1.0" encoding="UTF-8"?>

-<?eclipse version="3.4"?>

-<plugin>

-   <extension-point id="org.eclipse.bpmn2.modeler.runtime" name="BPMN2 Modeler Runtime Specialization" schema="schema/org.eclipse.bpmn2.modeler.runtime.exsd"/>

-   

-	<!-- EMF Extensions -->

-   

-	<extension

-		point="org.eclipse.emf.ecore.factory_override">

-		<factory

-			class="org.eclipse.bpmn2.modeler.core.model.Bpmn2ModelerFactory"

-			uri="http://www.omg.org/spec/BPMN/20100524/MODEL-XMI">

-		</factory>

-	</extension>

-

-   <extension

-         point="org.eclipse.emf.validation.constraintProviders">

-      <category

-            name="Core BPMN 2.0 Constraints"

-            id="org.eclipse.bpmn2.modeler.core.validation"/>

-      <constraintProvider cache="true">

-         <package namespaceUri="http://www.omg.org/spec/BPMN/20100524/MODEL-XMI"/>

-         <constraints categories="org.eclipse.bpmn2.modeler.core.validation">

-            <constraint

-                  lang="Java"

-                  class="org.eclipse.bpmn2.modeler.core.validation.ValidIdConstraint"

-                  severity="CANCEL"

-                  mode="Live"

-                  name="Valid IDs"

-                  id="org.eclipse.bpmn2.modeler.core.validation.ValidId"

-                  statusCode="1">

-               <description>

-                  IDs must be valid.

-               </description>

-               <message>

-                  The {0} ID must be a valid ID.

-               </message>

-               <target class="BaseElement">

-                  <event name="Set">

-                     <feature name="id"/>

-                  </event>

-                  <event name="Unset">

-                     <feature name="id"/>

-                  </event>

-               </target>

-            </constraint>

-            <constraint

-			        lang="OCL"

-			         severity="CANCEL"

-			         mode="Live"

-			         name="StartEventIncoming"

-			         id="org.eclipse.bpmn2.modeler.core.validation.StartEvent.incoming"

-			         statusCode="2" isEnabledByDefault="true">

-			      <description>Start Event must not have incoming flows</description>

-			      <message>Start Event must not have incoming sequence flows.</message>

-			      <target class="StartEvent" />

-			      <![CDATA[

-			      	self.incoming->isEmpty()

-			      ]]>

-			</constraint>

-			<constraint

-			        lang="OCL"

-			         severity="CANCEL"

-			         mode="Live"

-			         name="EndEventOutgoing"

-			         id="org.eclipse.bpmn2.modeler.core.validation.EndEvent.outgoing"

-			         statusCode="3" isEnabledByDefault="true">

-			      <description>End Event must not have outgoing flows</description>

-			      <message>End Event must not have outgoing sequence flows.</message>

-			      <target class="EndEvent" />

-			      <![CDATA[

-			         self.outgoing->isEmpty()

-			      ]]>

-			</constraint>

-			<constraint

-			        lang="OCL"

-			         severity="CANCEL"

-			         mode="Live"

-			         name="UniqueId"

-			         id="org.eclipse.bpmn2.modeler.core.validation.BaseElement.id"

-			         statusCode="3" isEnabledByDefault="true">

-			      <description>ID needs to be unique.</description>

-			      <message>ID needs to be unqiue.</message>

-			      <target class="BaseElement" />

-					<![CDATA[

-						self.id->notEmpty() implies bpmn2::BaseElement.allInstances()->select(s | s.id = self.id)->size() <= 1

-					]]>

-			</constraint>

-         </constraints>

-      </constraintProvider>

-   </extension>

-

-   <extension

-         point="org.eclipse.emf.validation.constraintBindings">

-      <clientContext

-            default="false"

-            id="org.eclipse.bpmn2.modeler.core.validationContext">

-         <selector class="org.eclipse.bpmn2.modeler.core.validation.ValidationDelegateClientSelector"/>

-      </clientContext>

-      <binding

-            context="org.eclipse.bpmn2.modeler.core.validationContext"

-            category="org.eclipse.bpmn2.modeler.core.validation"/>

-   </extension>

-	

-	<extension point="org.eclipse.emf.validation.validationListeners">

-		<listener class="org.eclipse.bpmn2.modeler.core.validation.ProblemsReporter">

-			<clientContext id="org.eclipse.bpmn2.modeler.core.validationContext"/>

-		</listener>

-	</extension>

-

-</plugin>

+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+   <extension-point id="org.eclipse.bpmn2.modeler.runtime" name="BPMN2 Modeler Runtime Specialization" schema="schema/org.eclipse.bpmn2.modeler.runtime.exsd"/>
+   
+	<!-- EMF Extensions -->
+   
+	<extension
+		point="org.eclipse.emf.ecore.factory_override">
+		<factory
+			class="org.eclipse.bpmn2.modeler.core.model.Bpmn2ModelerFactory"
+			uri="http://www.omg.org/spec/BPMN/20100524/MODEL-XMI">
+		</factory>
+	</extension>
+
+   <extension
+         point="org.eclipse.emf.validation.constraintProviders">
+      <category
+            name="Core BPMN 2.0 Constraints"
+            id="org.eclipse.bpmn2.modeler.core.validation"/>
+      <constraintProvider cache="true">
+         <package namespaceUri="http://www.omg.org/spec/BPMN/20100524/MODEL-XMI"/>
+         <constraints categories="org.eclipse.bpmn2.modeler.core.validation">
+            <constraint
+                  lang="Java"
+                  class="org.eclipse.bpmn2.modeler.core.validation.ValidIdConstraint"
+                  severity="CANCEL"
+                  mode="Live"
+                  name="Valid IDs"
+                  id="org.eclipse.bpmn2.modeler.core.validation.ValidId"
+                  statusCode="1">
+               <description>
+                  IDs must be valid.
+               </description>
+               <message>
+                  The {0} ID must be a valid ID.
+               </message>
+               <target class="BaseElement">
+                  <event name="Set">
+                     <feature name="id"/>
+                  </event>
+                  <event name="Unset">
+                     <feature name="id"/>
+                  </event>
+               </target>
+            </constraint>
+            <constraint
+			        lang="OCL"
+			         severity="CANCEL"
+			         mode="Live"
+			         name="StartEventIncoming"
+			         id="org.eclipse.bpmn2.modeler.core.validation.StartEvent.incoming"
+			         statusCode="2" isEnabledByDefault="true">
+			      <description>Start Event must not have incoming flows</description>
+			      <message>Start Event must not have incoming sequence flows.</message>
+			      <target class="StartEvent" />
+			      <![CDATA[
+			      	self.incoming->isEmpty()
+			      ]]>
+			</constraint>
+			<constraint
+			        lang="OCL"
+			         severity="CANCEL"
+			         mode="Live"
+			         name="EndEventOutgoing"
+			         id="org.eclipse.bpmn2.modeler.core.validation.EndEvent.outgoing"
+			         statusCode="3" isEnabledByDefault="true">
+			      <description>End Event must not have outgoing flows</description>
+			      <message>End Event must not have outgoing sequence flows.</message>
+			      <target class="EndEvent" />
+			      <![CDATA[
+			         self.outgoing->isEmpty()
+			      ]]>
+			</constraint>
+			<constraint
+			        lang="OCL"
+			         severity="CANCEL"
+			         mode="Live"
+			         name="UniqueId"
+			         id="org.eclipse.bpmn2.modeler.core.validation.BaseElement.id"
+			         statusCode="3" isEnabledByDefault="true">
+			      <description>ID needs to be unique.</description>
+			      <message>ID needs to be unqiue.</message>
+			      <target class="BaseElement" />
+					<![CDATA[
+						self.id->notEmpty() implies bpmn2::BaseElement.allInstances()->select(s | s.id = self.id)->size() <= 1
+					]]>
+			</constraint>
+         </constraints>
+      </constraintProvider>
+   </extension>
+
+   <extension
+         point="org.eclipse.emf.validation.constraintBindings">
+      <clientContext
+            default="false"
+            id="org.eclipse.bpmn2.modeler.core.validationContext">
+         <selector class="org.eclipse.bpmn2.modeler.core.validation.ValidationDelegateClientSelector"/>
+      </clientContext>
+      <binding
+            context="org.eclipse.bpmn2.modeler.core.validationContext"
+            category="org.eclipse.bpmn2.modeler.core.validation"/>
+   </extension>
+	
+	<extension point="org.eclipse.emf.validation.validationListeners">
+		<listener class="org.eclipse.bpmn2.modeler.core.validation.ProblemsReporter">
+			<clientContext id="org.eclipse.bpmn2.modeler.core.validationContext"/>
+		</listener>
+	</extension>
+
+</plugin>
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/ModelHandler.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/ModelHandler.java
index 27f656b..ed3be78 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/ModelHandler.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/ModelHandler.java
@@ -15,6 +15,8 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
 
 import org.eclipse.bpmn2.Artifact;
 import org.eclipse.bpmn2.Association;
@@ -75,6 +77,8 @@
 import org.eclipse.emf.ecore.EPackage;
 import org.eclipse.emf.ecore.resource.Resource;
 import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.util.BasicFeatureMap;
+import org.eclipse.emf.ecore.xml.type.AnyType;
 import org.eclipse.emf.transaction.RecordingCommand;
 import org.eclipse.emf.transaction.TransactionalEditingDomain;
 import org.eclipse.emf.transaction.util.TransactionUtil;
@@ -785,6 +789,15 @@
 	void loadResource() {
 		try {
 			resource.load(null);
+			Map<EObject, AnyType> xmap = resource.getEObjectToExtensionMap();
+			for (Entry<EObject, AnyType> entry : xmap.entrySet()) {
+				EObject o = entry.getKey();
+				System.out.println(o);
+				BasicFeatureMap fm = (BasicFeatureMap) entry.getValue().getMixed();
+				for (org.eclipse.emf.ecore.util.FeatureMap.Entry e : fm) {
+					System.out.println("feature:"+e.getEStructuralFeature().getName());
+				}
+			}
 		} catch (IOException e) {
 			Activator.logError(e);
 		}
@@ -911,20 +924,26 @@
 				return plane;
 			
 			List<DiagramElement> planeElement = plane.getPlaneElement();
-			
-			for (DiagramElement elem : planeElement) {
-				if (elem instanceof BPMNShape && ((BPMNShape) elem).getBpmnElement() != null &&
-						id.equals(((BPMNShape) elem).getBpmnElement().getId())) {
-					return (elem);
-				} else if (elem instanceof BPMNEdge &&
-						id.equals(((BPMNEdge) elem).getBpmnElement().getId())) {
-					return (elem);
-				}
-			}
+			return findDIElement(planeElement, id);
 		}
 		return null;
 	}
 
+	public DiagramElement findDIElement(List<DiagramElement> planeElements, String id) {
+		for (DiagramElement elem : planeElements) {
+			if (elem instanceof BPMNShape && ((BPMNShape) elem).getBpmnElement() != null &&
+					id.equals(((BPMNShape) elem).getBpmnElement().getId())) {
+				return elem;
+			} else if (elem instanceof BPMNEdge &&
+					id.equals(((BPMNEdge) elem).getBpmnElement().getId())) {
+				return elem;
+			} else if (elem instanceof BPMNPlane) {
+				return findDIElement(((BPMNPlane)elem).getPlaneElement(), id);
+			}
+		}
+		return null;
+	}
+	
 	public BaseElement findElement(String id) {
 		if (id==null || id.isEmpty())
 			return null;
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/di/DIImport.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/di/DIImport.java
index 630bda6..0fc188f 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/di/DIImport.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/di/DIImport.java
@@ -211,8 +211,17 @@
 					shapeQueue.offer(diShape);
 				}
 			}
+			else if (diagramElement instanceof BPMNPlane) {
+				List<DiagramElement> oe = ((BPMNPlane)diagramElement).getPlaneElement();
+				processShapes(shapeQueue);
+				importShapes(oe);
+				importConnections(oe);
+			}
 		}
-		
+		processShapes(shapeQueue);
+	}
+	
+	private void processShapes(Queue<BPMNShape> shapeQueue) {
 		// Process Queue
 		// First pass tries to find the missing BPMNShape container
 		// Second pass synthesizes missing containers 
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/di/DIUtils.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/di/DIUtils.java
index 03f57f2..3401ec1 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/di/DIUtils.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/di/DIUtils.java
@@ -196,15 +196,23 @@
 		for (BPMNDiagram d : diagrams) {
 			BPMNPlane plane = d.getPlane();
 			List<DiagramElement> planeElements = plane.getPlaneElement();
-			for (DiagramElement de : planeElements) {
-				if (de instanceof BPMNShape) {
-					if (bpmnElement == ((BPMNShape)de).getBpmnElement())
-						return de;
-				}
-				if (de instanceof BPMNEdge) {
-					if (bpmnElement == ((BPMNEdge)de).getBpmnElement())
-						return de;
-				}
+			return findPlaneElement(planeElements, bpmnElement);
+		}
+		return null;
+	}
+
+	public static DiagramElement findPlaneElement(List<DiagramElement> planeElements, BaseElement bpmnElement) {
+		for (DiagramElement de : planeElements) {
+			if (de instanceof BPMNShape) {
+				if (bpmnElement == ((BPMNShape)de).getBpmnElement())
+					return de;
+			}
+			if (de instanceof BPMNEdge) {
+				if (bpmnElement == ((BPMNEdge)de).getBpmnElement())
+					return de;
+			}
+			else if (de instanceof BPMNPlane) {
+				return findPlaneElement(((BPMNPlane)de).getPlaneElement(), bpmnElement);
 			}
 		}
 		return null;
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 bfed3be..d4c8a2e 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
@@ -1,610 +1,619 @@
-/*******************************************************************************

- * Copyright (c) 2011 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 Bob Brodt

- ******************************************************************************/

-/**

- * <copyright>

- * 

- * Copyright (c) 2010 SAP AG.

- * All rights reserved. This program and the accompanying materials

- * are 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:

- *    Reiner Hille-Doering (SAP AG) - initial API and implementation and/or initial documentation

- * 

- * </copyright>

- */

-package org.eclipse.bpmn2.modeler.core.model;

-

-import java.util.ArrayList;

-import java.util.Hashtable;

-import java.util.Iterator;

-import java.util.List;

-import java.util.Map;

-

-import org.eclipse.bpmn2.Bpmn2Package;

-import org.eclipse.bpmn2.Definitions;

-import org.eclipse.bpmn2.Import;

-import org.eclipse.bpmn2.ItemDefinition;

-import org.eclipse.bpmn2.Lane;

-import org.eclipse.bpmn2.Participant;

-import org.eclipse.bpmn2.RootElement;

-import org.eclipse.bpmn2.di.BPMNDiagram;

-import org.eclipse.bpmn2.di.BPMNEdge;

-import org.eclipse.bpmn2.di.BPMNLabel;

-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.preferences.Bpmn2Preferences;

-import org.eclipse.bpmn2.modeler.core.runtime.TargetRuntime;

-import org.eclipse.bpmn2.modeler.core.utils.ModelUtil;

-import org.eclipse.bpmn2.util.Bpmn2ResourceImpl;

-import org.eclipse.bpmn2.util.ImportHelper;

-import org.eclipse.bpmn2.util.QNameURIHandler;

-import org.eclipse.core.runtime.IStatus;

-import org.eclipse.core.runtime.Status;

-import org.eclipse.dd.dc.Bounds;

-import org.eclipse.dd.dc.DcPackage;

-import org.eclipse.dd.dc.Point;

-import org.eclipse.dd.di.DiPackage;

-import org.eclipse.dd.di.DiagramElement;

-import org.eclipse.emf.common.util.EList;

-import org.eclipse.emf.common.util.TreeIterator;

-import org.eclipse.emf.common.util.URI;

-import org.eclipse.emf.ecore.EClass;

-import org.eclipse.emf.ecore.EObject;

-import org.eclipse.emf.ecore.EPackage;

-import org.eclipse.emf.ecore.EReference;

-import org.eclipse.emf.ecore.EStructuralFeature;

-import org.eclipse.emf.ecore.resource.Resource;

-import org.eclipse.emf.ecore.util.ExtendedMetaData;

-import org.eclipse.emf.ecore.xmi.XMLHelper;

-import org.eclipse.emf.ecore.xmi.XMLLoad;

-import org.eclipse.emf.ecore.xmi.XMLResource;

-import org.eclipse.emf.ecore.xmi.XMLSave;

-import org.eclipse.emf.ecore.xmi.impl.XMLLoadImpl;

-import org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl;

-import org.xml.sax.helpers.DefaultHandler;

-

-/**

- * <!-- begin-user-doc --> The <b>Resource </b> associated with the package.

- * 

- * @implements Bpmn2Resource <!-- end-user-doc -->

- * @see org.eclipse.bpmn2.util.Bpmn2ResourceFactoryImpl

- */

-public class Bpmn2ModelerResourceImpl extends Bpmn2ResourceImpl {

-

-	public static final String BPMN2_CONTENT_TYPE_ID = "org.eclipse.bpmn2.content-type.xml";

-	protected BpmnXmlHelper xmlHelper;

-	protected QNameURIHandler uriHandler;

-

-	/**

-	 * Creates an instance of the resource.

-	 * 

-	 * @param uri

-	 *            the URI of the new resource.

-	 */

-	public Bpmn2ModelerResourceImpl(URI uri) {

-		super(uri);

-		

-		// overwrite helper and uri handler in options map

-		this.xmlHelper = new Bpmn2ModelerXmlHelper(this);

-        this.uriHandler = new FragmentQNameURIHandler(xmlHelper);

-        this.getDefaultLoadOptions().put(XMLResource.OPTION_URI_HANDLER, uriHandler);

-        this.getDefaultLoadOptions().put(XMLResource.OPTION_DEFER_IDREF_RESOLUTION, true);

-        this.getDefaultSaveOptions().put(XMLResource.OPTION_URI_HANDLER, uriHandler);

-

-        // only necessary if this resource will not be added to a ResourceSet instantly

-        this.eAdapters().add(oppositeReferenceAdapter);

-	}

-

-    @Override

-    protected XMLHelper createXMLHelper() {

-        return this.xmlHelper;

-    }

-

-	/**

-	 * Override this method to hook in our own XmlHandler

-	 */

-	@Override

-	protected XMLLoad createXMLLoad() {

-		return new XMLLoadImpl(createXMLHelper()) {

-			@Override

-			protected DefaultHandler makeDefaultHandler() {

-				return new Bpmn2ModelerXmlHandler(resource, helper, options);

-			}

-		};

-	}

-

-	@Override

-	protected XMLSave createXMLSave() {

-		return new Bpmn2ModelerXMLSave(createXMLHelper()) {

-		};

-	}

-

-	@Override

-	protected void prepareSave() {

-		EObject cur;

-		Definitions thisDefinitions = ImportHelper.getDefinitions(this);

-		for (Iterator<EObject> iter = getAllContents(); iter.hasNext();) {

-			cur = iter.next();

-

-			setDefaultId(cur);

-

-			for (EObject referenced : cur.eCrossReferences()) {

-				setDefaultId(referenced);

-				if (thisDefinitions != null) {

-					Resource refResource = referenced.eResource();

-					if (refResource != null && refResource != this) {

-						createImportIfNecessary(thisDefinitions, refResource);

-					}

-				}

-			}

-		}

-	}

-

-	/**

-	 * Set the ID attribute of cur to a generated ID, if it is not already set.

-	 * 

-	 * @param obj

-	 *            The object whose ID should be set.

-	 */

-	private void setDefaultId(EObject obj) {

-		if (obj.eClass() != null) {

-			EStructuralFeature idAttr = obj.eClass().getEIDAttribute();

-			if (idAttr != null && !obj.eIsSet(idAttr)) {

-				ModelUtil.setID(obj);

-			}

-		}

-	}

-

-	/**

-	 * We need extend the standard SAXXMLHandler to hook into the handling of

-	 * attribute references which may be either simple ID Strings or QNames.

-	 * We'll search through all of the objects' IDs first to find the one we're

-	 * looking for. If not, we'll try a QName search.

-	 */

-	protected static class Bpmn2ModelerXmlHandler extends BpmnXmlHandler {

-

-		Bpmn2Preferences prefs = null;

-		

-		public Bpmn2ModelerXmlHandler(XMLResource xmiResource, XMLHelper helper, Map<?, ?> options) {

-			super(xmiResource, helper, options);

-		}

-

-		@Override

-		protected void handleObjectAttribs(EObject obj) {

-			super.handleObjectAttribs(obj);

-			if (obj instanceof BPMNShape) {

-				BPMNShape bpmnShape = (BPMNShape)obj;

-

-				Hashtable<String,String> map = new Hashtable<String,String>();

-				if (attribs != null) {

-					for (int i = 0, size = attribs.getLength(); i < size; ++i) {

-						String key = attribs.getQName(i);

-						String value = attribs.getValue(i);

-						map.put(key, value);

-					}

-					Bpmn2Preferences.getInstance(this.resourceURI).applyBPMNDIDefaults(bpmnShape, map);

-				}

-			}

-			else if (obj instanceof ItemDefinition) {

-				ItemDefinition itemDef = (ItemDefinition)obj;

-

-				Definitions definitions = ImportHelper.getDefinitions(xmlResource);

-				URI referencingURI = ImportHelper.makeURICanonical(resourceURI);

-				String location = ModelUtil.getStringWrapperValue(itemDef.getStructureRef());

-				if (location!=null) {

-					int i = location.indexOf("$");

-					if (i>0)

-						location = location.substring(0,i);

-					URI uri = URI.createURI(location).resolve(referencingURI);

-					uri = uri.trimFragment();

-					Import imp = ImportHelper.findImportForLocation(definitions, uri);

-					itemDef.setImport(imp);

-				}

-			}

-		}

-

-		/**

-		 * Overridden to be able to convert ID references in attributes to URIs

-		 * during load. If the reference can't be found by its ID, we'll try a

-		 * QName search (done in the super class)

-		 * 

-		 * @param ids

-		 *            In our case the parameter will contain exactly one ID that

-		 *            we resolve to URI.

-		 */

-		@Override

-		protected void setValueFromId(EObject object, EReference eReference, String ids) {

-

-			for (EObject o : objects) {

-				TreeIterator<EObject> iter = o.eAllContents();

-				while (iter.hasNext()) {

-					EObject obj = iter.next();

-					EStructuralFeature feature = ((EObject) obj).eClass().getEIDAttribute();

-					if (feature != null && obj.eGet(feature) != null) {

-						Object id = obj.eGet(feature);

-						if (id != null && id.equals(ids)) {

-							try {

-								if (object.eGet(eReference) instanceof EList) {

-									((EList)object.eGet(eReference)).add(obj);

-								}

-								else {

-									object.eSet(eReference, obj);

-								}

-							} catch (Exception e) {

-								String msg = "Invalid or unknown reference from:\n  " +

-										object + "\nfeature:\n  " + eReference +

-										"\nto:\n  " + obj;

-								IStatus s = new Status(Status.ERROR, Activator.PLUGIN_ID,

-										msg, e);

-								Activator.getDefault().logStatus(s);

-							}

-							return;

-						}

-					}

-				}

-			}

-

-			// hack to handle QNames and arbitrary strings in structureRefs

-			if (eReference.getName().equals("structureRef") && object instanceof ItemDefinition) {

-				object.eSet(eReference, ModelUtil.createStringWrapper(ids));

-				return;

-			}

-

-			super.setValueFromId(object, eReference, ids);

-		}

-	}

-	

-	public static class Bpmn2ModelerXMLSave extends XMLSaveImpl {

-		protected float minX = Float.MAX_VALUE;

-		protected float minY = Float.MAX_VALUE;

-

-		public Bpmn2ModelerXMLSave(XMLHelper helper) {

-			super(helper);

-			helper.getPrefixToNamespaceMap().clear();

-		}

-

-		@Override

-		protected void init(XMLResource resource, Map<?, ?> options) {

-			super.init(resource, options);

-			featureTable = new Bpmn2ModelerXMLSave.Bpmn2Lookup(map, extendedMetaData, elementHandler);

-			

-			final List<BPMNDiagram> diagrams = getAll(BPMNDiagram.class, resource);

-			for (BPMNDiagram bpmnDiagram : diagrams) {

-				findMinXY(bpmnDiagram);

-			}

-			

-		}

-		

-        @Override

-        protected boolean shouldSaveFeature(EObject o, EStructuralFeature f) {

-            if (o instanceof BPMNShape && f==BpmnDiPackage.eINSTANCE.getBPMNShape_IsHorizontal()) {

-            	BPMNShape s = (BPMNShape)o;

-            	if (s.getBpmnElement() instanceof Lane || s.getBpmnElement() instanceof Participant)

-            		return true;

-            }

-            

-            // we also want to store x and y with value zero, would be skipped because of default value otherwise

-            if (o instanceof Bounds) {

-            	return true;

-            }

-            

-            return super.shouldSaveFeature(o, f);

-        }

-		

-		protected <T> List<T> getAll(Class<T> class1, Resource resource) {

-			ArrayList<T> l = new ArrayList<T>();

-			TreeIterator<EObject> contents = resource.getAllContents();

-			for (; contents.hasNext();) {

-				Object t = contents.next();

-				if (class1.isInstance(t)) {

-					l.add((T) t);

-				}

-			}

-			return l;

-		}

-		

-		protected void findMinXY(BPMNDiagram bpmnDiagram) {

-			EList<DiagramElement> elements = (EList<DiagramElement>) bpmnDiagram.getPlane().getPlaneElement();

-			for (DiagramElement e : elements) {

-				if (e instanceof BPMNShape) {

-					Bounds b = ((BPMNShape)e).getBounds();

-					minX = Math.min(minX, b.getX());

-					minY = Math.min(minY, b.getY());

-				}

-				else if (e instanceof BPMNEdge) {

-					List<Point> points = ((BPMNEdge)e).getWaypoint();

-					for (Point p : points) {

-						minX = Math.min(minX, p.getX());

-						minY = Math.min(minY, p.getY());

-					}

-

-				}

-				else if (e instanceof BPMNLabel) {

-					Bounds b = ((BPMNLabel)e).getBounds();

-					minX = Math.min(minX, b.getX());

-					minY = Math.min(minY, b.getY());

-				}

-			}

-		}

-

-		@Override

-		protected void saveElement(EObject o, EStructuralFeature f) {

-			float oldX = 0, oldY = 0;

-			List<Point> oldPoints = null;

-			

-			if (o instanceof BPMNShape) {

-				Bounds b = ((BPMNShape)o).getBounds();

-				if (minX<0) {

-					oldX = b.getX();

-					b.setX(oldX - minX);

-				}

-				if (minY<0) {

-					oldY = b.getY();

-					b.setY(oldY - minY);

-				}

-			}

-			else if (o instanceof BPMNEdge) {

-				List<Point> points = ((BPMNEdge)o).getWaypoint();

-				oldPoints = new ArrayList<Point>();

-				oldPoints.addAll(points);

-				for (Point p : points) {

-					if (minX<0)

-						p.setX( p.getX() - minX);

-					if (minY<0)

-						p.setY( p.getY() - minY);

-				}

-			}

-			else if (o instanceof BPMNLabel) {

-				Bounds b = ((BPMNLabel)o).getBounds();

-				if (b!=null) {

-					if (minX<0) {

-						oldX = b.getX();

-						b.setX(oldX - minX);

-					}

-					if (minY<0) {

-						oldY = b.getY();

-						b.setY(oldY - minY);

-					}

-				}

-			}

-

-			super.saveElement(o, f);

-			

-			if (o instanceof BPMNShape) {

-				Bounds b = ((BPMNShape)o).getBounds();

-				if (minX<0) {

-					b.setX(oldX);

-				}

-				if (minY<0) {

-					b.setY(oldY);

-				}

-			}

-			else if (o instanceof BPMNEdge) {

-				List<Point> points = ((BPMNEdge)o).getWaypoint();

-				int index = 0;

-				for (Point p : points) {

-					if (minX<0)

-						p.setX(oldPoints.get(index).getX());

-					if (minY<0)

-						p.setY(oldPoints.get(index).getY());

-					++index;

-				}

-			}

-			else if (o instanceof BPMNLabel) {

-				Bounds b = ((BPMNLabel)o).getBounds();

-				if (b!=null) {

-					if (minX<0) {

-						b.setX(oldX);

-					}

-					if (minY<0) {

-						b.setY(oldY);

-					}

-				}

-			}

-			

-		}

-

-		@Override

-		public void traverse(List<? extends EObject> contents) {

-			for (EObject e : contents) {

-				if (e instanceof Definitions) {

-					List<RootElement> roots = ((Definitions) e).getRootElements();

-					Process p = null;

-					for (RootElement root : roots) {

-						if (root instanceof Process) {

-							p = (Process) root;

-						}

-					}

-					if (p != null) {

-						((Definitions) e).getRootElements().remove(p);

-						((Definitions) e).getRootElements().add((RootElement) p);

-					}

-				}

-			}

-			super.traverse(contents);

-		}

-

-		public static class Bpmn2Lookup extends XMLSaveImpl.Lookup {

-			public Bpmn2Lookup(XMLMap map, ExtendedMetaData extendedMetaData, ElementHandler elementHandler) {

-				super(map, extendedMetaData, elementHandler);

-			}

-

-			@Override

-			public EStructuralFeature[] getFeatures(EClass cls) {

-				int index = getIndex(cls);

-				EClass c = classes[index];

-

-				if (c == cls) {

-					return features[index];

-				}

-

-				EStructuralFeature[] featureList = listFeatures(cls);

-				if (c == null) {

-					classes[index] = cls;

-					features[index] = featureList;

-					featureKinds[index] = listKinds(featureList);

-				}

-

-				if (cls.getName().equalsIgnoreCase("Process")) {

-					EStructuralFeature[] modifiedFeatureList = getModifiedProcessFeatureSet(featureList);

-					if (c == null) {

-						classes[index] = cls;

-						features[index] = modifiedFeatureList;

-						featureKinds[index] = listKinds(modifiedFeatureList);

-					}

-					return modifiedFeatureList;

-				}

-				return featureList;

-			}

-		}

-

-		private static EStructuralFeature[] getModifiedProcessFeatureSet(EStructuralFeature[] processFeatureList) {

-			/**

-			 * Feature list for Process provided by eclipse.bpmn2: -

-			 * extensionDefinitions (0) - id (1) - anyAttribute (2) - name (3) -

-			 * definitionalCollaborationRef (4) - isClosed (5) - isExecutable

-			 * (6) - processType (7) - extensionValues (8) - documentation (9) -

-			 * supportedInterfaceRefs (10) - ioSpecification (11) - ioBinding

-			 * (12) - laneSets (13) - flowElements (14) - auditing (15) -

-			 * monitoring (16) - properties (17) - artifacts (18) - resources

-			 * (19) - correlationSubscriptions (20) - supports (21) Semantic.xsd

-			 * sequence definition for Process: <xsd:sequence> <xsd:element

-			 * ref="auditing" minOccurs="0" maxOccurs="1"/> <xsd:element

-			 * ref="monitoring" minOccurs="0" maxOccurs="1"/> <xsd:element

-			 * ref="property" minOccurs="0" maxOccurs="unbounded"/> <xsd:element

-			 * ref="laneSet" minOccurs="0" maxOccurs="unbounded"/> <xsd:element

-			 * ref="flowElement" minOccurs="0" maxOccurs="unbounded"/>

-			 * <xsd:element ref="artifact" minOccurs="0" maxOccurs="unbounded"/>

-			 * <xsd:element ref="resourceRole" minOccurs="0"

-			 * maxOccurs="unbounded"/> <xsd:element

-			 * ref="correlationSubscription" minOccurs="0"

-			 * maxOccurs="unbounded"/> <xsd:element name="supports"

-			 * type="xsd:QName" minOccurs="0" maxOccurs="unbounded"/>

-			 * </xsd:sequence>

-			 * 

-			 * Moving auditing, monitoring, property above flowElements...

-			 */

-

-			EStructuralFeature[] retArray = new EStructuralFeature[processFeatureList.length];

-			for (int i = 0; i < 13; i++) {

-				retArray[i] = processFeatureList[i];

-			}

-			retArray[13] = processFeatureList[15]; // auditing

-			retArray[14] = processFeatureList[16]; // monitoring

-			retArray[15] = processFeatureList[17]; // properties

-			retArray[16] = processFeatureList[13]; // lanesets

-			retArray[17] = processFeatureList[14]; // flow elements

-			retArray[18] = processFeatureList[18]; // artifacts

-			retArray[19] = processFeatureList[19]; // resources

-			retArray[20] = processFeatureList[20]; // correlationSubscriptions

-			retArray[21] = processFeatureList[21]; // supports

-

-			return retArray;

-		}

-	}

-	

-	// TODO check this, is this the correct way to deal with this ID prefixes

-	/**

-	 * QName handler to make create URIs out of the fragment, which is the local part of the QName

-	 * 

-	 * Most other tools dont understand QNames in referencing attributes

-	 * 

-	 * @author drobisch

-	 *

-	 */

-	public static class FragmentQNameURIHandler extends QNameURIHandler {

-

-		protected BpmnXmlHelper xmlHelper;

-

-		public FragmentQNameURIHandler(BpmnXmlHelper xmlHelper) {

-			super(xmlHelper);

-			this.xmlHelper = xmlHelper;

-		}

-

-		@Override

-		public URI deresolve(URI uri) {

-			String fragment = uri.fragment();

-			if (fragment != null && !fragment.startsWith("/")) {

-				// return just fragment (i.e. without the '#'), always assume

-				// local reference

-				return URI.createURI(fragment);

-			}

-			return super.deresolve(uri);

-		}

-

-		@Override

-		public String convertQNameToUri(String qName) {

-			if (qName.contains("#") || qName.contains("/")) {

-				// We already have an URI and not QName, e.g. URL

-				return qName;

-			}

-

-			// Split into prefix and local part (fragment)

-			String[] parts = qName.split(":");

-			String prefix, fragment;

-			if (parts.length == 1) {

-				prefix = null;

-				fragment = qName;

-			} else if (parts.length == 2) {

-				prefix = parts[0];

-				fragment = parts[1];

-			} else

-				throw new IllegalArgumentException("Illegal QName: " + qName);

-

-			if (fragment.contains(".")) {

-				// HACK: officially IDs can contain ".", but unfortunately

-				// XmlHandler calls resolve also for xsi:schemaLocation stuff

-				// and similar, that are

-				// NO URIs. We must not process them.

-				return qName;

-			}

-

-			boolean isTargetNamespacePrefix = false;

-			try {

-				isTargetNamespacePrefix = xmlHelper.isTargetNamespace(prefix);

-			} catch (Exception e) {

-			}

-			if (!isTargetNamespacePrefix)

-				return xmlHelper.getPathForPrefix(prefix).appendFragment(fragment).toString();

-			else

-				return baseURI.appendFragment(fragment).toString();

-		}

-	}

-	

-	protected class Bpmn2ModelerXmlHelper extends BpmnXmlHelper {

-		

-		public Bpmn2ModelerXmlHelper(Bpmn2ResourceImpl resource) {

-			super(resource);

-		}

-		

-    	@Override

-		public EStructuralFeature getFeature(EClass eClass, String namespaceURI, String name, boolean isElement) {

-    		// This fixes https://bugs.eclipse.org/bugs/show_bug.cgi?id=378296

-    		// I'm still not convinced that getFeature() shouldn't simply return the feature

-    		// from the given EClass instead of searching the EPackage of the Resource being

-    		// loaded (if the EClass has a feature with that name of course).

-    		EPackage pkg = eClass.getEPackage(); 

-			if (pkg != Bpmn2Package.eINSTANCE &&

-					pkg != BpmnDiPackage.eINSTANCE &&

-					pkg != DcPackage.eINSTANCE &&

-					pkg != DiPackage.eINSTANCE &&

-					pkg != TargetRuntime.getCurrentRuntime().getModelDescriptor().getEPackage()) {

-				return eClass.getEStructuralFeature(name);

-			}

-			return super.getFeature(eClass, namespaceURI, name, isElement);

-		}

-	}

-}

+/*******************************************************************************
+ * Copyright (c) 2011 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 Bob Brodt
+ ******************************************************************************/
+/**
+ * <copyright>
+ * 
+ * Copyright (c) 2010 SAP AG.
+ * All rights reserved. This program and the accompanying materials
+ * are 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:
+ *    Reiner Hille-Doering (SAP AG) - initial API and implementation and/or initial documentation
+ * 
+ * </copyright>
+ */
+package org.eclipse.bpmn2.modeler.core.model;
+
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.bpmn2.Bpmn2Package;
+import org.eclipse.bpmn2.Definitions;
+import org.eclipse.bpmn2.Import;
+import org.eclipse.bpmn2.ItemDefinition;
+import org.eclipse.bpmn2.Lane;
+import org.eclipse.bpmn2.Participant;
+import org.eclipse.bpmn2.RootElement;
+import org.eclipse.bpmn2.di.BPMNDiagram;
+import org.eclipse.bpmn2.di.BPMNEdge;
+import org.eclipse.bpmn2.di.BPMNLabel;
+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.preferences.Bpmn2Preferences;
+import org.eclipse.bpmn2.modeler.core.runtime.TargetRuntime;
+import org.eclipse.bpmn2.modeler.core.utils.ModelUtil;
+import org.eclipse.bpmn2.util.Bpmn2ResourceImpl;
+import org.eclipse.bpmn2.util.ImportHelper;
+import org.eclipse.bpmn2.util.QNameURIHandler;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.dd.dc.Bounds;
+import org.eclipse.dd.dc.DcPackage;
+import org.eclipse.dd.dc.Point;
+import org.eclipse.dd.di.DiPackage;
+import org.eclipse.dd.di.DiagramElement;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.common.util.TreeIterator;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.util.ExtendedMetaData;
+import org.eclipse.emf.ecore.xmi.XMLHelper;
+import org.eclipse.emf.ecore.xmi.XMLLoad;
+import org.eclipse.emf.ecore.xmi.XMLResource;
+import org.eclipse.emf.ecore.xmi.XMLSave;
+import org.eclipse.emf.ecore.xmi.impl.XMLLoadImpl;
+import org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * <!-- begin-user-doc --> The <b>Resource </b> associated with the package.
+ * 
+ * @implements Bpmn2Resource <!-- end-user-doc -->
+ * @see org.eclipse.bpmn2.util.Bpmn2ResourceFactoryImpl
+ */
+public class Bpmn2ModelerResourceImpl extends Bpmn2ResourceImpl {
+
+	public static final String BPMN2_CONTENT_TYPE_ID = "org.eclipse.bpmn2.content-type.xml";
+	protected BpmnXmlHelper xmlHelper;
+	protected QNameURIHandler uriHandler;
+	public HashMap xmlNameToFeatureMap = new HashMap();
+
+	/**
+	 * Creates an instance of the resource.
+	 * 
+	 * @param uri
+	 *            the URI of the new resource.
+	 */
+	public Bpmn2ModelerResourceImpl(URI uri) {
+		super(uri);
+		
+		// overwrite helper and uri handler in options map
+		this.xmlHelper = new Bpmn2ModelerXmlHelper(this);
+        this.uriHandler = new FragmentQNameURIHandler(xmlHelper);
+        this.getDefaultLoadOptions().put(XMLResource.OPTION_URI_HANDLER, uriHandler);
+        this.getDefaultLoadOptions().put(XMLResource.OPTION_DEFER_IDREF_RESOLUTION, true);
+        this.getDefaultSaveOptions().put(XMLResource.OPTION_URI_HANDLER, uriHandler);
+
+        // some interesting things to play with:
+//        this.getDefaultLoadOptions().put(XMLResource.OPTION_LAX_FEATURE_PROCESSING, true);
+//        this.getDefaultLoadOptions().put(XMLResource.OPTION_LAX_WILDCARD_PROCESSING, true);
+//        this.getDefaultLoadOptions().put(XMLResource.OPTION_RECORD_UNKNOWN_FEATURE, true);
+//        this.getDefaultLoadOptions().put(XMLResource.OPTION_ANY_TYPE, BpmnDiPackage.eINSTANCE.getBPMNPlane());
+        this.getDefaultLoadOptions().put(XMLResource.OPTION_USE_XML_NAME_TO_FEATURE_MAP, xmlNameToFeatureMap);
+
+        // only necessary if this resource will not be added to a ResourceSet instantly
+        this.eAdapters().add(oppositeReferenceAdapter);
+	}
+
+    @Override
+    protected XMLHelper createXMLHelper() {
+        return this.xmlHelper;
+    }
+
+	/**
+	 * Override this method to hook in our own XmlHandler
+	 */
+	@Override
+	protected XMLLoad createXMLLoad() {
+		return new XMLLoadImpl(createXMLHelper()) {
+			@Override
+			protected DefaultHandler makeDefaultHandler() {
+				return new Bpmn2ModelerXmlHandler(resource, helper, options);
+			}
+		};
+	}
+
+	@Override
+	protected XMLSave createXMLSave() {
+		return new Bpmn2ModelerXMLSave(createXMLHelper()) {
+		};
+	}
+
+	@Override
+	protected void prepareSave() {
+		EObject cur;
+		Definitions thisDefinitions = ImportHelper.getDefinitions(this);
+		for (Iterator<EObject> iter = getAllContents(); iter.hasNext();) {
+			cur = iter.next();
+
+			setDefaultId(cur);
+
+			for (EObject referenced : cur.eCrossReferences()) {
+				setDefaultId(referenced);
+				if (thisDefinitions != null) {
+					Resource refResource = referenced.eResource();
+					if (refResource != null && refResource != this) {
+						createImportIfNecessary(thisDefinitions, refResource);
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * Set the ID attribute of cur to a generated ID, if it is not already set.
+	 * 
+	 * @param obj
+	 *            The object whose ID should be set.
+	 */
+	private void setDefaultId(EObject obj) {
+		if (obj.eClass() != null) {
+			EStructuralFeature idAttr = obj.eClass().getEIDAttribute();
+			if (idAttr != null && !obj.eIsSet(idAttr)) {
+				ModelUtil.setID(obj);
+			}
+		}
+	}
+
+	/**
+	 * We need extend the standard SAXXMLHandler to hook into the handling of
+	 * attribute references which may be either simple ID Strings or QNames.
+	 * We'll search through all of the objects' IDs first to find the one we're
+	 * looking for. If not, we'll try a QName search.
+	 */
+	protected static class Bpmn2ModelerXmlHandler extends BpmnXmlHandler {
+
+		Bpmn2Preferences prefs = null;
+		
+		public Bpmn2ModelerXmlHandler(XMLResource xmiResource, XMLHelper helper, Map<?, ?> options) {
+			super(xmiResource, helper, options);
+		}
+
+		@Override
+		protected void handleObjectAttribs(EObject obj) {
+			super.handleObjectAttribs(obj);
+			if (obj instanceof BPMNShape) {
+				BPMNShape bpmnShape = (BPMNShape)obj;
+
+				Hashtable<String,String> map = new Hashtable<String,String>();
+				if (attribs != null) {
+					for (int i = 0, size = attribs.getLength(); i < size; ++i) {
+						String key = attribs.getQName(i);
+						String value = attribs.getValue(i);
+						map.put(key, value);
+					}
+					Bpmn2Preferences.getInstance(this.resourceURI).applyBPMNDIDefaults(bpmnShape, map);
+				}
+			}
+			else if (obj instanceof ItemDefinition) {
+				ItemDefinition itemDef = (ItemDefinition)obj;
+
+				Definitions definitions = ImportHelper.getDefinitions(xmlResource);
+				URI referencingURI = ImportHelper.makeURICanonical(resourceURI);
+				String location = ModelUtil.getStringWrapperValue(itemDef.getStructureRef());
+				if (location!=null) {
+					int i = location.indexOf("$");
+					if (i>0)
+						location = location.substring(0,i);
+					URI uri = URI.createURI(location).resolve(referencingURI);
+					uri = uri.trimFragment();
+					Import imp = ImportHelper.findImportForLocation(definitions, uri);
+					itemDef.setImport(imp);
+				}
+			}
+		}
+
+		/**
+		 * Overridden to be able to convert ID references in attributes to URIs
+		 * during load. If the reference can't be found by its ID, we'll try a
+		 * QName search (done in the super class)
+		 * 
+		 * @param ids
+		 *            In our case the parameter will contain exactly one ID that
+		 *            we resolve to URI.
+		 */
+		@Override
+		protected void setValueFromId(EObject object, EReference eReference, String ids) {
+
+			for (EObject o : objects) {
+				TreeIterator<EObject> iter = o.eAllContents();
+				while (iter.hasNext()) {
+					EObject obj = iter.next();
+					EStructuralFeature feature = ((EObject) obj).eClass().getEIDAttribute();
+					if (feature != null && obj.eGet(feature) != null) {
+						Object id = obj.eGet(feature);
+						if (id != null && id.equals(ids)) {
+							try {
+								if (object.eGet(eReference) instanceof EList) {
+									((EList)object.eGet(eReference)).add(obj);
+								}
+								else {
+									object.eSet(eReference, obj);
+								}
+							} catch (Exception e) {
+								String msg = "Invalid or unknown reference from:\n  " +
+										object + "\nfeature:\n  " + eReference +
+										"\nto:\n  " + obj;
+								IStatus s = new Status(Status.ERROR, Activator.PLUGIN_ID,
+										msg, e);
+								Activator.getDefault().logStatus(s);
+							}
+							return;
+						}
+					}
+				}
+			}
+
+			// hack to handle QNames and arbitrary strings in structureRefs
+			if (eReference.getName().equals("structureRef") && object instanceof ItemDefinition) {
+				object.eSet(eReference, ModelUtil.createStringWrapper(ids));
+				return;
+			}
+
+			super.setValueFromId(object, eReference, ids);
+		}
+	}
+	
+	public static class Bpmn2ModelerXMLSave extends XMLSaveImpl {
+		protected float minX = Float.MAX_VALUE;
+		protected float minY = Float.MAX_VALUE;
+
+		public Bpmn2ModelerXMLSave(XMLHelper helper) {
+			super(helper);
+			helper.getPrefixToNamespaceMap().clear();
+		}
+
+		@Override
+		protected void init(XMLResource resource, Map<?, ?> options) {
+			super.init(resource, options);
+			featureTable = new Bpmn2ModelerXMLSave.Bpmn2Lookup(map, extendedMetaData, elementHandler);
+			
+			final List<BPMNDiagram> diagrams = getAll(BPMNDiagram.class, resource);
+			for (BPMNDiagram bpmnDiagram : diagrams) {
+				findMinXY(bpmnDiagram);
+			}
+			
+		}
+		
+        @Override
+        protected boolean shouldSaveFeature(EObject o, EStructuralFeature f) {
+            if (o instanceof BPMNShape && f==BpmnDiPackage.eINSTANCE.getBPMNShape_IsHorizontal()) {
+            	BPMNShape s = (BPMNShape)o;
+            	if (s.getBpmnElement() instanceof Lane || s.getBpmnElement() instanceof Participant)
+            		return true;
+            }
+            
+            // we also want to store x and y with value zero, would be skipped because of default value otherwise
+            if (o instanceof Bounds) {
+            	return true;
+            }
+            
+            return super.shouldSaveFeature(o, f);
+        }
+		
+		protected <T> List<T> getAll(Class<T> class1, Resource resource) {
+			ArrayList<T> l = new ArrayList<T>();
+			TreeIterator<EObject> contents = resource.getAllContents();
+			for (; contents.hasNext();) {
+				Object t = contents.next();
+				if (class1.isInstance(t)) {
+					l.add((T) t);
+				}
+			}
+			return l;
+		}
+		
+		protected void findMinXY(BPMNDiagram bpmnDiagram) {
+			EList<DiagramElement> elements = (EList<DiagramElement>) bpmnDiagram.getPlane().getPlaneElement();
+			for (DiagramElement e : elements) {
+				if (e instanceof BPMNShape) {
+					Bounds b = ((BPMNShape)e).getBounds();
+					minX = Math.min(minX, b.getX());
+					minY = Math.min(minY, b.getY());
+				}
+				else if (e instanceof BPMNEdge) {
+					List<Point> points = ((BPMNEdge)e).getWaypoint();
+					for (Point p : points) {
+						minX = Math.min(minX, p.getX());
+						minY = Math.min(minY, p.getY());
+					}
+
+				}
+				else if (e instanceof BPMNLabel) {
+					Bounds b = ((BPMNLabel)e).getBounds();
+					minX = Math.min(minX, b.getX());
+					minY = Math.min(minY, b.getY());
+				}
+			}
+		}
+
+		@Override
+		protected void saveElement(EObject o, EStructuralFeature f) {
+			float oldX = 0, oldY = 0;
+			List<Point> oldPoints = null;
+			
+			if (o instanceof BPMNShape) {
+				Bounds b = ((BPMNShape)o).getBounds();
+				if (minX<0) {
+					oldX = b.getX();
+					b.setX(oldX - minX);
+				}
+				if (minY<0) {
+					oldY = b.getY();
+					b.setY(oldY - minY);
+				}
+			}
+			else if (o instanceof BPMNEdge) {
+				List<Point> points = ((BPMNEdge)o).getWaypoint();
+				oldPoints = new ArrayList<Point>();
+				oldPoints.addAll(points);
+				for (Point p : points) {
+					if (minX<0)
+						p.setX( p.getX() - minX);
+					if (minY<0)
+						p.setY( p.getY() - minY);
+				}
+			}
+			else if (o instanceof BPMNLabel) {
+				Bounds b = ((BPMNLabel)o).getBounds();
+				if (b!=null) {
+					if (minX<0) {
+						oldX = b.getX();
+						b.setX(oldX - minX);
+					}
+					if (minY<0) {
+						oldY = b.getY();
+						b.setY(oldY - minY);
+					}
+				}
+			}
+
+			super.saveElement(o, f);
+			
+			if (o instanceof BPMNShape) {
+				Bounds b = ((BPMNShape)o).getBounds();
+				if (minX<0) {
+					b.setX(oldX);
+				}
+				if (minY<0) {
+					b.setY(oldY);
+				}
+			}
+			else if (o instanceof BPMNEdge) {
+				List<Point> points = ((BPMNEdge)o).getWaypoint();
+				int index = 0;
+				for (Point p : points) {
+					if (minX<0)
+						p.setX(oldPoints.get(index).getX());
+					if (minY<0)
+						p.setY(oldPoints.get(index).getY());
+					++index;
+				}
+			}
+			else if (o instanceof BPMNLabel) {
+				Bounds b = ((BPMNLabel)o).getBounds();
+				if (b!=null) {
+					if (minX<0) {
+						b.setX(oldX);
+					}
+					if (minY<0) {
+						b.setY(oldY);
+					}
+				}
+			}
+			
+		}
+
+		@Override
+		public void traverse(List<? extends EObject> contents) {
+			for (EObject e : contents) {
+				if (e instanceof Definitions) {
+					List<RootElement> roots = ((Definitions) e).getRootElements();
+					Process p = null;
+					for (RootElement root : roots) {
+						if (root instanceof Process) {
+							p = (Process) root;
+						}
+					}
+					if (p != null) {
+						((Definitions) e).getRootElements().remove(p);
+						((Definitions) e).getRootElements().add((RootElement) p);
+					}
+				}
+			}
+			super.traverse(contents);
+		}
+
+		public static class Bpmn2Lookup extends XMLSaveImpl.Lookup {
+			public Bpmn2Lookup(XMLMap map, ExtendedMetaData extendedMetaData, ElementHandler elementHandler) {
+				super(map, extendedMetaData, elementHandler);
+			}
+
+			@Override
+			public EStructuralFeature[] getFeatures(EClass cls) {
+				int index = getIndex(cls);
+				EClass c = classes[index];
+
+				if (c == cls) {
+					return features[index];
+				}
+
+				EStructuralFeature[] featureList = listFeatures(cls);
+				if (c == null) {
+					classes[index] = cls;
+					features[index] = featureList;
+					featureKinds[index] = listKinds(featureList);
+				}
+
+				if (cls.getName().equalsIgnoreCase("Process")) {
+					EStructuralFeature[] modifiedFeatureList = getModifiedProcessFeatureSet(featureList);
+					if (c == null) {
+						classes[index] = cls;
+						features[index] = modifiedFeatureList;
+						featureKinds[index] = listKinds(modifiedFeatureList);
+					}
+					return modifiedFeatureList;
+				}
+				return featureList;
+			}
+		}
+
+		private static EStructuralFeature[] getModifiedProcessFeatureSet(EStructuralFeature[] processFeatureList) {
+			/**
+			 * Feature list for Process provided by eclipse.bpmn2: -
+			 * extensionDefinitions (0) - id (1) - anyAttribute (2) - name (3) -
+			 * definitionalCollaborationRef (4) - isClosed (5) - isExecutable
+			 * (6) - processType (7) - extensionValues (8) - documentation (9) -
+			 * supportedInterfaceRefs (10) - ioSpecification (11) - ioBinding
+			 * (12) - laneSets (13) - flowElements (14) - auditing (15) -
+			 * monitoring (16) - properties (17) - artifacts (18) - resources
+			 * (19) - correlationSubscriptions (20) - supports (21) Semantic.xsd
+			 * sequence definition for Process: <xsd:sequence> <xsd:element
+			 * ref="auditing" minOccurs="0" maxOccurs="1"/> <xsd:element
+			 * ref="monitoring" minOccurs="0" maxOccurs="1"/> <xsd:element
+			 * ref="property" minOccurs="0" maxOccurs="unbounded"/> <xsd:element
+			 * ref="laneSet" minOccurs="0" maxOccurs="unbounded"/> <xsd:element
+			 * ref="flowElement" minOccurs="0" maxOccurs="unbounded"/>
+			 * <xsd:element ref="artifact" minOccurs="0" maxOccurs="unbounded"/>
+			 * <xsd:element ref="resourceRole" minOccurs="0"
+			 * maxOccurs="unbounded"/> <xsd:element
+			 * ref="correlationSubscription" minOccurs="0"
+			 * maxOccurs="unbounded"/> <xsd:element name="supports"
+			 * type="xsd:QName" minOccurs="0" maxOccurs="unbounded"/>
+			 * </xsd:sequence>
+			 * 
+			 * Moving auditing, monitoring, property above flowElements...
+			 */
+
+			EStructuralFeature[] retArray = new EStructuralFeature[processFeatureList.length];
+			for (int i = 0; i < 13; i++) {
+				retArray[i] = processFeatureList[i];
+			}
+			retArray[13] = processFeatureList[15]; // auditing
+			retArray[14] = processFeatureList[16]; // monitoring
+			retArray[15] = processFeatureList[17]; // properties
+			retArray[16] = processFeatureList[13]; // lanesets
+			retArray[17] = processFeatureList[14]; // flow elements
+			retArray[18] = processFeatureList[18]; // artifacts
+			retArray[19] = processFeatureList[19]; // resources
+			retArray[20] = processFeatureList[20]; // correlationSubscriptions
+			retArray[21] = processFeatureList[21]; // supports
+
+			return retArray;
+		}
+	}
+	
+	// TODO check this, is this the correct way to deal with this ID prefixes
+	/**
+	 * QName handler to make create URIs out of the fragment, which is the local part of the QName
+	 * 
+	 * Most other tools dont understand QNames in referencing attributes
+	 * 
+	 * @author drobisch
+	 *
+	 */
+	public static class FragmentQNameURIHandler extends QNameURIHandler {
+
+		protected BpmnXmlHelper xmlHelper;
+
+		public FragmentQNameURIHandler(BpmnXmlHelper xmlHelper) {
+			super(xmlHelper);
+			this.xmlHelper = xmlHelper;
+		}
+
+		@Override
+		public URI deresolve(URI uri) {
+			String fragment = uri.fragment();
+			if (fragment != null && !fragment.startsWith("/")) {
+				// return just fragment (i.e. without the '#'), always assume
+				// local reference
+				return URI.createURI(fragment);
+			}
+			return super.deresolve(uri);
+		}
+
+		@Override
+		public String convertQNameToUri(String qName) {
+			if (qName.contains("#") || qName.contains("/")) {
+				// We already have an URI and not QName, e.g. URL
+				return qName;
+			}
+
+			// Split into prefix and local part (fragment)
+			String[] parts = qName.split(":");
+			String prefix, fragment;
+			if (parts.length == 1) {
+				prefix = null;
+				fragment = qName;
+			} else if (parts.length == 2) {
+				prefix = parts[0];
+				fragment = parts[1];
+			} else
+				throw new IllegalArgumentException("Illegal QName: " + qName);
+
+			if (fragment.contains(".")) {
+				// HACK: officially IDs can contain ".", but unfortunately
+				// XmlHandler calls resolve also for xsi:schemaLocation stuff
+				// and similar, that are
+				// NO URIs. We must not process them.
+				return qName;
+			}
+
+			boolean isTargetNamespacePrefix = false;
+			try {
+				isTargetNamespacePrefix = xmlHelper.isTargetNamespace(prefix);
+			} catch (Exception e) {
+			}
+			if (!isTargetNamespacePrefix)
+				return xmlHelper.getPathForPrefix(prefix).appendFragment(fragment).toString();
+			else
+				return baseURI.appendFragment(fragment).toString();
+		}
+	}
+	
+	protected class Bpmn2ModelerXmlHelper extends BpmnXmlHelper {
+		
+		public Bpmn2ModelerXmlHelper(Bpmn2ResourceImpl resource) {
+			super(resource);
+		}
+		
+    	@Override
+		public EStructuralFeature getFeature(EClass eClass, String namespaceURI, String name, boolean isElement) {
+    		// This fixes https://bugs.eclipse.org/bugs/show_bug.cgi?id=378296
+    		// I'm still not convinced that getFeature() shouldn't simply return the feature
+    		// from the given EClass instead of searching the EPackage of the Resource being
+    		// loaded (if the EClass has a feature with that name of course).
+    		EPackage pkg = eClass.getEPackage(); 
+			if (pkg != Bpmn2Package.eINSTANCE &&
+					pkg != BpmnDiPackage.eINSTANCE &&
+					pkg != DcPackage.eINSTANCE &&
+					pkg != DiPackage.eINSTANCE &&
+					pkg != TargetRuntime.getCurrentRuntime().getModelDescriptor().getEPackage()) {
+				return eClass.getEStructuralFeature(name);
+			}
+			return super.getFeature(eClass, namespaceURI, name, isElement);
+		}
+	}
+}
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/utils/ErrorUtils.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/utils/ErrorUtils.java
index fbd1982..4c1a6fb 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/utils/ErrorUtils.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/utils/ErrorUtils.java
@@ -1,81 +1,81 @@
-/******************************************************************************* 

- * Copyright (c) 2011 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 Innar Made

- ******************************************************************************/

-package org.eclipse.bpmn2.modeler.core.utils;

-

-import org.eclipse.bpmn2.modeler.core.Activator;

-import org.eclipse.core.runtime.CoreException;

-import org.eclipse.core.runtime.IStatus;

-import org.eclipse.core.runtime.Platform;

-import org.eclipse.core.runtime.Status;

-import org.eclipse.jface.action.IStatusLineManager;

-import org.eclipse.jface.dialogs.ErrorDialog;

-import org.eclipse.swt.widgets.Display;

-import org.eclipse.ui.IActionBars;

-import org.eclipse.ui.IEditorSite;

-import org.eclipse.ui.IViewSite;

-import org.eclipse.ui.IWorkbench;

-import org.eclipse.ui.IWorkbenchPage;

-import org.eclipse.ui.IWorkbenchPart;

-import org.eclipse.ui.IWorkbenchPartSite;

-import org.eclipse.ui.IWorkbenchWindow;

-import org.eclipse.ui.PlatformUI;

-

-public class ErrorUtils {

-	public static void throwCoreException(String message) throws CoreException {

-		IStatus status = new Status(IStatus.ERROR,

-				Activator.PLUGIN_ID, IStatus.OK, message, null);

-		Platform.getLog(Activator.getDefault().getBundle()).log(status);

-		throw new CoreException(status);

-	}

-	

-

-	public static void showErrorWithLogging(IStatus status){

-		Platform.getLog(Activator.getDefault().getBundle()).log(status);

-		ErrorDialog.openError(PlatformUI.getWorkbench().getDisplay().getActiveShell(), "An error occured", null, status);

-	}

-

-

-	public static void showErrorMessage(final String msg) {

-		Display.getDefault().asyncExec( new Runnable() {

-	

-			@Override

-			public void run() {

-				IWorkbench wb = PlatformUI.getWorkbench();

-				IWorkbenchWindow win = wb.getActiveWorkbenchWindow();

-				IWorkbenchPage page = win.getActivePage();

-				IWorkbenchPart part = page.getActivePart();

-				if (part==null)

-					return;

-				

-				IActionBars actionBars = null;

-				IWorkbenchPartSite site = part.getSite();

-				if (site instanceof IViewSite)

-					actionBars = ((IViewSite) site).getActionBars();

-				else if (site instanceof IEditorSite)

-					actionBars = ((IEditorSite) site).getActionBars();

-	

-				if( actionBars == null )

-					return;

-	

-				IStatusLineManager statusLineManager = actionBars.getStatusLineManager();

-				if( statusLineManager == null )

-					return;

-				

-				statusLineManager.setErrorMessage(msg);

-				statusLineManager.markDirty();

-				statusLineManager.update(true);

-			}

-		});

-	}

-	

-}

+/******************************************************************************* 
+ * Copyright (c) 2011 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 Innar Made
+ ******************************************************************************/
+package org.eclipse.bpmn2.modeler.core.utils;
+
+import org.eclipse.bpmn2.modeler.core.Activator;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.action.IStatusLineManager;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IViewSite;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartSite;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+
+public class ErrorUtils {
+	public static void throwCoreException(String message) throws CoreException {
+		IStatus status = new Status(IStatus.ERROR,
+				Activator.PLUGIN_ID, IStatus.OK, message, null);
+		Platform.getLog(Activator.getDefault().getBundle()).log(status);
+		throw new CoreException(status);
+	}
+	
+
+	public static void showErrorWithLogging(IStatus status){
+		Platform.getLog(Activator.getDefault().getBundle()).log(status);
+		ErrorDialog.openError(PlatformUI.getWorkbench().getDisplay().getActiveShell(), "An error occured", null, status);
+	}
+
+
+	public static void showErrorMessage(final String msg) {
+		Display.getDefault().asyncExec( new Runnable() {
+	
+			@Override
+			public void run() {
+				IWorkbench wb = PlatformUI.getWorkbench();
+				IWorkbenchWindow win = wb.getActiveWorkbenchWindow();
+				IWorkbenchPage page = win.getActivePage();
+				IWorkbenchPart part = page.getActivePart();
+				if (part==null)
+					return;
+				
+				IActionBars actionBars = null;
+				IWorkbenchPartSite site = part.getSite();
+				if (site instanceof IViewSite)
+					actionBars = ((IViewSite) site).getActionBars();
+				else if (site instanceof IEditorSite)
+					actionBars = ((IEditorSite) site).getActionBars();
+	
+				if( actionBars == null )
+					return;
+	
+				IStatusLineManager statusLineManager = actionBars.getStatusLineManager();
+				if( statusLineManager == null )
+					return;
+				
+				statusLineManager.setErrorMessage(msg);
+				statusLineManager.markDirty();
+				statusLineManager.update(true);
+			}
+		});
+	}
+	
+}
diff --git a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/Activator.java b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/Activator.java
index dc0e7ea..1f30a53 100644
--- a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/Activator.java
+++ b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/Activator.java
@@ -1,283 +1,283 @@
-/******************************************************************************* 

- * Copyright (c) 2011 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 Innar Made

- ******************************************************************************/

-package org.eclipse.bpmn2.modeler.ui;

-

-import java.lang.reflect.Field;

-import java.net.MalformedURLException;

-import java.net.URL;

-

-import org.eclipse.bpel.wsil.model.inspection.InspectionPackage;

-import org.eclipse.bpmn2.di.impl.BpmnDiPackageImpl;

-import org.eclipse.bpmn2.impl.Bpmn2PackageImpl;

-import org.eclipse.bpmn2.modeler.core.adapters.AdapterRegistry;

-import org.eclipse.bpmn2.modeler.ui.adapters.Bpmn2EditorDiItemProviderAdapterFactory;

-import org.eclipse.bpmn2.modeler.ui.adapters.Bpmn2EditorItemProviderAdapterFactory;

-import org.eclipse.bpmn2.modeler.ui.adapters.Bpmn2WSDLAdapterFactory;

-import org.eclipse.bpmn2.modeler.ui.adapters.Bpmn2WSILAdapterFactory;

-import org.eclipse.bpmn2.modeler.ui.adapters.Bpmn2XSDAdapterFactory;

-import org.eclipse.core.resources.IResourceChangeEvent;

-import org.eclipse.core.resources.ISaveContext;

-import org.eclipse.core.resources.ISaveParticipant;

-import org.eclipse.core.resources.ISavedState;

-import org.eclipse.core.resources.IWorkspace;

-import org.eclipse.core.resources.ResourcesPlugin;

-import org.eclipse.core.runtime.CoreException;

-import org.eclipse.core.runtime.IStatus;

-import org.eclipse.core.runtime.Platform;

-import org.eclipse.core.runtime.Status;

-import org.eclipse.jface.dialogs.ErrorDialog;

-import org.eclipse.jface.dialogs.IDialogSettings;

-import org.eclipse.jface.resource.ImageDescriptor;

-import org.eclipse.jface.resource.ImageRegistry;

-import org.eclipse.swt.graphics.Image;

-import org.eclipse.ui.PlatformUI;

-import org.eclipse.ui.plugin.AbstractUIPlugin;

-import org.eclipse.wst.wsdl.WSDLPackage;

-import org.eclipse.xsd.XSDPackage;

-import org.osgi.framework.BundleContext;

-

-/**

- * The activator class controls the plug-in life cycle

- */

-public class Activator extends AbstractUIPlugin {

-

-	// The plug-in ID

-	public static final String PLUGIN_ID = "org.eclipse.bpmn2.modeler.ui"; //$NON-NLS-1$

-

-	// The shared instance

-	private static Activator plugin;

-	

-	// handles changes to the bpmn file

-	private BPMN2ResourceChangeListener resourceChangeListener;

-	private ISaveParticipant saveParticipant;

-	

-	// Adapter Factory registration

-	static {

-		AdapterRegistry.INSTANCE.registerAdapterFactory(

-			    WSDLPackage.eINSTANCE, Bpmn2WSDLAdapterFactory.getInstance());

-		

-		AdapterRegistry.INSTANCE.registerAdapterFactory(

-			    XSDPackage.eINSTANCE, Bpmn2XSDAdapterFactory.getInstance());

-		

-		AdapterRegistry.INSTANCE.registerAdapterFactory(

-			    InspectionPackage.eINSTANCE, Bpmn2WSILAdapterFactory.getInstance() );

-		

-		// BPMN2 metamodel adapter factories

-		AdapterRegistry.BPMN2_ADAPTER_FACTORIES.addAdapterFactory(

-				AdapterRegistry.INSTANCE.registerFactory(Bpmn2PackageImpl.eINSTANCE, new Bpmn2EditorItemProviderAdapterFactory()));

-		AdapterRegistry.BPMN2_ADAPTER_FACTORIES.addAdapterFactory(

-				AdapterRegistry.INSTANCE.registerFactory(BpmnDiPackageImpl.eINSTANCE, new Bpmn2EditorDiItemProviderAdapterFactory()));

-	}

-

-	/**

-	 * The constructor

-	 */

-	public Activator() {

-	}

-

-	/*

-	 * (non-Javadoc)

-	 * 

-	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)

-	 */

-	public void start(BundleContext context) throws Exception {

-		super.start(context);

-		plugin = this;

-

-		initializeResourceChangeListener();

-	}

-

-	/*

-	 * (non-Javadoc)

-	 * 

-	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)

-	 */

-	public void stop(BundleContext context) throws Exception {

-		plugin = null;

-		super.stop(context);

-		

-		IWorkspace workspace = ResourcesPlugin.getWorkspace();

-		if (workspace != null) {

-			workspace.removeResourceChangeListener(this.resourceChangeListener);

-		}

-	}

-

-	/**

-	 * Returns the shared instance

-	 * 

-	 * @return the shared instance

-	 */

-	public static Activator getDefault() {

-		return plugin;

-	}

-

-	public static void logStatus(IStatus status) {

-		Platform.getLog(plugin.getBundle()).log(status);

-	}

-

-	public static void logError(Exception e) {

-		logStatus(createStatus(e));

-	}

-

-	private static Status createStatus(Exception e) {

-		return new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(), e);

-	}

-

-	public static void showErrorWithLogging(Exception e){

-		Status s = createStatus(e);

-		logStatus(s);

-		ErrorDialog.openError(PlatformUI.getWorkbench().getDisplay().getActiveShell(), "An error occured", null, s);

-	}

-

-	/**

-	 * Return the dialog settings for a given object. The object may be a string

-	 * or any other java object. In that case, the object's class name will be used

-	 * to retrieve that section name.

-	 * 

-	 * @param object 

-	 * @return the dialog settings for that object

-	 * 

-	 */

-	public IDialogSettings getDialogSettingsFor ( Object object ) 

-	{

-	    String name = object.getClass().getName();

-	    if (object instanceof String) {

-	        name = (String) object;

-	    }

-	    

-	    IDialogSettings main = getDialogSettings();	    

-	    IDialogSettings settings = main.getSection( name );

-	    if (settings == null) {

-	        settings = main.addNewSection(name);

-	    }

-	    return settings;

-	}

-

-	/**

-	 * @return

-	 */

-	public String getID() {

-		return getBundle().getSymbolicName();

-	}

-	

-	/**

-	 * Initializes the table of images used in this plugin.

-	 */

-	@Override

-	protected ImageRegistry createImageRegistry() {

-		ImageRegistry registry = super.createImageRegistry();

-		URL baseURL = getBundle().getEntry("/"); //$NON-NLS-1$

-

-		// A little reflection magic ... so that we don't

-		// have to add the createImageDescriptor every time

-		// we add it to the IConstants ..

-		Field fields[] = IConstants.class.getFields();	

-		for(int i=0; i < fields.length; i++) {

-			Field f = fields[i];

-			if (f.getType() != String.class) { 

-				continue;

-			}

-			String name = f.getName();

-			if (name.startsWith("ICON_") || name.startsWith("CURSOR_") || name.startsWith("IMAGE_")) {   //$NON-NLS-1$ //$NON-NLS-2$

-				try {

-					String value = (String) f.get(null);

-					createImageDescriptor(registry, value, baseURL);

-				} catch (Exception e) {

-					logError(e);

-				}

-			}			

-		}

-		return registry;

-	}

-

-	/**

-	 * Creates an image descriptor and places it in the image registry.

-	 */

-	private void createImageDescriptor(ImageRegistry registry, String id, URL baseURL) {

-		URL url = null;

-		try {

-			url = new URL(baseURL, IConstants.ICON_PATH + id);

-		} catch (MalformedURLException e) {

-			logError(e);

-		}

-		ImageDescriptor desc = ImageDescriptor.createFromURL(url);

-		registry.put(id, desc);

-	}

-

-	public Image getImage(String id) {

-		return getImageRegistry().get(id);

-	}

-

-

-	/**

-	 * Installs the IResourceChangeListener for this Plugin. Also

-	 * checks if there were any changes to bpmn files while the plug-in

-	 * was not active.

-	 */

-	private void initializeResourceChangeListener() throws CoreException {

-		this.resourceChangeListener = new BPMN2ResourceChangeListener();

-		// Add the save participant in a separate thread

-		// to make sure that it doesn't block the UI thread and potentially cause

-		// deadlocks with the code that caused our plugin to be started.

-		Thread initSaveParticipantThread = new Thread(new Runnable() {

-			@Override

-			public void run() {

-				try {

-					IWorkspace workspace = ResourcesPlugin.getWorkspace();

-					workspace.addResourceChangeListener(Activator.this.resourceChangeListener, IResourceChangeEvent.POST_BUILD);

-					ISavedState savedState = workspace.addSaveParticipant("BPMN2 Modeler", getSaveParticipant());

-					if (savedState != null) {

-						savedState.processResourceChangeEvents(Activator.this.resourceChangeListener);

-					}

-				} catch (CoreException e) {

-					throw new RuntimeException(e);

-				}

-			}

-		});

-		initSaveParticipantThread.setName("BPMN2 Modeler plugin init"); //$NON-NLS-1$

-		initSaveParticipantThread.start();

-	}

-

-	/**

-	 * We are only interested in the resource delta while the plugin was

-	 * not active and don't really care about the plug-in save lifecycle.

-	 */

-	private ISaveParticipant getSaveParticipant() {

-		if (this.saveParticipant == null) {

-			this.saveParticipant = new ISaveParticipant() {

-				@Override

-				public void doneSaving(ISaveContext context) {

-				}

-				@Override

-				public void prepareToSave(ISaveContext context) throws CoreException {

-				}

-				@Override

-				public void rollback(ISaveContext context) {

-				}

-				@Override

-				public void saving(ISaveContext context) throws CoreException {

-					context.needDelta();

-				}

-			};

-		}

-		return this.saveParticipant;

-	}

-

-	/**

-	 * Returns the resource change listener.

-	 */

-	public BPMN2ResourceChangeListener getResourceChangeListener() {

-		return this.resourceChangeListener;

-	}

-

-}

+/******************************************************************************* 
+ * Copyright (c) 2011 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 Innar Made
+ ******************************************************************************/
+package org.eclipse.bpmn2.modeler.ui;
+
+import java.lang.reflect.Field;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.eclipse.bpel.wsil.model.inspection.InspectionPackage;
+import org.eclipse.bpmn2.di.impl.BpmnDiPackageImpl;
+import org.eclipse.bpmn2.impl.Bpmn2PackageImpl;
+import org.eclipse.bpmn2.modeler.core.adapters.AdapterRegistry;
+import org.eclipse.bpmn2.modeler.ui.adapters.Bpmn2EditorDiItemProviderAdapterFactory;
+import org.eclipse.bpmn2.modeler.ui.adapters.Bpmn2EditorItemProviderAdapterFactory;
+import org.eclipse.bpmn2.modeler.ui.adapters.Bpmn2WSDLAdapterFactory;
+import org.eclipse.bpmn2.modeler.ui.adapters.Bpmn2WSILAdapterFactory;
+import org.eclipse.bpmn2.modeler.ui.adapters.Bpmn2XSDAdapterFactory;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.ISaveContext;
+import org.eclipse.core.resources.ISaveParticipant;
+import org.eclipse.core.resources.ISavedState;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.eclipse.wst.wsdl.WSDLPackage;
+import org.eclipse.xsd.XSDPackage;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends AbstractUIPlugin {
+
+	// The plug-in ID
+	public static final String PLUGIN_ID = "org.eclipse.bpmn2.modeler.ui"; //$NON-NLS-1$
+
+	// The shared instance
+	private static Activator plugin;
+	
+	// handles changes to the bpmn file
+	private BPMN2ResourceChangeListener resourceChangeListener;
+	private ISaveParticipant saveParticipant;
+	
+	// Adapter Factory registration
+	static {
+		AdapterRegistry.INSTANCE.registerAdapterFactory(
+			    WSDLPackage.eINSTANCE, Bpmn2WSDLAdapterFactory.getInstance());
+		
+		AdapterRegistry.INSTANCE.registerAdapterFactory(
+			    XSDPackage.eINSTANCE, Bpmn2XSDAdapterFactory.getInstance());
+		
+		AdapterRegistry.INSTANCE.registerAdapterFactory(
+			    InspectionPackage.eINSTANCE, Bpmn2WSILAdapterFactory.getInstance() );
+		
+		// BPMN2 metamodel adapter factories
+		AdapterRegistry.BPMN2_ADAPTER_FACTORIES.addAdapterFactory(
+				AdapterRegistry.INSTANCE.registerFactory(Bpmn2PackageImpl.eINSTANCE, new Bpmn2EditorItemProviderAdapterFactory()));
+		AdapterRegistry.BPMN2_ADAPTER_FACTORIES.addAdapterFactory(
+				AdapterRegistry.INSTANCE.registerFactory(BpmnDiPackageImpl.eINSTANCE, new Bpmn2EditorDiItemProviderAdapterFactory()));
+	}
+
+	/**
+	 * The constructor
+	 */
+	public Activator() {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+	 */
+	public void start(BundleContext context) throws Exception {
+		super.start(context);
+		plugin = this;
+
+		initializeResourceChangeListener();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+	 */
+	public void stop(BundleContext context) throws Exception {
+		plugin = null;
+		super.stop(context);
+		
+		IWorkspace workspace = ResourcesPlugin.getWorkspace();
+		if (workspace != null) {
+			workspace.removeResourceChangeListener(this.resourceChangeListener);
+		}
+	}
+
+	/**
+	 * Returns the shared instance
+	 * 
+	 * @return the shared instance
+	 */
+	public static Activator getDefault() {
+		return plugin;
+	}
+
+	public static void logStatus(IStatus status) {
+		Platform.getLog(plugin.getBundle()).log(status);
+	}
+
+	public static void logError(Exception e) {
+		logStatus(createStatus(e));
+	}
+
+	private static Status createStatus(Exception e) {
+		return new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(), e);
+	}
+
+	public static void showErrorWithLogging(Exception e){
+		Status s = createStatus(e);
+		logStatus(s);
+		ErrorDialog.openError(PlatformUI.getWorkbench().getDisplay().getActiveShell(), "An error occured", null, s);
+	}
+
+	/**
+	 * Return the dialog settings for a given object. The object may be a string
+	 * or any other java object. In that case, the object's class name will be used
+	 * to retrieve that section name.
+	 * 
+	 * @param object 
+	 * @return the dialog settings for that object
+	 * 
+	 */
+	public IDialogSettings getDialogSettingsFor ( Object object ) 
+	{
+	    String name = object.getClass().getName();
+	    if (object instanceof String) {
+	        name = (String) object;
+	    }
+	    
+	    IDialogSettings main = getDialogSettings();	    
+	    IDialogSettings settings = main.getSection( name );
+	    if (settings == null) {
+	        settings = main.addNewSection(name);
+	    }
+	    return settings;
+	}
+
+	/**
+	 * @return
+	 */
+	public String getID() {
+		return getBundle().getSymbolicName();
+	}
+	
+	/**
+	 * Initializes the table of images used in this plugin.
+	 */
+	@Override
+	protected ImageRegistry createImageRegistry() {
+		ImageRegistry registry = super.createImageRegistry();
+		URL baseURL = getBundle().getEntry("/"); //$NON-NLS-1$
+
+		// A little reflection magic ... so that we don't
+		// have to add the createImageDescriptor every time
+		// we add it to the IConstants ..
+		Field fields[] = IConstants.class.getFields();	
+		for(int i=0; i < fields.length; i++) {
+			Field f = fields[i];
+			if (f.getType() != String.class) { 
+				continue;
+			}
+			String name = f.getName();
+			if (name.startsWith("ICON_") || name.startsWith("CURSOR_") || name.startsWith("IMAGE_")) {   //$NON-NLS-1$ //$NON-NLS-2$
+				try {
+					String value = (String) f.get(null);
+					createImageDescriptor(registry, value, baseURL);
+				} catch (Exception e) {
+					logError(e);
+				}
+			}			
+		}
+		return registry;
+	}
+
+	/**
+	 * Creates an image descriptor and places it in the image registry.
+	 */
+	private void createImageDescriptor(ImageRegistry registry, String id, URL baseURL) {
+		URL url = null;
+		try {
+			url = new URL(baseURL, IConstants.ICON_PATH + id);
+		} catch (MalformedURLException e) {
+			logError(e);
+		}
+		ImageDescriptor desc = ImageDescriptor.createFromURL(url);
+		registry.put(id, desc);
+	}
+
+	public Image getImage(String id) {
+		return getImageRegistry().get(id);
+	}
+
+
+	/**
+	 * Installs the IResourceChangeListener for this Plugin. Also
+	 * checks if there were any changes to bpmn files while the plug-in
+	 * was not active.
+	 */
+	private void initializeResourceChangeListener() throws CoreException {
+		this.resourceChangeListener = new BPMN2ResourceChangeListener();
+		// Add the save participant in a separate thread
+		// to make sure that it doesn't block the UI thread and potentially cause
+		// deadlocks with the code that caused our plugin to be started.
+		Thread initSaveParticipantThread = new Thread(new Runnable() {
+			@Override
+			public void run() {
+				try {
+					IWorkspace workspace = ResourcesPlugin.getWorkspace();
+					workspace.addResourceChangeListener(Activator.this.resourceChangeListener, IResourceChangeEvent.POST_BUILD);
+					ISavedState savedState = workspace.addSaveParticipant("BPMN2 Modeler", getSaveParticipant());
+					if (savedState != null) {
+						savedState.processResourceChangeEvents(Activator.this.resourceChangeListener);
+					}
+				} catch (CoreException e) {
+					throw new RuntimeException(e);
+				}
+			}
+		});
+		initSaveParticipantThread.setName("BPMN2 Modeler plugin init"); //$NON-NLS-1$
+		initSaveParticipantThread.start();
+	}
+
+	/**
+	 * We are only interested in the resource delta while the plugin was
+	 * not active and don't really care about the plug-in save lifecycle.
+	 */
+	private ISaveParticipant getSaveParticipant() {
+		if (this.saveParticipant == null) {
+			this.saveParticipant = new ISaveParticipant() {
+				@Override
+				public void doneSaving(ISaveContext context) {
+				}
+				@Override
+				public void prepareToSave(ISaveContext context) throws CoreException {
+				}
+				@Override
+				public void rollback(ISaveContext context) {
+				}
+				@Override
+				public void saving(ISaveContext context) throws CoreException {
+					context.needDelta();
+				}
+			};
+		}
+		return this.saveParticipant;
+	}
+
+	/**
+	 * Returns the resource change listener.
+	 */
+	public BPMN2ResourceChangeListener getResourceChangeListener() {
+		return this.resourceChangeListener;
+	}
+
+}
diff --git a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/BPMN2ResourceChangeListener.java b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/BPMN2ResourceChangeListener.java
index b205195..1cca90a 100644
--- a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/BPMN2ResourceChangeListener.java
+++ b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/BPMN2ResourceChangeListener.java
@@ -1,153 +1,153 @@
-/*******************************************************************************

- * Copyright (c) 2011 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 Bob Brodt

- ******************************************************************************/

-

-package org.eclipse.bpmn2.modeler.ui;

-

-import java.util.ArrayList;

-import java.util.Iterator;

-import java.util.List;

-

-import org.eclipse.core.resources.IFile;

-import org.eclipse.core.resources.IResource;

-import org.eclipse.core.resources.IResourceChangeEvent;

-import org.eclipse.core.resources.IResourceChangeListener;

-import org.eclipse.core.resources.IResourceDelta;

-import org.eclipse.core.resources.IResourceDeltaVisitor;

-import org.eclipse.core.resources.IWorkspaceRoot;

-import org.eclipse.core.resources.IWorkspaceRunnable;

-import org.eclipse.core.resources.ResourcesPlugin;

-import org.eclipse.core.runtime.CoreException;

-import org.eclipse.core.runtime.IPath;

-import org.eclipse.core.runtime.IProgressMonitor;

-

-/**

- * @author Bob Brodt

- *

- */

-public class BPMN2ResourceChangeListener implements IResourceChangeListener {

-

-	class ResourceDeltaVisitor implements IResourceDeltaVisitor {

-

-		public boolean visit(final IResourceDelta delta) throws CoreException {

-			IResource target = delta.getResource();

-//			switch (delta.getKind()) {

-//			case IResourceDelta.ADDED:

-//				System.out.println(target.getFullPath()+" ADDED");

-//				break;

-//			case IResourceDelta.CHANGED:

-//				System.out.println(target.getFullPath()+" CHANGED");

-//				break;

-//			case IResourceDelta.REMOVED:

-//				System.out.println(target.getFullPath()+" REMOVED");

-//				break;

-//			case IResourceDelta.ADDED_PHANTOM:

-//				System.out.println(target.getFullPath()+" ADDED_PHANTOM");

-//				break;

-//			}

-			if (target.getType() == IResource.FILE) {

-				handleFile(delta);

-			}

-			return true;

-		}

-

-		private void handleFile(final IResourceDelta delta)

-			throws CoreException {

-			IWorkspaceRunnable runnable = new IWorkspaceRunnable() {

-				public void run(IProgressMonitor monitor)

-					throws CoreException {

-					IFile target = (IFile) delta.getResource();

-					int flags = delta.getFlags();

-					

-					switch (delta.getKind()) {

-					case IResourceDelta.ADDED:

-						if ((flags & IResourceDelta.MOVED_FROM) != 0) {

-							if (target.exists())

-								fileMoved(delta.getMovedFromPath(), target.getFullPath());

-						}

-						break;

-					case IResourceDelta.REMOVED:

-						if ((flags & IResourceDelta.MOVED_TO) != 0) {

-							if (target.exists())

-								fileMoved(target.getFullPath(), delta.getMovedToPath());

-						} else {

-							fileDeleted(target.getFullPath(), monitor);

-						}

-						break;

-					}

-				}

-			};

-			ResourcesPlugin.getWorkspace().run(runnable, null);

-		}

-	}

-

-	protected IResourceDeltaVisitor visitor;

-	protected List<IFileChangeListener> listeners;

-

-	public BPMN2ResourceChangeListener() {

-		listeners = new ArrayList<IFileChangeListener>();

-	}

-

-	/**

-	 * Objects like the BPELEditor can add listeners so they can be

-	 * notified and react when BPEL files change.

-	 */

-	public void addListener(IFileChangeListener listener) {

-		listeners.add(listener);

-	}

-	

-	/**

-	 * Removed the listener.

-	 */

-	public void removeListener(IFileChangeListener listener) {

-		listeners.remove(listener);

-	}

-

-	/* (non-Javadoc)

-	 * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent)

-	 */

-	@Override

-	public void resourceChanged(IResourceChangeEvent event) {

-		try {

-			event.getDelta().accept(getResourceDeltaVisitor());

-		} catch (CoreException e) {

-			Activator.logError(e);

-		}

-	}

-

-	protected IResourceDeltaVisitor getResourceDeltaVisitor() {

-		if (visitor == null) {

-			visitor = new ResourceDeltaVisitor();

-		}

-		return visitor;

-	}

-

-	protected void fileMoved(IPath oldFilePath, IPath newFilePath) throws CoreException {

-		// notify listeners

-		// make a copy of listener list to avoid concurrent list modification

-		List<IFileChangeListener> l = new ArrayList<IFileChangeListener>();

-		l.addAll(listeners);

-		for (IFileChangeListener listener : l) {

-			listener.moved(oldFilePath, newFilePath);

-		}

-	}

-	

-	protected void fileDeleted(IPath filePath, IProgressMonitor monitor) throws CoreException {

-		// notify listeners

-		// make a copy of listener list to avoid concurrent list modification

-		List<IFileChangeListener> l = new ArrayList<IFileChangeListener>();

-		l.addAll(listeners);

-		for (IFileChangeListener listener : l) {

-			listener.deleted(filePath);

-		}

-	}

-}

+/*******************************************************************************
+ * Copyright (c) 2011 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 Bob Brodt
+ ******************************************************************************/
+
+package org.eclipse.bpmn2.modeler.ui;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IResourceDeltaVisitor;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+/**
+ * @author Bob Brodt
+ *
+ */
+public class BPMN2ResourceChangeListener implements IResourceChangeListener {
+
+	class ResourceDeltaVisitor implements IResourceDeltaVisitor {
+
+		public boolean visit(final IResourceDelta delta) throws CoreException {
+			IResource target = delta.getResource();
+//			switch (delta.getKind()) {
+//			case IResourceDelta.ADDED:
+//				System.out.println(target.getFullPath()+" ADDED");
+//				break;
+//			case IResourceDelta.CHANGED:
+//				System.out.println(target.getFullPath()+" CHANGED");
+//				break;
+//			case IResourceDelta.REMOVED:
+//				System.out.println(target.getFullPath()+" REMOVED");
+//				break;
+//			case IResourceDelta.ADDED_PHANTOM:
+//				System.out.println(target.getFullPath()+" ADDED_PHANTOM");
+//				break;
+//			}
+			if (target.getType() == IResource.FILE) {
+				handleFile(delta);
+			}
+			return true;
+		}
+
+		private void handleFile(final IResourceDelta delta)
+			throws CoreException {
+			IWorkspaceRunnable runnable = new IWorkspaceRunnable() {
+				public void run(IProgressMonitor monitor)
+					throws CoreException {
+					IFile target = (IFile) delta.getResource();
+					int flags = delta.getFlags();
+					
+					switch (delta.getKind()) {
+					case IResourceDelta.ADDED:
+						if ((flags & IResourceDelta.MOVED_FROM) != 0) {
+							if (target.exists())
+								fileMoved(delta.getMovedFromPath(), target.getFullPath());
+						}
+						break;
+					case IResourceDelta.REMOVED:
+						if ((flags & IResourceDelta.MOVED_TO) != 0) {
+							if (target.exists())
+								fileMoved(target.getFullPath(), delta.getMovedToPath());
+						} else {
+							fileDeleted(target.getFullPath(), monitor);
+						}
+						break;
+					}
+				}
+			};
+			ResourcesPlugin.getWorkspace().run(runnable, null);
+		}
+	}
+
+	protected IResourceDeltaVisitor visitor;
+	protected List<IFileChangeListener> listeners;
+
+	public BPMN2ResourceChangeListener() {
+		listeners = new ArrayList<IFileChangeListener>();
+	}
+
+	/**
+	 * Objects like the BPELEditor can add listeners so they can be
+	 * notified and react when BPEL files change.
+	 */
+	public void addListener(IFileChangeListener listener) {
+		listeners.add(listener);
+	}
+	
+	/**
+	 * Removed the listener.
+	 */
+	public void removeListener(IFileChangeListener listener) {
+		listeners.remove(listener);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent)
+	 */
+	@Override
+	public void resourceChanged(IResourceChangeEvent event) {
+		try {
+			event.getDelta().accept(getResourceDeltaVisitor());
+		} catch (CoreException e) {
+			Activator.logError(e);
+		}
+	}
+
+	protected IResourceDeltaVisitor getResourceDeltaVisitor() {
+		if (visitor == null) {
+			visitor = new ResourceDeltaVisitor();
+		}
+		return visitor;
+	}
+
+	protected void fileMoved(IPath oldFilePath, IPath newFilePath) throws CoreException {
+		// notify listeners
+		// make a copy of listener list to avoid concurrent list modification
+		List<IFileChangeListener> l = new ArrayList<IFileChangeListener>();
+		l.addAll(listeners);
+		for (IFileChangeListener listener : l) {
+			listener.moved(oldFilePath, newFilePath);
+		}
+	}
+	
+	protected void fileDeleted(IPath filePath, IProgressMonitor monitor) throws CoreException {
+		// notify listeners
+		// make a copy of listener list to avoid concurrent list modification
+		List<IFileChangeListener> l = new ArrayList<IFileChangeListener>();
+		l.addAll(listeners);
+		for (IFileChangeListener listener : l) {
+			listener.deleted(filePath);
+		}
+	}
+}
diff --git a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/diagram/BpmnToolBehaviourFeature.java b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/diagram/BpmnToolBehaviourFeature.java
index 9475bcc..b4fb2c6 100644
--- a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/diagram/BpmnToolBehaviourFeature.java
+++ b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/diagram/BpmnToolBehaviourFeature.java
@@ -1,424 +1,424 @@
-/******************************************************************************* 

- * Copyright (c) 2011 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 Innar Made

- ******************************************************************************/

-package org.eclipse.bpmn2.modeler.ui.diagram;

-

-import java.util.ArrayList;

-import java.util.List;

-

-import org.eclipse.bpmn2.modeler.core.Activator;

-import org.eclipse.bpmn2.modeler.core.features.IBpmn2AddFeature;

-import org.eclipse.bpmn2.modeler.core.features.IBpmn2CreateFeature;

-import org.eclipse.bpmn2.modeler.core.features.activity.ActivitySelectionBehavior;

-import org.eclipse.bpmn2.modeler.core.features.event.EventSelectionBehavior;

-import org.eclipse.bpmn2.modeler.core.runtime.CustomTaskDescriptor;

-import org.eclipse.bpmn2.modeler.core.runtime.ModelEnablementDescriptor;

-import org.eclipse.bpmn2.modeler.core.runtime.TargetRuntime;

-import org.eclipse.bpmn2.modeler.core.utils.GraphicsUtil;

-import org.eclipse.bpmn2.modeler.ui.FeatureMap;

-import org.eclipse.bpmn2.modeler.ui.ImageProvider;

-import org.eclipse.bpmn2.modeler.ui.editor.BPMN2Editor;

-import org.eclipse.bpmn2.modeler.ui.features.activity.task.CustomTaskFeatureContainer;

-import org.eclipse.bpmn2.modeler.ui.features.choreography.ChoreographySelectionBehavior;

-import org.eclipse.bpmn2.modeler.ui.features.choreography.ChoreographyUtil;

-import org.eclipse.core.resources.IProject;

-import org.eclipse.core.resources.ResourcesPlugin;

-import org.eclipse.emf.common.util.EList;

-import org.eclipse.emf.ecore.EObject;

-import org.eclipse.emf.ecore.resource.Resource;

-import org.eclipse.graphiti.IExecutionInfo;

-import org.eclipse.graphiti.datatypes.ILocation;

-import org.eclipse.graphiti.dt.IDiagramTypeProvider;

-import org.eclipse.graphiti.features.FeatureCheckerAdapter;

-import org.eclipse.graphiti.features.ICreateConnectionFeature;

-import org.eclipse.graphiti.features.ICreateFeature;

-import org.eclipse.graphiti.features.IFeature;

-import org.eclipse.graphiti.features.IFeatureAndContext;

-import org.eclipse.graphiti.features.IFeatureChecker;

-import org.eclipse.graphiti.features.IFeatureCheckerHolder;

-import org.eclipse.graphiti.features.IFeatureProvider;

-import org.eclipse.graphiti.features.context.IContext;

-import org.eclipse.graphiti.features.context.IDoubleClickContext;

-import org.eclipse.graphiti.features.context.IPictogramElementContext;

-import org.eclipse.graphiti.features.context.impl.AddContext;

-import org.eclipse.graphiti.features.context.impl.CreateConnectionContext;

-import org.eclipse.graphiti.features.context.impl.CreateContext;

-import org.eclipse.graphiti.features.context.impl.CustomContext;

-import org.eclipse.graphiti.features.context.impl.UpdateContext;

-import org.eclipse.graphiti.features.custom.ICustomFeature;

-import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm;

-import org.eclipse.graphiti.mm.algorithms.Polyline;

-import org.eclipse.graphiti.mm.algorithms.Text;

-import org.eclipse.graphiti.mm.pictograms.Anchor;

-import org.eclipse.graphiti.mm.pictograms.AnchorContainer;

-import org.eclipse.graphiti.mm.pictograms.ContainerShape;

-import org.eclipse.graphiti.mm.pictograms.Diagram;

-import org.eclipse.graphiti.mm.pictograms.PictogramElement;

-import org.eclipse.graphiti.mm.pictograms.Shape;

-import org.eclipse.graphiti.palette.IPaletteCompartmentEntry;

-import org.eclipse.graphiti.palette.impl.ConnectionCreationToolEntry;

-import org.eclipse.graphiti.palette.impl.ObjectCreationToolEntry;

-import org.eclipse.graphiti.palette.impl.PaletteCompartmentEntry;

-import org.eclipse.graphiti.services.Graphiti;

-import org.eclipse.graphiti.tb.ContextButtonEntry;

-import org.eclipse.graphiti.tb.DefaultToolBehaviorProvider;

-import org.eclipse.graphiti.tb.IContextButtonPadData;

-import org.eclipse.graphiti.ui.editor.DiagramEditor;

-import org.eclipse.jface.dialogs.MessageDialog;

-

-public class BpmnToolBehaviourFeature extends DefaultToolBehaviorProvider implements IFeatureCheckerHolder {

-

-	BPMNFeatureProvider featureProvider;

-	ModelEnablementDescriptor modelEnablements;

-	

-	public BpmnToolBehaviourFeature(IDiagramTypeProvider diagramTypeProvider) {

-		super(diagramTypeProvider);

-	}

-

-	@Override

-	public IPaletteCompartmentEntry[] getPalette() {

-

-		EList<Resource> resources = getDiagramTypeProvider().getDiagram().eResource().getResourceSet().getResources();

-		IProject project = null;

-		for (Resource resource : resources) {

-			if (resource.getURI().segmentCount() > 1) {

-				String projectName = resource.getURI().segment(1);

-				project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);

-				if (project != null) {

-					break;

-				}

-			}

-		}

-

-		BPMN2Editor editor = (BPMN2Editor)getDiagramTypeProvider().getDiagramEditor();

-		Diagram diagram = getDiagramTypeProvider().getDiagram();

-		Object object = Graphiti.getLinkService().getBusinessObjectForLinkedPictogramElement(diagram);

-		modelEnablements = editor.getTargetRuntime().getModelEnablements((EObject)object);

-		featureProvider = (BPMNFeatureProvider)getFeatureProvider();

-		

-		List<IPaletteCompartmentEntry> palette = new ArrayList<IPaletteCompartmentEntry>();

-

-		// add compartments from super class

-		createConnectors(palette);

-		createTasksCompartments(palette);

-		createGatewaysCompartments(palette);

-		createEventsCompartments(palette);

-		createEventDefinitionsCompartments(palette);

-		createDataCompartments(palette);

-		createOtherCompartments(palette);

-		createCustomTasks(palette);

-

-		return palette.toArray(new IPaletteCompartmentEntry[palette.size()]);

-	}

-

-	private void createEventsCompartments(List<IPaletteCompartmentEntry> palette) {

-		PaletteCompartmentEntry compartmentEntry = new PaletteCompartmentEntry("Events", null);

-

-		createEntries(FeatureMap.EVENTS, compartmentEntry);

-

-		if (compartmentEntry.getToolEntries().size()>0)

-			palette.add(compartmentEntry);

-	}

-

-	private void createOtherCompartments(List<IPaletteCompartmentEntry> palette) {

-		PaletteCompartmentEntry compartmentEntry = new PaletteCompartmentEntry("Other", null);

-		compartmentEntry.setInitiallyOpen(false);

-

-		createEntries(FeatureMap.OTHER, compartmentEntry);

-

-		if (compartmentEntry.getToolEntries().size()>0)

-			palette.add(compartmentEntry);

-	}

-

-	private void createDataCompartments(List<IPaletteCompartmentEntry> palette) {

-		PaletteCompartmentEntry compartmentEntry = new PaletteCompartmentEntry("Data Items", null);

-		compartmentEntry.setInitiallyOpen(false);

-

-		createEntries(FeatureMap.DATA, compartmentEntry);

-

-		if (compartmentEntry.getToolEntries().size()>0)

-			palette.add(compartmentEntry);

-	}

-

-	private void createEventDefinitionsCompartments(List<IPaletteCompartmentEntry> palette) {

-		PaletteCompartmentEntry compartmentEntry = new PaletteCompartmentEntry("Event Definitions", null);

-		compartmentEntry.setInitiallyOpen(false);

-

-		createEntries(FeatureMap.EVENT_DEFINITIONS, compartmentEntry);

-

-		if (compartmentEntry.getToolEntries().size()>0)

-			palette.add(compartmentEntry);

-	}

-

-	private void createGatewaysCompartments(List<IPaletteCompartmentEntry> palette) {

-		PaletteCompartmentEntry compartmentEntry = new PaletteCompartmentEntry("Gateways", null);

-

-		createEntries(FeatureMap.GATEWAYS, compartmentEntry);

-

-		if (compartmentEntry.getToolEntries().size()>0)

-			palette.add(compartmentEntry);

-	}

-

-	private void createTasksCompartments(List<IPaletteCompartmentEntry> palette) {

-		PaletteCompartmentEntry compartmentEntry = new PaletteCompartmentEntry("Tasks", null);

-

-		createEntries(FeatureMap.TASKS, compartmentEntry);

-

-		if (compartmentEntry.getToolEntries().size()>0)

-			palette.add(compartmentEntry);

-	}

-

-	private void createConnectors(List<IPaletteCompartmentEntry> palette) {

-		PaletteCompartmentEntry compartmentEntry = new PaletteCompartmentEntry("Connectors", null);

-

-		createEntries(FeatureMap.CONNECTORS, compartmentEntry);

-

-		if (compartmentEntry.getToolEntries().size()>0)

-			palette.add(compartmentEntry);

-	}

-

-	private void createEntries(List<Class> neededEntries, PaletteCompartmentEntry compartmentEntry) {

-		for (Class c : neededEntries) {

-			if (modelEnablements.isEnabled(c.getSimpleName())) {

-				IFeature feature = featureProvider.getCreateFeatureForBusinessObject(c);

-				if (feature instanceof ICreateFeature) {

-					ICreateFeature cf = (ICreateFeature)feature;

-					ObjectCreationToolEntry objectCreationToolEntry = new ObjectCreationToolEntry(cf.getCreateName(),

-						cf.getCreateDescription(), cf.getCreateImageId(), cf.getCreateLargeImageId(), cf);

-					compartmentEntry.addToolEntry(objectCreationToolEntry);

-				}

-				else if (feature instanceof ICreateConnectionFeature) {

-					ICreateConnectionFeature cf = (ICreateConnectionFeature)feature;

-					ConnectionCreationToolEntry connectionCreationToolEntry = new ConnectionCreationToolEntry(

-							cf.getCreateName(), cf.getCreateDescription(), cf.getCreateImageId(),

-							cf.getCreateLargeImageId());

-					connectionCreationToolEntry.addCreateConnectionFeature(cf);

-					compartmentEntry.addToolEntry(connectionCreationToolEntry);

-				}

-			}

-		}

-	}

-

-	private void createCustomTasks(List<IPaletteCompartmentEntry> ret) {

-		PaletteCompartmentEntry compartmentEntry = null;

-		BPMN2Editor editor = (BPMN2Editor) getDiagramTypeProvider().getDiagramEditor();

-		TargetRuntime rt = editor.getTargetRuntime();

-		

-		try {

-			for (CustomTaskDescriptor tc : rt.getCustomTasks()) {

-				if (true) {//modelEnablements.isEnabled(tc.getId())) {

-					CustomTaskFeatureContainer container = (CustomTaskFeatureContainer)tc.getFeatureContainer();

-	

-					container.setId(featureProvider, tc.getId());

-					ICreateFeature cf = container.getCreateFeature(featureProvider);

-					ObjectCreationToolEntry objectCreationToolEntry = new ObjectCreationToolEntry(tc.getName(),

-							cf.getCreateDescription(), cf.getCreateImageId(), cf.getCreateLargeImageId(), cf);

-					

-					if (compartmentEntry==null) {

-						compartmentEntry = new PaletteCompartmentEntry("Custom Task", null);

-						compartmentEntry.setInitiallyOpen(false);

-						ret.add(compartmentEntry);

-					}

-					

-					compartmentEntry.addToolEntry(objectCreationToolEntry);

-				}

-			}

-		} catch (Exception ex) {

-			Activator.logError(ex);

-		}

-	}

-

-	@Override

-	public IFeatureChecker getFeatureChecker() {

-		return new FeatureCheckerAdapter(false) {

-			@Override

-			public boolean allowAdd(IContext context) {

-				return super.allowAdd(context);

-			}

-

-			@Override

-			public boolean allowCreate() {

-				return super.allowCreate();

-			}

-		};

-	}

-

-	@Override

-	public GraphicsAlgorithm[] getClickArea(PictogramElement pe) {

-		if (ActivitySelectionBehavior.canApplyTo(pe)) {

-			return ActivitySelectionBehavior.getClickArea(pe);

-		} else if (EventSelectionBehavior.canApplyTo(pe)) {

-			return EventSelectionBehavior.getClickArea(pe);

-		} else if (ChoreographySelectionBehavior.canApplyTo(pe)) {

-			return ChoreographySelectionBehavior.getClickArea(pe);

-		}

-		return super.getClickArea(pe);

-	}

-

-	@Override

-	public GraphicsAlgorithm getSelectionBorder(PictogramElement pe) {

-		if (ActivitySelectionBehavior.canApplyTo(pe)) {

-			return ActivitySelectionBehavior.getSelectionBorder(pe);

-		} else if (EventSelectionBehavior.canApplyTo(pe)) {

-			return EventSelectionBehavior.getSelectionBorder(pe);

-		} else if (ChoreographySelectionBehavior.canApplyTo(pe)) {

-			return ChoreographySelectionBehavior.getSelectionBorder(pe);

-		}

-		else if (pe instanceof ContainerShape) {

-			if (((ContainerShape)pe).getChildren().size()>0) {

-				GraphicsAlgorithm ga = ((ContainerShape)pe).getChildren().get(0).getGraphicsAlgorithm();

-				if (!(ga instanceof Text) && !(ga instanceof Polyline))

-					return ga;

-				ga = ((ContainerShape)pe).getGraphicsAlgorithm();

-				if (ga.getGraphicsAlgorithmChildren().size()>0)

-					return ga.getGraphicsAlgorithmChildren().get(0);

-				return ga;

-			}

-		}

-		else if (pe instanceof Shape) {

-			return ((Shape)pe).getGraphicsAlgorithm();

-		}

-		return super.getSelectionBorder(pe);

-	}

-

-	@Override

-	public IContextButtonPadData getContextButtonPad(IPictogramElementContext context) {

-		IContextButtonPadData data = super.getContextButtonPad(context);

-		PictogramElement pe = context.getPictogramElement();

-		IFeatureProvider fp = getFeatureProvider();

-

-		String labelProperty = Graphiti.getPeService().getPropertyValue(pe, GraphicsUtil.LABEL_PROPERTY);

-		if (Boolean.parseBoolean(labelProperty)) {

-			// labels don't have a buttonpad

-			setGenericContextButtons(data, pe, 0);

-			return data;

-		}

-

-		if( pe.getGraphicsAlgorithm()!= null && pe.getGraphicsAlgorithm().getWidth() < 40 ){

-		    ILocation origin = getAbsoluteLocation(pe.getGraphicsAlgorithm());

-		    data.getPadLocation().setRectangle(origin.getX(), origin.getY(), 40, 40);

-		}

-		

-		// 1. set the generic context buttons

-		// Participant bands can only be removed from the choreograpy task

-		int genericButtons = CONTEXT_BUTTON_DELETE;

-		if (ChoreographyUtil.isChoreographyParticipantBand(pe)) {

-			genericButtons |= CONTEXT_BUTTON_REMOVE;

-		}

-		setGenericContextButtons(data, pe, genericButtons);

-

-		// 2. set the expand & collapse buttons

-		CustomContext cc = new CustomContext(new PictogramElement[] { pe });

-		ICustomFeature[] cf = fp.getCustomFeatures(cc);

-		for (int i = 0; i < cf.length; i++) {

-			ICustomFeature iCustomFeature = cf[i];

-			if (iCustomFeature.canExecute(cc)) {

-				ContextButtonEntry button = new ContextButtonEntry(iCustomFeature, cc);

-				button.setText(iCustomFeature.getName()); //$NON-NLS-1$

-				button.setIconId(iCustomFeature.getImageId());

-				button.setDescription(iCustomFeature.getDescription());

-				

-				data.getDomainSpecificContextButtons().add(button);

-			}

-		}

-

-		// 3. add one domain specific context-button, which offers all

-		// available connection-features as drag&drop features...

-

-		// 3.a. create new CreateConnectionContext

-		CreateConnectionContext ccc = new CreateConnectionContext();

-		ccc.setSourcePictogramElement(pe);

-		Anchor anchor = null;

-		if (pe instanceof Anchor) {

-			anchor = (Anchor) pe;

-		} else if (pe instanceof AnchorContainer) {

-			// assume, that our shapes always have chopbox anchors

-			anchor = Graphiti.getPeService().getChopboxAnchor((AnchorContainer) pe);

-		}

-		ccc.setSourceAnchor(anchor);

-

-		// 3.b. create context button and add "Create Connections" feature

-		ICreateConnectionFeature[] features = fp.getCreateConnectionFeatures();

-		ContextButtonEntry button = new ContextButtonEntry(null, context);

-		button.setText("Create Connection"); //$NON-NLS-1$

-		String description = null;

-		ArrayList<String> names = new ArrayList<String>();

-		button.setIconId(ImageProvider.IMG_16_SEQUENCE_FLOW);

-		for (ICreateConnectionFeature feature : features) {

-			if (feature.isAvailable(ccc) && feature.canStartConnection(ccc)) {

-				button.addDragAndDropFeature(feature);

-				names.add(feature.getCreateName());

-			}

-		}

-		

-		// 3.c. build a reasonable description for the context button action 

-		for (int i=0; i<names.size(); ++i) {

-			if (description==null)

-				description = "Click and drag to create a\n";

-			description += names.get(i);

-			if (i+2 == names.size())

-				description += " or ";

-			else if (i+1 < names.size())

-				description += ", ";

-		}

-		button.setDescription(description);

-

-		// 3.d. add context button, button only if it contains at least one feature

-		if (button.getDragAndDropFeatures().size() > 0) {

-			data.getDomainSpecificContextButtons().add(button);

-		}

-

-		return data;

-	}

-

-	@Override

-	public void postExecute(IExecutionInfo executionInfo) {

-		BPMN2Editor editor = (BPMN2Editor)getDiagramTypeProvider().getDiagramEditor();

-		for (IFeatureAndContext fc : executionInfo.getExecutionList()) {

-			IContext context = fc.getContext();

-			IFeature feature = fc.getFeature();

-			if (context instanceof AddContext) {

-				if (feature instanceof IBpmn2AddFeature) {

-					((IBpmn2AddFeature)feature).postExecute(executionInfo);

-				}

-			}

-			else if (context instanceof CreateContext) {

-				if (feature instanceof IBpmn2CreateFeature) {

-					((IBpmn2CreateFeature)feature).postExecute(executionInfo);

-				}

-			}

-			else if (context instanceof UpdateContext) {

-				editor.setPictogramElementForSelection(

-						((UpdateContext)context).getPictogramElement());

-				editor.refresh();

-			}

-		}

-	}

-

-	@Override

-	public ICustomFeature getDoubleClickFeature(IDoubleClickContext context) {

-		ICustomFeature[] cf = getFeatureProvider().getCustomFeatures(context);

-		for (int i = 0; i < cf.length; i++) {

-			ICustomFeature iCustomFeature = cf[i];

-			if (iCustomFeature.canExecute(context)) {

-				return iCustomFeature;

-			}

-		}

-		return null;

-	}

-

-	@Override

-	public GraphicsAlgorithm getChopboxAnchorArea(PictogramElement pe) {

-		return super.getChopboxAnchorArea(pe);

-	}

-

+/******************************************************************************* 
+ * Copyright (c) 2011 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 Innar Made
+ ******************************************************************************/
+package org.eclipse.bpmn2.modeler.ui.diagram;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.bpmn2.modeler.core.Activator;
+import org.eclipse.bpmn2.modeler.core.features.IBpmn2AddFeature;
+import org.eclipse.bpmn2.modeler.core.features.IBpmn2CreateFeature;
+import org.eclipse.bpmn2.modeler.core.features.activity.ActivitySelectionBehavior;
+import org.eclipse.bpmn2.modeler.core.features.event.EventSelectionBehavior;
+import org.eclipse.bpmn2.modeler.core.runtime.CustomTaskDescriptor;
+import org.eclipse.bpmn2.modeler.core.runtime.ModelEnablementDescriptor;
+import org.eclipse.bpmn2.modeler.core.runtime.TargetRuntime;
+import org.eclipse.bpmn2.modeler.core.utils.GraphicsUtil;
+import org.eclipse.bpmn2.modeler.ui.FeatureMap;
+import org.eclipse.bpmn2.modeler.ui.ImageProvider;
+import org.eclipse.bpmn2.modeler.ui.editor.BPMN2Editor;
+import org.eclipse.bpmn2.modeler.ui.features.activity.task.CustomTaskFeatureContainer;
+import org.eclipse.bpmn2.modeler.ui.features.choreography.ChoreographySelectionBehavior;
+import org.eclipse.bpmn2.modeler.ui.features.choreography.ChoreographyUtil;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.graphiti.IExecutionInfo;
+import org.eclipse.graphiti.datatypes.ILocation;
+import org.eclipse.graphiti.dt.IDiagramTypeProvider;
+import org.eclipse.graphiti.features.FeatureCheckerAdapter;
+import org.eclipse.graphiti.features.ICreateConnectionFeature;
+import org.eclipse.graphiti.features.ICreateFeature;
+import org.eclipse.graphiti.features.IFeature;
+import org.eclipse.graphiti.features.IFeatureAndContext;
+import org.eclipse.graphiti.features.IFeatureChecker;
+import org.eclipse.graphiti.features.IFeatureCheckerHolder;
+import org.eclipse.graphiti.features.IFeatureProvider;
+import org.eclipse.graphiti.features.context.IContext;
+import org.eclipse.graphiti.features.context.IDoubleClickContext;
+import org.eclipse.graphiti.features.context.IPictogramElementContext;
+import org.eclipse.graphiti.features.context.impl.AddContext;
+import org.eclipse.graphiti.features.context.impl.CreateConnectionContext;
+import org.eclipse.graphiti.features.context.impl.CreateContext;
+import org.eclipse.graphiti.features.context.impl.CustomContext;
+import org.eclipse.graphiti.features.context.impl.UpdateContext;
+import org.eclipse.graphiti.features.custom.ICustomFeature;
+import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm;
+import org.eclipse.graphiti.mm.algorithms.Polyline;
+import org.eclipse.graphiti.mm.algorithms.Text;
+import org.eclipse.graphiti.mm.pictograms.Anchor;
+import org.eclipse.graphiti.mm.pictograms.AnchorContainer;
+import org.eclipse.graphiti.mm.pictograms.ContainerShape;
+import org.eclipse.graphiti.mm.pictograms.Diagram;
+import org.eclipse.graphiti.mm.pictograms.PictogramElement;
+import org.eclipse.graphiti.mm.pictograms.Shape;
+import org.eclipse.graphiti.palette.IPaletteCompartmentEntry;
+import org.eclipse.graphiti.palette.impl.ConnectionCreationToolEntry;
+import org.eclipse.graphiti.palette.impl.ObjectCreationToolEntry;
+import org.eclipse.graphiti.palette.impl.PaletteCompartmentEntry;
+import org.eclipse.graphiti.services.Graphiti;
+import org.eclipse.graphiti.tb.ContextButtonEntry;
+import org.eclipse.graphiti.tb.DefaultToolBehaviorProvider;
+import org.eclipse.graphiti.tb.IContextButtonPadData;
+import org.eclipse.graphiti.ui.editor.DiagramEditor;
+import org.eclipse.jface.dialogs.MessageDialog;
+
+public class BpmnToolBehaviourFeature extends DefaultToolBehaviorProvider implements IFeatureCheckerHolder {
+
+	BPMNFeatureProvider featureProvider;
+	ModelEnablementDescriptor modelEnablements;
+	
+	public BpmnToolBehaviourFeature(IDiagramTypeProvider diagramTypeProvider) {
+		super(diagramTypeProvider);
+	}
+
+	@Override
+	public IPaletteCompartmentEntry[] getPalette() {
+
+		EList<Resource> resources = getDiagramTypeProvider().getDiagram().eResource().getResourceSet().getResources();
+		IProject project = null;
+		for (Resource resource : resources) {
+			if (resource.getURI().segmentCount() > 1) {
+				String projectName = resource.getURI().segment(1);
+				project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
+				if (project != null) {
+					break;
+				}
+			}
+		}
+
+		BPMN2Editor editor = (BPMN2Editor)getDiagramTypeProvider().getDiagramEditor();
+		Diagram diagram = getDiagramTypeProvider().getDiagram();
+		Object object = Graphiti.getLinkService().getBusinessObjectForLinkedPictogramElement(diagram);
+		modelEnablements = editor.getTargetRuntime().getModelEnablements((EObject)object);
+		featureProvider = (BPMNFeatureProvider)getFeatureProvider();
+		
+		List<IPaletteCompartmentEntry> palette = new ArrayList<IPaletteCompartmentEntry>();
+
+		// add compartments from super class
+		createConnectors(palette);
+		createTasksCompartments(palette);
+		createGatewaysCompartments(palette);
+		createEventsCompartments(palette);
+		createEventDefinitionsCompartments(palette);
+		createDataCompartments(palette);
+		createOtherCompartments(palette);
+		createCustomTasks(palette);
+
+		return palette.toArray(new IPaletteCompartmentEntry[palette.size()]);
+	}
+
+	private void createEventsCompartments(List<IPaletteCompartmentEntry> palette) {
+		PaletteCompartmentEntry compartmentEntry = new PaletteCompartmentEntry("Events", null);
+
+		createEntries(FeatureMap.EVENTS, compartmentEntry);
+
+		if (compartmentEntry.getToolEntries().size()>0)
+			palette.add(compartmentEntry);
+	}
+
+	private void createOtherCompartments(List<IPaletteCompartmentEntry> palette) {
+		PaletteCompartmentEntry compartmentEntry = new PaletteCompartmentEntry("Other", null);
+		compartmentEntry.setInitiallyOpen(false);
+
+		createEntries(FeatureMap.OTHER, compartmentEntry);
+
+		if (compartmentEntry.getToolEntries().size()>0)
+			palette.add(compartmentEntry);
+	}
+
+	private void createDataCompartments(List<IPaletteCompartmentEntry> palette) {
+		PaletteCompartmentEntry compartmentEntry = new PaletteCompartmentEntry("Data Items", null);
+		compartmentEntry.setInitiallyOpen(false);
+
+		createEntries(FeatureMap.DATA, compartmentEntry);
+
+		if (compartmentEntry.getToolEntries().size()>0)
+			palette.add(compartmentEntry);
+	}
+
+	private void createEventDefinitionsCompartments(List<IPaletteCompartmentEntry> palette) {
+		PaletteCompartmentEntry compartmentEntry = new PaletteCompartmentEntry("Event Definitions", null);
+		compartmentEntry.setInitiallyOpen(false);
+
+		createEntries(FeatureMap.EVENT_DEFINITIONS, compartmentEntry);
+
+		if (compartmentEntry.getToolEntries().size()>0)
+			palette.add(compartmentEntry);
+	}
+
+	private void createGatewaysCompartments(List<IPaletteCompartmentEntry> palette) {
+		PaletteCompartmentEntry compartmentEntry = new PaletteCompartmentEntry("Gateways", null);
+
+		createEntries(FeatureMap.GATEWAYS, compartmentEntry);
+
+		if (compartmentEntry.getToolEntries().size()>0)
+			palette.add(compartmentEntry);
+	}
+
+	private void createTasksCompartments(List<IPaletteCompartmentEntry> palette) {
+		PaletteCompartmentEntry compartmentEntry = new PaletteCompartmentEntry("Tasks", null);
+
+		createEntries(FeatureMap.TASKS, compartmentEntry);
+
+		if (compartmentEntry.getToolEntries().size()>0)
+			palette.add(compartmentEntry);
+	}
+
+	private void createConnectors(List<IPaletteCompartmentEntry> palette) {
+		PaletteCompartmentEntry compartmentEntry = new PaletteCompartmentEntry("Connectors", null);
+
+		createEntries(FeatureMap.CONNECTORS, compartmentEntry);
+
+		if (compartmentEntry.getToolEntries().size()>0)
+			palette.add(compartmentEntry);
+	}
+
+	private void createEntries(List<Class> neededEntries, PaletteCompartmentEntry compartmentEntry) {
+		for (Class c : neededEntries) {
+			if (modelEnablements.isEnabled(c.getSimpleName())) {
+				IFeature feature = featureProvider.getCreateFeatureForBusinessObject(c);
+				if (feature instanceof ICreateFeature) {
+					ICreateFeature cf = (ICreateFeature)feature;
+					ObjectCreationToolEntry objectCreationToolEntry = new ObjectCreationToolEntry(cf.getCreateName(),
+						cf.getCreateDescription(), cf.getCreateImageId(), cf.getCreateLargeImageId(), cf);
+					compartmentEntry.addToolEntry(objectCreationToolEntry);
+				}
+				else if (feature instanceof ICreateConnectionFeature) {
+					ICreateConnectionFeature cf = (ICreateConnectionFeature)feature;
+					ConnectionCreationToolEntry connectionCreationToolEntry = new ConnectionCreationToolEntry(
+							cf.getCreateName(), cf.getCreateDescription(), cf.getCreateImageId(),
+							cf.getCreateLargeImageId());
+					connectionCreationToolEntry.addCreateConnectionFeature(cf);
+					compartmentEntry.addToolEntry(connectionCreationToolEntry);
+				}
+			}
+		}
+	}
+
+	private void createCustomTasks(List<IPaletteCompartmentEntry> ret) {
+		PaletteCompartmentEntry compartmentEntry = null;
+		BPMN2Editor editor = (BPMN2Editor) getDiagramTypeProvider().getDiagramEditor();
+		TargetRuntime rt = editor.getTargetRuntime();
+		
+		try {
+			for (CustomTaskDescriptor tc : rt.getCustomTasks()) {
+				if (true) {//modelEnablements.isEnabled(tc.getId())) {
+					CustomTaskFeatureContainer container = (CustomTaskFeatureContainer)tc.getFeatureContainer();
+	
+					container.setId(featureProvider, tc.getId());
+					ICreateFeature cf = container.getCreateFeature(featureProvider);
+					ObjectCreationToolEntry objectCreationToolEntry = new ObjectCreationToolEntry(tc.getName(),
+							cf.getCreateDescription(), cf.getCreateImageId(), cf.getCreateLargeImageId(), cf);
+					
+					if (compartmentEntry==null) {
+						compartmentEntry = new PaletteCompartmentEntry("Custom Task", null);
+						compartmentEntry.setInitiallyOpen(false);
+						ret.add(compartmentEntry);
+					}
+					
+					compartmentEntry.addToolEntry(objectCreationToolEntry);
+				}
+			}
+		} catch (Exception ex) {
+			Activator.logError(ex);
+		}
+	}
+
+	@Override
+	public IFeatureChecker getFeatureChecker() {
+		return new FeatureCheckerAdapter(false) {
+			@Override
+			public boolean allowAdd(IContext context) {
+				return super.allowAdd(context);
+			}
+
+			@Override
+			public boolean allowCreate() {
+				return super.allowCreate();
+			}
+		};
+	}
+
+	@Override
+	public GraphicsAlgorithm[] getClickArea(PictogramElement pe) {
+		if (ActivitySelectionBehavior.canApplyTo(pe)) {
+			return ActivitySelectionBehavior.getClickArea(pe);
+		} else if (EventSelectionBehavior.canApplyTo(pe)) {
+			return EventSelectionBehavior.getClickArea(pe);
+		} else if (ChoreographySelectionBehavior.canApplyTo(pe)) {
+			return ChoreographySelectionBehavior.getClickArea(pe);
+		}
+		return super.getClickArea(pe);
+	}
+
+	@Override
+	public GraphicsAlgorithm getSelectionBorder(PictogramElement pe) {
+		if (ActivitySelectionBehavior.canApplyTo(pe)) {
+			return ActivitySelectionBehavior.getSelectionBorder(pe);
+		} else if (EventSelectionBehavior.canApplyTo(pe)) {
+			return EventSelectionBehavior.getSelectionBorder(pe);
+		} else if (ChoreographySelectionBehavior.canApplyTo(pe)) {
+			return ChoreographySelectionBehavior.getSelectionBorder(pe);
+		}
+		else if (pe instanceof ContainerShape) {
+			if (((ContainerShape)pe).getChildren().size()>0) {
+				GraphicsAlgorithm ga = ((ContainerShape)pe).getChildren().get(0).getGraphicsAlgorithm();
+				if (!(ga instanceof Text) && !(ga instanceof Polyline))
+					return ga;
+				ga = ((ContainerShape)pe).getGraphicsAlgorithm();
+				if (ga.getGraphicsAlgorithmChildren().size()>0)
+					return ga.getGraphicsAlgorithmChildren().get(0);
+				return ga;
+			}
+		}
+		else if (pe instanceof Shape) {
+			return ((Shape)pe).getGraphicsAlgorithm();
+		}
+		return super.getSelectionBorder(pe);
+	}
+
+	@Override
+	public IContextButtonPadData getContextButtonPad(IPictogramElementContext context) {
+		IContextButtonPadData data = super.getContextButtonPad(context);
+		PictogramElement pe = context.getPictogramElement();
+		IFeatureProvider fp = getFeatureProvider();
+
+		String labelProperty = Graphiti.getPeService().getPropertyValue(pe, GraphicsUtil.LABEL_PROPERTY);
+		if (Boolean.parseBoolean(labelProperty)) {
+			// labels don't have a buttonpad
+			setGenericContextButtons(data, pe, 0);
+			return data;
+		}
+
+		if( pe.getGraphicsAlgorithm()!= null && pe.getGraphicsAlgorithm().getWidth() < 40 ){
+		    ILocation origin = getAbsoluteLocation(pe.getGraphicsAlgorithm());
+		    data.getPadLocation().setRectangle(origin.getX(), origin.getY(), 40, 40);
+		}
+		
+		// 1. set the generic context buttons
+		// Participant bands can only be removed from the choreograpy task
+		int genericButtons = CONTEXT_BUTTON_DELETE;
+		if (ChoreographyUtil.isChoreographyParticipantBand(pe)) {
+			genericButtons |= CONTEXT_BUTTON_REMOVE;
+		}
+		setGenericContextButtons(data, pe, genericButtons);
+
+		// 2. set the expand & collapse buttons
+		CustomContext cc = new CustomContext(new PictogramElement[] { pe });
+		ICustomFeature[] cf = fp.getCustomFeatures(cc);
+		for (int i = 0; i < cf.length; i++) {
+			ICustomFeature iCustomFeature = cf[i];
+			if (iCustomFeature.canExecute(cc)) {
+				ContextButtonEntry button = new ContextButtonEntry(iCustomFeature, cc);
+				button.setText(iCustomFeature.getName()); //$NON-NLS-1$
+				button.setIconId(iCustomFeature.getImageId());
+				button.setDescription(iCustomFeature.getDescription());
+				
+				data.getDomainSpecificContextButtons().add(button);
+			}
+		}
+
+		// 3. add one domain specific context-button, which offers all
+		// available connection-features as drag&drop features...
+
+		// 3.a. create new CreateConnectionContext
+		CreateConnectionContext ccc = new CreateConnectionContext();
+		ccc.setSourcePictogramElement(pe);
+		Anchor anchor = null;
+		if (pe instanceof Anchor) {
+			anchor = (Anchor) pe;
+		} else if (pe instanceof AnchorContainer) {
+			// assume, that our shapes always have chopbox anchors
+			anchor = Graphiti.getPeService().getChopboxAnchor((AnchorContainer) pe);
+		}
+		ccc.setSourceAnchor(anchor);
+
+		// 3.b. create context button and add "Create Connections" feature
+		ICreateConnectionFeature[] features = fp.getCreateConnectionFeatures();
+		ContextButtonEntry button = new ContextButtonEntry(null, context);
+		button.setText("Create Connection"); //$NON-NLS-1$
+		String description = null;
+		ArrayList<String> names = new ArrayList<String>();
+		button.setIconId(ImageProvider.IMG_16_SEQUENCE_FLOW);
+		for (ICreateConnectionFeature feature : features) {
+			if (feature.isAvailable(ccc) && feature.canStartConnection(ccc)) {
+				button.addDragAndDropFeature(feature);
+				names.add(feature.getCreateName());
+			}
+		}
+		
+		// 3.c. build a reasonable description for the context button action 
+		for (int i=0; i<names.size(); ++i) {
+			if (description==null)
+				description = "Click and drag to create a\n";
+			description += names.get(i);
+			if (i+2 == names.size())
+				description += " or ";
+			else if (i+1 < names.size())
+				description += ", ";
+		}
+		button.setDescription(description);
+
+		// 3.d. add context button, button only if it contains at least one feature
+		if (button.getDragAndDropFeatures().size() > 0) {
+			data.getDomainSpecificContextButtons().add(button);
+		}
+
+		return data;
+	}
+
+	@Override
+	public void postExecute(IExecutionInfo executionInfo) {
+		BPMN2Editor editor = (BPMN2Editor)getDiagramTypeProvider().getDiagramEditor();
+		for (IFeatureAndContext fc : executionInfo.getExecutionList()) {
+			IContext context = fc.getContext();
+			IFeature feature = fc.getFeature();
+			if (context instanceof AddContext) {
+				if (feature instanceof IBpmn2AddFeature) {
+					((IBpmn2AddFeature)feature).postExecute(executionInfo);
+				}
+			}
+			else if (context instanceof CreateContext) {
+				if (feature instanceof IBpmn2CreateFeature) {
+					((IBpmn2CreateFeature)feature).postExecute(executionInfo);
+				}
+			}
+			else if (context instanceof UpdateContext) {
+				editor.setPictogramElementForSelection(
+						((UpdateContext)context).getPictogramElement());
+				editor.refresh();
+			}
+		}
+	}
+
+	@Override
+	public ICustomFeature getDoubleClickFeature(IDoubleClickContext context) {
+		ICustomFeature[] cf = getFeatureProvider().getCustomFeatures(context);
+		for (int i = 0; i < cf.length; i++) {
+			ICustomFeature iCustomFeature = cf[i];
+			if (iCustomFeature.canExecute(context)) {
+				return iCustomFeature;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public GraphicsAlgorithm getChopboxAnchorArea(PictogramElement pe) {
+		return super.getChopboxAnchorArea(pe);
+	}
+
 }
\ No newline at end of file
diff --git a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/editor/BPMN2EditorUpdateBehavior.java b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/editor/BPMN2EditorUpdateBehavior.java
index 742a432..d396e43 100644
--- a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/editor/BPMN2EditorUpdateBehavior.java
+++ b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/editor/BPMN2EditorUpdateBehavior.java
@@ -1,126 +1,126 @@
-/*******************************************************************************

- * Copyright (c) 2011 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 Bob Brodt

- ******************************************************************************/

-

-package org.eclipse.bpmn2.modeler.ui.editor;

-

-import org.eclipse.bpmn2.modeler.core.model.Bpmn2ModelerResourceSetImpl;

-import org.eclipse.core.commands.operations.DefaultOperationHistory;

-import org.eclipse.core.resources.IFile;

-import org.eclipse.emf.common.util.URI;

-import org.eclipse.emf.ecore.resource.Resource;

-import org.eclipse.emf.ecore.resource.ResourceSet;

-import org.eclipse.emf.edit.provider.ComposedAdapterFactory;

-import org.eclipse.emf.transaction.TransactionalEditingDomain;

-import org.eclipse.emf.transaction.impl.TransactionalEditingDomainImpl;

-import org.eclipse.emf.workspace.IWorkspaceCommandStack;

-import org.eclipse.emf.workspace.WorkspaceEditingDomainFactory;

-import org.eclipse.graphiti.ui.editor.DefaultUpdateBehavior;

-import org.eclipse.graphiti.ui.editor.DiagramEditor;

-import org.eclipse.graphiti.ui.editor.IDiagramEditorInput;

-import org.eclipse.graphiti.ui.internal.editor.GFWorkspaceCommandStackImpl;

-import org.eclipse.ui.IEditorInput;

-import org.eclipse.emf.workspace.util.WorkspaceSynchronizer;

-

-/**

- * This overrides the DefaultUpdateBehavior provider class from Graphiti. This

- * is necessary because we want to provide our own ResourceSet implementation

- * instead of being forced to deal with the default ResourceSetImpl. See

- * createResourceSetAndEditingDomain() for details.

- * 

- * @author Bob Brodt

- * 

- */

-public class BPMN2EditorUpdateBehavior extends DefaultUpdateBehavior {

-

-	private TransactionalEditingDomain editingDomain;

-	private WorkspaceSynchronizer workspaceSynchronizer;

-

-	/**

-	 * @param diagramEditor

-	 */

-	public BPMN2EditorUpdateBehavior(DiagramEditor diagramEditor) {

-		super(diagramEditor);

-	}

-

-	public TransactionalEditingDomain getEditingDomain() {

-		if (editingDomain == null)

-			createEditingDomain();

-		return editingDomain;

-	}

-

-	@Override

-	public void createEditingDomain() {

-		if (editingDomain == null) {

-			editingDomain = createResourceSetAndEditingDomain();

-			initializeEditingDomain(editingDomain);

-		}

-	}

-

-	public TransactionalEditingDomain createResourceSetAndEditingDomain() {

-		// Argh!! This is the ONLY line of code that actually differs

-		// (significantly) from

-		// the Graphiti EMF Service. Here we want to substitute our own

-		// Bpmn2ModelerResourceSetImpl instead of using a ResourceSetImpl.

-		final ResourceSet resourceSet = new Bpmn2ModelerResourceSetImpl();

-		final IWorkspaceCommandStack workspaceCommandStack = new GFWorkspaceCommandStackImpl(

-				new DefaultOperationHistory());

-

-		final TransactionalEditingDomainImpl editingDomain = new TransactionalEditingDomainImpl(

-				new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE),

-				workspaceCommandStack, resourceSet);

-		WorkspaceEditingDomainFactory.INSTANCE.mapResourceSet(editingDomain);

-		return editingDomain;

-	}

-	

-	protected void initializeEditingDomain(TransactionalEditingDomain domain) {

-		// we want first crack at these notifications!

-		workspaceSynchronizer = new WorkspaceSynchronizer(getEditingDomain(),

-				new BPMN2EditorWorkspaceSynchronizerDelegate(diagramEditor));

-		

-		super.initializeEditingDomain(domain);

-	}

-	

-	public void dispose() {

-		super.dispose();

-		workspaceSynchronizer.dispose();

-	}

-	

-	public class BPMN2EditorWorkspaceSynchronizerDelegate implements WorkspaceSynchronizer.Delegate {

-

-		private BPMN2Editor bpmnEditor;

-

-		/**

-		 * The DiagramEditorBehavior reacts on a setResourceChanged(true) if he gets

-		 * activated.

-		 */

-		public BPMN2EditorWorkspaceSynchronizerDelegate(DiagramEditor diagramEditor) {

-			this.bpmnEditor = (BPMN2Editor)diagramEditor;

-		}

-

-		public void dispose() { 

-			bpmnEditor = null;

-		}

-

-		public boolean handleResourceChanged(Resource resource) {

-			return bpmnEditor.handleResourceChanged(resource);

-		}

-

-		public boolean handleResourceDeleted(Resource resource) {

-			return bpmnEditor.handleResourceDeleted(resource);

-		}

-

-		public boolean handleResourceMoved(Resource resource, URI newURI) {

-			return bpmnEditor.handleResourceMoved(resource, newURI);

-		}

-

+/*******************************************************************************
+ * Copyright (c) 2011 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 Bob Brodt
+ ******************************************************************************/
+
+package org.eclipse.bpmn2.modeler.ui.editor;
+
+import org.eclipse.bpmn2.modeler.core.model.Bpmn2ModelerResourceSetImpl;
+import org.eclipse.core.commands.operations.DefaultOperationHistory;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.emf.transaction.impl.TransactionalEditingDomainImpl;
+import org.eclipse.emf.workspace.IWorkspaceCommandStack;
+import org.eclipse.emf.workspace.WorkspaceEditingDomainFactory;
+import org.eclipse.graphiti.ui.editor.DefaultUpdateBehavior;
+import org.eclipse.graphiti.ui.editor.DiagramEditor;
+import org.eclipse.graphiti.ui.editor.IDiagramEditorInput;
+import org.eclipse.graphiti.ui.internal.editor.GFWorkspaceCommandStackImpl;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.emf.workspace.util.WorkspaceSynchronizer;
+
+/**
+ * This overrides the DefaultUpdateBehavior provider class from Graphiti. This
+ * is necessary because we want to provide our own ResourceSet implementation
+ * instead of being forced to deal with the default ResourceSetImpl. See
+ * createResourceSetAndEditingDomain() for details.
+ * 
+ * @author Bob Brodt
+ * 
+ */
+public class BPMN2EditorUpdateBehavior extends DefaultUpdateBehavior {
+
+	private TransactionalEditingDomain editingDomain;
+	private WorkspaceSynchronizer workspaceSynchronizer;
+
+	/**
+	 * @param diagramEditor
+	 */
+	public BPMN2EditorUpdateBehavior(DiagramEditor diagramEditor) {
+		super(diagramEditor);
+	}
+
+	public TransactionalEditingDomain getEditingDomain() {
+		if (editingDomain == null)
+			createEditingDomain();
+		return editingDomain;
+	}
+
+	@Override
+	public void createEditingDomain() {
+		if (editingDomain == null) {
+			editingDomain = createResourceSetAndEditingDomain();
+			initializeEditingDomain(editingDomain);
+		}
+	}
+
+	public TransactionalEditingDomain createResourceSetAndEditingDomain() {
+		// Argh!! This is the ONLY line of code that actually differs
+		// (significantly) from
+		// the Graphiti EMF Service. Here we want to substitute our own
+		// Bpmn2ModelerResourceSetImpl instead of using a ResourceSetImpl.
+		final ResourceSet resourceSet = new Bpmn2ModelerResourceSetImpl();
+		final IWorkspaceCommandStack workspaceCommandStack = new GFWorkspaceCommandStackImpl(
+				new DefaultOperationHistory());
+
+		final TransactionalEditingDomainImpl editingDomain = new TransactionalEditingDomainImpl(
+				new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE),
+				workspaceCommandStack, resourceSet);
+		WorkspaceEditingDomainFactory.INSTANCE.mapResourceSet(editingDomain);
+		return editingDomain;
+	}
+	
+	protected void initializeEditingDomain(TransactionalEditingDomain domain) {
+		// we want first crack at these notifications!
+		workspaceSynchronizer = new WorkspaceSynchronizer(getEditingDomain(),
+				new BPMN2EditorWorkspaceSynchronizerDelegate(diagramEditor));
+		
+		super.initializeEditingDomain(domain);
+	}
+	
+	public void dispose() {
+		super.dispose();
+		workspaceSynchronizer.dispose();
+	}
+	
+	public class BPMN2EditorWorkspaceSynchronizerDelegate implements WorkspaceSynchronizer.Delegate {
+
+		private BPMN2Editor bpmnEditor;
+
+		/**
+		 * The DiagramEditorBehavior reacts on a setResourceChanged(true) if he gets
+		 * activated.
+		 */
+		public BPMN2EditorWorkspaceSynchronizerDelegate(DiagramEditor diagramEditor) {
+			this.bpmnEditor = (BPMN2Editor)diagramEditor;
+		}
+
+		public void dispose() { 
+			bpmnEditor = null;
+		}
+
+		public boolean handleResourceChanged(Resource resource) {
+			return bpmnEditor.handleResourceChanged(resource);
+		}
+
+		public boolean handleResourceDeleted(Resource resource) {
+			return bpmnEditor.handleResourceDeleted(resource);
+		}
+
+		public boolean handleResourceMoved(Resource resource, URI newURI) {
+			return bpmnEditor.handleResourceMoved(resource, newURI);
+		}
+
 	}}
\ No newline at end of file