Merge "Bug 513318: [BPMN] UnsupportedOperationException when creating a subprocess  merge from papyrus/streams/2.0-maintenance 93412837d1"
diff --git a/org.eclipse.papyrus.bpmn.tests/src/org/eclipse/papyrus/bpmn/bpmnprofiletest/BPMNProcessCustomTest.java b/org.eclipse.papyrus.bpmn.tests/src/org/eclipse/papyrus/bpmn/bpmnprofiletest/BPMNProcessCustomTest.java
index ea92375..df76d72 100755
--- a/org.eclipse.papyrus.bpmn.tests/src/org/eclipse/papyrus/bpmn/bpmnprofiletest/BPMNProcessCustomTest.java
+++ b/org.eclipse.papyrus.bpmn.tests/src/org/eclipse/papyrus/bpmn/bpmnprofiletest/BPMNProcessCustomTest.java
@@ -21,6 +21,7 @@
 import org.eclipse.papyrus.bpmn.BPMNProfile.impl.BPMNProcessCustom;
 import org.eclipse.papyrus.bpmn.util.BPMNResource;
 import org.eclipse.uml2.uml.Activity;
+import org.eclipse.uml2.uml.LoopNode;
 import org.eclipse.uml2.uml.Model;
 import org.eclipse.uml2.uml.OpaqueAction;
 import org.eclipse.uml2.uml.UMLFactory;
@@ -44,12 +45,12 @@
 		StereotypeApplicationHelper.getInstance(null).applyStereotype(activity, BPMNProfilePackage.eINSTANCE.getBPMNProcess());
 
 		OpaqueAction action = UMLFactory.eINSTANCE.createOpaqueAction();
-		activity.getOwnedNodes().add(action);		
+		activity.getOwnedNodes().add(action);
 		task = (Task) StereotypeApplicationHelper.getInstance(null).applyStereotype(action, BPMNProfilePackage.eINSTANCE.getTask());
 
 		bpmnProcess = UMLUtil.getStereotypeApplication(activity, BPMNProcess.class);
 	}
-	
+
 	/*
 	 * test that custom code is present in generated code
 	 */
@@ -78,11 +79,14 @@
 	 */
 	@Test
 	public void getFlowElementsTest(){
-			EList<FlowElement> flowElements = bpmnProcess.getFlowElements();
-			Assert.assertNotNull(flowElements);
-			assertEquals(task, flowElements.get(0));
+		EList<FlowElement> flowElements = bpmnProcess.getFlowElements();
+		Assert.assertNotNull(flowElements);
+		assertEquals(task, flowElements.get(0));
 	}
 	
+	/*
+	 * test that custom code is present in generated code
+	 */
 	@Test
 	public void basicGetSupportsGeneratedTest(){
 		try{
@@ -92,9 +96,56 @@
 			Assert.fail("missing custom code !");
 		}
 	}
-	
+
 	@Test
 	public void basicGetSupportsTest(){
 		assertEquals(bpmnProcess, bpmnProcess.getSupports());
 	}
+
+	/*
+	 * test that custom code is present in generated code
+	 */
+	@Test
+	public void getLaneSetsTest(){
+		try{
+			bpmnProcess.getLaneSets();
+		}
+		catch(UnsupportedOperationException e){
+			Assert.fail("missing custom code !");
+		}
+	}
+	
+	/*
+	 * test nested loops
+	 */
+	@Test
+	public void getFlowElementsLoopNodeTest(){
+		Model model = BPMNResource.createBPMNModel();
+				
+		Activity activity = UMLFactory.eINSTANCE.createActivity();
+		model.getPackagedElements().add(activity);
+		StereotypeApplicationHelper.getInstance(null).applyStereotype(activity, BPMNProfilePackage.eINSTANCE.getBPMNProcess());
+
+		LoopNode loopNode = UMLFactory.eINSTANCE.createLoopNode();
+		activity.getOwnedNodes().add(loopNode);
+		StereotypeApplicationHelper.getInstance(null).applyStereotype(loopNode, BPMNProfilePackage.eINSTANCE.getStandardLoopCharacteristics());
+		
+		LoopNode loopNode2 = UMLFactory.eINSTANCE.createLoopNode();
+		loopNode.getNodes().add(loopNode2);
+		StereotypeApplicationHelper.getInstance(null).applyStereotype(loopNode2, BPMNProfilePackage.eINSTANCE.getStandardLoopCharacteristics());
+		
+		LoopNode loopNode3 = UMLFactory.eINSTANCE.createLoopNode();
+		loopNode2.getNodes().add(loopNode3);
+		StereotypeApplicationHelper.getInstance(null).applyStereotype(loopNode3, BPMNProfilePackage.eINSTANCE.getStandardLoopCharacteristics());
+		
+		OpaqueAction action = UMLFactory.eINSTANCE.createOpaqueAction();
+		loopNode3.getNodes().add(action);
+		Task looptask = (Task) StereotypeApplicationHelper.getInstance(null).applyStereotype(action, BPMNProfilePackage.eINSTANCE.getTask());
+
+		BPMNProcess loopBpmnProcess = UMLUtil.getStereotypeApplication(activity, BPMNProcess.class);
+		
+		EList<FlowElement> flowElements = loopBpmnProcess.getFlowElements();
+		Assert.assertNotNull(flowElements);
+		assertEquals(looptask, flowElements.get(0));
+	}
 }
diff --git a/org.eclipse.papyrus.bpmn.tests/src/org/eclipse/papyrus/bpmn/bpmnprofiletest/SubProcessCustomTest.java b/org.eclipse.papyrus.bpmn.tests/src/org/eclipse/papyrus/bpmn/bpmnprofiletest/SubProcessCustomTest.java
new file mode 100644
index 0000000..f2e4fe4
--- /dev/null
+++ b/org.eclipse.papyrus.bpmn.tests/src/org/eclipse/papyrus/bpmn/bpmnprofiletest/SubProcessCustomTest.java
@@ -0,0 +1,97 @@
+package org.eclipse.papyrus.bpmn.bpmnprofiletest;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.papyrus.bpmn.BPMNProfile.BPMNProcess;
+import org.eclipse.papyrus.bpmn.BPMNProfile.BPMNProfilePackage;
+import org.eclipse.papyrus.bpmn.BPMNProfile.FlowElement;
+import org.eclipse.papyrus.bpmn.BPMNProfile.SubProcess;
+import org.eclipse.papyrus.bpmn.BPMNProfile.Task;
+import org.eclipse.papyrus.bpmn.BPMNProfile.impl.SubProcessCustom;
+import org.eclipse.papyrus.bpmn.util.BPMNResource;
+import org.eclipse.uml2.uml.Activity;
+import org.eclipse.uml2.uml.Model;
+import org.eclipse.uml2.uml.OpaqueAction;
+import org.eclipse.uml2.uml.StructuredActivityNode;
+import org.eclipse.uml2.uml.UMLFactory;
+import org.eclipse.uml2.uml.util.UMLUtil;
+import org.eclipse.uml2.uml.util.UMLUtil.StereotypeApplicationHelper;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class SubProcessCustomTest {
+
+	
+	private SubProcess subProcess;
+	private Task task;
+	
+	@Before	
+	public void setUp(){
+		Model model = BPMNResource.createBPMNModel();
+		
+		Activity activity = UMLFactory.eINSTANCE.createActivity();
+		model.getPackagedElements().add(activity);
+		StereotypeApplicationHelper.getInstance(null).applyStereotype(activity, BPMNProfilePackage.eINSTANCE.getBPMNProcess());
+
+		StructuredActivityNode node = UMLFactory.eINSTANCE.createStructuredActivityNode();
+		activity.getOwnedNodes().add(node);
+		StereotypeApplicationHelper.getInstance(null).applyStereotype(node, BPMNProfilePackage.eINSTANCE.getSubProcess());
+		
+		OpaqueAction action = UMLFactory.eINSTANCE.createOpaqueAction();
+		node.getNodes().add(action);		
+		task = (Task) StereotypeApplicationHelper.getInstance(null).applyStereotype(action, BPMNProfilePackage.eINSTANCE.getTask());
+
+		UMLUtil.getStereotypeApplication(activity, BPMNProcess.class);
+		
+		subProcess = UMLUtil.getStereotypeApplication(node, SubProcess.class);
+	}
+	
+	
+	/*
+	 * test that custom code is present in generated code
+	 */
+	@Test
+	public void getFlowElementsGeneratedTest(){
+		try{
+			subProcess.getFlowElements();
+		}
+		catch(UnsupportedOperationException e){
+			Assert.fail("missing custom code !");
+		}
+	}
+	
+	/*
+	 * test custom code
+	 */
+	@Test
+	public void getFlowElementsCustomTest(){
+		EList<FlowElement> flowElements = SubProcessCustom.getFlowElements(subProcess);
+		Assert.assertNotNull(flowElements);
+		assertEquals(task, flowElements.get(0));
+	}
+	
+	/*
+	 * test full path
+	 */
+	@Test
+	public void getFlowElementsTest(){
+			EList<FlowElement> flowElements = subProcess.getFlowElements();
+			Assert.assertNotNull(flowElements);
+			assertEquals(task, flowElements.get(0));
+	}
+	
+	/*
+	 * test that custom code is present in generated code
+	 */
+	@Test
+	public void getLaneSetTest(){
+		try{
+			subProcess.getLaneSets();
+		}
+		catch(UnsupportedOperationException e){
+			Assert.fail("missing custom code !");
+		}
+	}
+}
diff --git a/org.eclipse.papyrus.bpmn/custom-src/org/eclipse/papyrus/bpmn/BPMNProfile/impl/BPMNProcessCustom.java b/org.eclipse.papyrus.bpmn/custom-src/org/eclipse/papyrus/bpmn/BPMNProfile/impl/BPMNProcessCustom.java
index 276dfd6..34139d9 100755
--- a/org.eclipse.papyrus.bpmn/custom-src/org/eclipse/papyrus/bpmn/BPMNProfile/impl/BPMNProcessCustom.java
+++ b/org.eclipse.papyrus.bpmn/custom-src/org/eclipse/papyrus/bpmn/BPMNProfile/impl/BPMNProcessCustom.java
@@ -24,9 +24,11 @@
 import org.eclipse.papyrus.bpmn.BPMNProfile.BPMNProfilePackage;
 import org.eclipse.papyrus.bpmn.BPMNProfile.BoundaryEvent;
 import org.eclipse.papyrus.bpmn.BPMNProfile.FlowElement;
+import org.eclipse.papyrus.bpmn.BPMNProfile.LaneSet;
 import org.eclipse.papyrus.bpmn.BPMNProfile.Task;
 import org.eclipse.uml2.uml.Activity;
 import org.eclipse.uml2.uml.ActivityNode;
+import org.eclipse.uml2.uml.ActivityPartition;
 import org.eclipse.uml2.uml.Element;
 import org.eclipse.uml2.uml.LoopNode;
 import org.eclipse.uml2.uml.OpaqueAction;
@@ -52,6 +54,28 @@
 		return flowElements;
 	}
 
+	private static List<FlowElement> getFlowElementsInLoop(LoopNode loopNode) {
+		List<FlowElement> flowElements = new ArrayList<>();
+
+		// first, recursively manage nested loop
+		List<LoopNode> loopNodes = loopNode.getNodes().stream()
+				.filter(LoopNode.class::isInstance)
+				.map(LoopNode.class::cast)
+				.collect(Collectors.toList());
+
+		for (LoopNode node : loopNodes) {
+			flowElements.addAll(getFlowElementsInLoop(node));
+		}
+
+		// then process with other elements
+		flowElements.addAll(loopNode.getNodes().stream()
+				.map(e -> UMLUtil.getStereotypeApplication(e, FlowElement.class))
+				.filter(Objects::nonNull)
+				.collect(Collectors.toList()));
+
+		return flowElements;
+	}
+
 	public static EList<FlowElement> getFlowElements(BPMNProcess bpmnProcess) {
 		List<FlowElement> flowElements = new ArrayList<>();
 
@@ -62,13 +86,10 @@
 			EList<ActivityNode> nodes = activity.getNodes();
 
 			for (ActivityNode n : nodes) {
-				log.debug("bpmnProcess " + bpmnProcess.getId() +  " contains " + n.getName());
-				if(n instanceof LoopNode){
-					LoopNode loopNode = (LoopNode)n;
-					flowElements.addAll(loopNode.getNodes().stream()
-						.map(e -> UMLUtil.getStereotypeApplication(e, FlowElement.class))
-						.filter(Objects::nonNull)
-						.collect(Collectors.toList()));
+				log.debug("bpmnProcess " + bpmnProcess.getId() + " contains " + n.getName());
+				if (n instanceof LoopNode) {
+					LoopNode loopNode = (LoopNode) n;
+					flowElements.addAll(getFlowElementsInLoop(loopNode));
 				}
 				if (n instanceof OpaqueAction) {
 					Task task = UMLUtil.getStereotypeApplication(n, Task.class);
@@ -87,7 +108,22 @@
 		}
 
 		// Can't return BasicElist, will throw ClassCastException later, so we need this magic stuff
-		return new UnmodifiableEList<>((BPMNProcessImpl)bpmnProcess, BPMNProfilePackage.eINSTANCE.getFlowElementsContainer_FlowElements(), flowElements.size(), flowElements.toArray());
+		return new UnmodifiableEList<>((BPMNProcessImpl) bpmnProcess, BPMNProfilePackage.eINSTANCE.getFlowElementsContainer_FlowElements(), flowElements.size(), flowElements.toArray());
+	}
+
+
+	public static EList<LaneSet> getLaneSets(BPMNProcess bpmnProcess) {
+		List<LaneSet> laneSet = new ArrayList<>();
+		Activity activity = bpmnProcess.getBase_Activity();
+		if (activity != null) {
+			EList<ActivityPartition> partitions = activity.getPartitions();
+			if (partitions != null && !partitions.isEmpty()) {
+				partitions.stream().map(b -> UMLUtil.getStereotypeApplication(b, LaneSet.class))
+						.filter(Objects::nonNull)
+						.collect(Collectors.toList());
+			}
+		}
+		return new UnmodifiableEList<>((BPMNProcessImpl) bpmnProcess, BPMNProfilePackage.eINSTANCE.getFlowElementsContainer_FlowElements(), laneSet.size(), laneSet.toArray());
 	}
 
 }
diff --git a/org.eclipse.papyrus.bpmn/custom-src/org/eclipse/papyrus/bpmn/BPMNProfile/impl/FlowElementCustom.java b/org.eclipse.papyrus.bpmn/custom-src/org/eclipse/papyrus/bpmn/BPMNProfile/impl/FlowElementCustom.java
index 6b39a45..a581520 100755
--- a/org.eclipse.papyrus.bpmn/custom-src/org/eclipse/papyrus/bpmn/BPMNProfile/impl/FlowElementCustom.java
+++ b/org.eclipse.papyrus.bpmn/custom-src/org/eclipse/papyrus/bpmn/BPMNProfile/impl/FlowElementCustom.java
@@ -31,6 +31,13 @@
 	private FlowElementCustom() {
 	}
 
+	private static Element getLoopContainer(Element container){
+		while (container != null && container instanceof LoopNode) {
+			container = container.getOwner();
+		}
+		return container;
+	}
+	
 	public static FlowElementsContainer basicGetContainer(FlowElement flowElement) {
 		FlowElementsContainer flowElementsContainer = null;
 		Element element = flowElement.getBase_Element();
@@ -39,10 +46,10 @@
 			if (element instanceof ActivityNode || element instanceof ActivityEdge) {
 				Element container = element.getOwner();
 				if (container != null && container instanceof LoopNode) {
-					container = container.getOwner();
+					container = getLoopContainer(container);
 				}
 				if(container != null){
-					log.debug("owner : " + element.getOwner());
+					log.debug("owner : " + container);
 					flowElementsContainer = UMLUtil.getStereotypeApplication(container, FlowElementsContainer.class);
 				}
 			} else if (element instanceof Event) {
diff --git a/org.eclipse.papyrus.bpmn/custom-src/org/eclipse/papyrus/bpmn/BPMNProfile/impl/SubProcessCustom.java b/org.eclipse.papyrus.bpmn/custom-src/org/eclipse/papyrus/bpmn/BPMNProfile/impl/SubProcessCustom.java
new file mode 100644
index 0000000..66bcdf2
--- /dev/null
+++ b/org.eclipse.papyrus.bpmn/custom-src/org/eclipse/papyrus/bpmn/BPMNProfile/impl/SubProcessCustom.java
@@ -0,0 +1,47 @@
+/*****************************************************************************
+ * Copyright (c) 2016 CEA.
+ * <p>
+ * 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
+ * <p>
+ * Contributors:
+ * Géry Deloge (CEATech AQUI) gery.deloge@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.bpmn.BPMNProfile.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.util.EcoreEList.UnmodifiableEList;
+import org.eclipse.papyrus.bpmn.BPMNProfile.BPMNProfilePackage;
+import org.eclipse.papyrus.bpmn.BPMNProfile.FlowElement;
+import org.eclipse.papyrus.bpmn.BPMNProfile.SubProcess;
+import org.eclipse.uml2.uml.ActivityNode;
+import org.eclipse.uml2.uml.StructuredActivityNode;
+import org.eclipse.uml2.uml.util.UMLUtil;
+
+public class SubProcessCustom {
+
+	private SubProcessCustom() {
+	}
+
+	
+	public static EList<FlowElement> getFlowElements(SubProcess subProcess) {
+		List<FlowElement> flowElements = new ArrayList<>();
+		StructuredActivityNode baseNode = (StructuredActivityNode) subProcess.getBase_Element();
+		EList<ActivityNode> nodes;
+		if (baseNode != null && (nodes = baseNode.getNodes()) != null && !nodes.isEmpty()) {
+			flowElements = nodes.stream()
+					.map(e -> UMLUtil.getStereotypeApplication(e, FlowElement.class))
+					.filter(Objects::nonNull)
+					.collect(Collectors.toList());
+		}
+		// Can't return BasicElist, will throw ClassCastException later, so we need this magic stuff
+		return new UnmodifiableEList<>((SubProcessImpl) subProcess, BPMNProfilePackage.eINSTANCE.getFlowElementsContainer_FlowElements(), flowElements.size(), flowElements.toArray());
+	}
+}
diff --git a/org.eclipse.papyrus.bpmn/model/BPMNProfile.ecore b/org.eclipse.papyrus.bpmn/model/BPMNProfile.ecore
index 544977c..4223f5b 100755
--- a/org.eclipse.papyrus.bpmn/model/BPMNProfile.ecore
+++ b/org.eclipse.papyrus.bpmn/model/BPMNProfile.ecore
@@ -157,7 +157,8 @@
   <eClassifiers xsi:type="ecore:EClass" name="FlowElementsContainer" abstract="true"
       eSuperTypes="#//BaseElement">
     <eStructuralFeatures xsi:type="ecore:EReference" name="laneSets" ordered="false"
-        upperBound="-1" eType="#//LaneSet" eOpposite="#//LaneSet/flowElementsContainer"/>
+        upperBound="-1" eType="#//LaneSet" changeable="false" volatile="true" transient="true"
+        derived="true" eOpposite="#//LaneSet/flowElementsContainer"/>
     <eStructuralFeatures xsi:type="ecore:EReference" name="flowElements" ordered="false"
         upperBound="-1" eType="#//FlowElement" changeable="false" volatile="true"
         transient="true" derived="true" eOpposite="#//FlowElement/container"/>
@@ -257,7 +258,8 @@
         upperBound="-1" eType="#//Lane" changeable="false" volatile="true" transient="true"
         derived="true"/>
     <eStructuralFeatures xsi:type="ecore:EReference" name="flowElementsContainer"
-        ordered="false" eType="#//FlowElementsContainer" eOpposite="#//FlowElementsContainer/laneSets"/>
+        ordered="false" eType="#//FlowElementsContainer" volatile="true" transient="true"
+        derived="true" eOpposite="#//FlowElementsContainer/laneSets"/>
   </eClassifiers>
   <eClassifiers xsi:type="ecore:EClass" name="Lane" eSuperTypes="#//BaseElement">
     <eOperations name="LanelaneSet" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean">
diff --git a/org.eclipse.papyrus.bpmn/model/bpmn.profile.uml b/org.eclipse.papyrus.bpmn/model/bpmn.profile.uml
index 6f83a6e..e023433 100755
--- a/org.eclipse.papyrus.bpmn/model/bpmn.profile.uml
+++ b/org.eclipse.papyrus.bpmn/model/bpmn.profile.uml
@@ -13012,11 +13012,11 @@
     </packagedElement>
     <packagedElement xmi:type="uml:Stereotype" xmi:id="BPMNProfile-CoreStructure-Common-FlowElementsContainer" name="FlowElementsContainer" isAbstract="true">
       <generalization xmi:type="uml:Generalization" xmi:id="BPMNProfile-CoreStructure-Common-FlowElementsContainer-generalization" general="BPMNProfile-CoreStructure-Foundation-BaseElement"/>
-      <ownedAttribute xmi:type="uml:Property" xmi:id="BPMNProfile-CoreStructure-Common-FlowElementsContainer-flowElements" name="flowElements" visibility="public" type="BPMNProfile-CoreStructure-Common-FlowElement" isReadOnly="true" association="BPMNProfile-CoreStructure-Common-packagedElement-38" isderived="false">
+      <ownedAttribute xmi:type="uml:Property" xmi:id="BPMNProfile-CoreStructure-Common-FlowElementsContainer-flowElements" name="flowElements" visibility="public" type="BPMNProfile-CoreStructure-Common-FlowElement" isReadOnly="true" isDerived="true" association="BPMNProfile-CoreStructure-Common-packagedElement-38" isderived="false">
         <lowerValue xmi:type="uml:LiteralInteger" xmi:id="BPMNProfile-CoreStructure-Common-FlowElementsContainer-flowElements-lowerValue"/>
         <upperValue xmi:type="uml:LiteralUnlimitedNatural" xmi:id="BPMNProfile-CoreStructure-Common-FlowElementsContainer-flowElements-upperValue" value="*"/>
       </ownedAttribute>
-      <ownedAttribute xmi:type="uml:Property" xmi:id="BPMNProfile-CoreStructure-Common-FlowElementsContainer-laneSets" name="laneSets" visibility="public" type="BPMNProfile-Process-LaneSet" association="BPMNProfile-CoreStructure-Common-packagedElement-42" isderived="false">
+      <ownedAttribute xmi:type="uml:Property" xmi:id="BPMNProfile-CoreStructure-Common-FlowElementsContainer-laneSets" name="laneSets" visibility="public" type="BPMNProfile-Process-LaneSet" isReadOnly="true" isDerived="true" association="BPMNProfile-CoreStructure-Common-packagedElement-42" isderived="false">
         <lowerValue xmi:type="uml:LiteralInteger" xmi:id="BPMNProfile-CoreStructure-Common-FlowElementsContainer-laneSets-lowerValue"/>
         <upperValue xmi:type="uml:LiteralUnlimitedNatural" xmi:id="BPMNProfile-CoreStructure-Common-FlowElementsContainer-laneSets-upperValue" value="*"/>
       </ownedAttribute>
diff --git a/org.eclipse.papyrus.bpmn/src/org/eclipse/papyrus/bpmn/BPMNProfile/FlowElementsContainer.java b/org.eclipse.papyrus.bpmn/src/org/eclipse/papyrus/bpmn/BPMNProfile/FlowElementsContainer.java
index 1847c60..5d8e81b 100755
--- a/org.eclipse.papyrus.bpmn/src/org/eclipse/papyrus/bpmn/BPMNProfile/FlowElementsContainer.java
+++ b/org.eclipse.papyrus.bpmn/src/org/eclipse/papyrus/bpmn/BPMNProfile/FlowElementsContainer.java
@@ -35,7 +35,7 @@
 	 * @return the value of the '<em>Lane Sets</em>' reference list.
 	 * @see org.eclipse.papyrus.bpmn.BPMNProfile.BPMNProfilePackage#getFlowElementsContainer_LaneSets()
 	 * @see org.eclipse.papyrus.bpmn.BPMNProfile.LaneSet#getFlowElementsContainer
-	 * @model opposite="flowElementsContainer" ordered="false"
+	 * @model opposite="flowElementsContainer" transient="true" changeable="false" volatile="true" derived="true" ordered="false"
 	 * @generated
 	 */
 	EList<LaneSet> getLaneSets();
diff --git a/org.eclipse.papyrus.bpmn/src/org/eclipse/papyrus/bpmn/BPMNProfile/LaneSet.java b/org.eclipse.papyrus.bpmn/src/org/eclipse/papyrus/bpmn/BPMNProfile/LaneSet.java
index 95c2d0b..eaefba6 100755
--- a/org.eclipse.papyrus.bpmn/src/org/eclipse/papyrus/bpmn/BPMNProfile/LaneSet.java
+++ b/org.eclipse.papyrus.bpmn/src/org/eclipse/papyrus/bpmn/BPMNProfile/LaneSet.java
@@ -101,7 +101,7 @@
 	 * @see #setFlowElementsContainer(FlowElementsContainer)
 	 * @see org.eclipse.papyrus.bpmn.BPMNProfile.BPMNProfilePackage#getLaneSet_FlowElementsContainer()
 	 * @see org.eclipse.papyrus.bpmn.BPMNProfile.FlowElementsContainer#getLaneSets
-	 * @model opposite="laneSets" ordered="false"
+	 * @model opposite="laneSets" transient="true" volatile="true" derived="true" ordered="false"
 	 * @generated
 	 */
 	FlowElementsContainer getFlowElementsContainer();
diff --git a/org.eclipse.papyrus.bpmn/src/org/eclipse/papyrus/bpmn/BPMNProfile/impl/BPMNProcessImpl.java b/org.eclipse.papyrus.bpmn/src/org/eclipse/papyrus/bpmn/BPMNProfile/impl/BPMNProcessImpl.java
index a9beffc..6f1c27b 100755
--- a/org.eclipse.papyrus.bpmn/src/org/eclipse/papyrus/bpmn/BPMNProfile/impl/BPMNProcessImpl.java
+++ b/org.eclipse.papyrus.bpmn/src/org/eclipse/papyrus/bpmn/BPMNProfile/impl/BPMNProcessImpl.java
@@ -61,16 +61,6 @@
  */
 public class BPMNProcessImpl extends CallableElementImpl implements BPMNProcess {
 	/**
-	 * The cached value of the '{@link #getLaneSets() <em>Lane Sets</em>}' reference list.
-	 * <!-- begin-user-doc -->
-	 * <!-- end-user-doc -->
-	 * @see #getLaneSets()
-	 * @generated
-	 * @ordered
-	 */
-	protected EList<LaneSet> laneSets;
-
-	/**
 	 * The default value of the '{@link #getProcessType() <em>Process Type</em>}' attribute.
 	 * <!-- begin-user-doc -->
 	 * <!-- end-user-doc -->
@@ -222,13 +212,10 @@
 	/**
 	 * <!-- begin-user-doc -->
 	 * <!-- end-user-doc -->
-	 * @generated
+	 * @generated NOT
 	 */
 	public EList<LaneSet> getLaneSets() {
-		if (laneSets == null) {
-			laneSets = new EObjectWithInverseResolvingEList<LaneSet>(LaneSet.class, this, BPMNProfilePackage.BPMN_PROCESS__LANE_SETS, BPMNProfilePackage.LANE_SET__FLOW_ELEMENTS_CONTAINER);
-		}
-		return laneSets;
+		return BPMNProcessCustom.getLaneSets(this);
 	}
 
 	/**
@@ -644,8 +631,6 @@
 	@Override
 	public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
 		switch (featureID) {
-			case BPMNProfilePackage.BPMN_PROCESS__LANE_SETS:
-				return ((InternalEList<InternalEObject>)(InternalEList<?>)getLaneSets()).basicAdd(otherEnd, msgs);
 			case BPMNProfilePackage.BPMN_PROCESS__RESOURCES:
 				return ((InternalEList<InternalEObject>)(InternalEList<?>)getResources()).basicAdd(otherEnd, msgs);
 		}
@@ -660,8 +645,6 @@
 	@Override
 	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
 		switch (featureID) {
-			case BPMNProfilePackage.BPMN_PROCESS__LANE_SETS:
-				return ((InternalEList<?>)getLaneSets()).basicRemove(otherEnd, msgs);
 			case BPMNProfilePackage.BPMN_PROCESS__RESOURCES:
 				return ((InternalEList<?>)getResources()).basicRemove(otherEnd, msgs);
 		}
@@ -720,10 +703,6 @@
 	@Override
 	public void eSet(int featureID, Object newValue) {
 		switch (featureID) {
-			case BPMNProfilePackage.BPMN_PROCESS__LANE_SETS:
-				getLaneSets().clear();
-				getLaneSets().addAll((Collection<? extends LaneSet>)newValue);
-				return;
 			case BPMNProfilePackage.BPMN_PROCESS__PROCESS_TYPE:
 				setProcessType((ProcessType)newValue);
 				return;
@@ -769,9 +748,6 @@
 	@Override
 	public void eUnset(int featureID) {
 		switch (featureID) {
-			case BPMNProfilePackage.BPMN_PROCESS__LANE_SETS:
-				getLaneSets().clear();
-				return;
 			case BPMNProfilePackage.BPMN_PROCESS__PROCESS_TYPE:
 				setProcessType(PROCESS_TYPE_EDEFAULT);
 				return;
@@ -815,7 +791,7 @@
 	public boolean eIsSet(int featureID) {
 		switch (featureID) {
 			case BPMNProfilePackage.BPMN_PROCESS__LANE_SETS:
-				return laneSets != null && !laneSets.isEmpty();
+				return !getLaneSets().isEmpty();
 			case BPMNProfilePackage.BPMN_PROCESS__FLOW_ELEMENTS:
 				return !getFlowElements().isEmpty();
 			case BPMNProfilePackage.BPMN_PROCESS__PROCESS_TYPE:
diff --git a/org.eclipse.papyrus.bpmn/src/org/eclipse/papyrus/bpmn/BPMNProfile/impl/BPMNProfile.ecore b/org.eclipse.papyrus.bpmn/src/org/eclipse/papyrus/bpmn/BPMNProfile/impl/BPMNProfile.ecore
index 5f33452..6e5c2d1 100755
--- a/org.eclipse.papyrus.bpmn/src/org/eclipse/papyrus/bpmn/BPMNProfile/impl/BPMNProfile.ecore
+++ b/org.eclipse.papyrus.bpmn/src/org/eclipse/papyrus/bpmn/BPMNProfile/impl/BPMNProfile.ecore
@@ -137,7 +137,8 @@
   <eClassifiers xsi:type="ecore:EClass" name="FlowElementsContainer" abstract="true"
       eSuperTypes="#//BaseElement">
     <eStructuralFeatures xsi:type="ecore:EReference" name="laneSets" ordered="false"
-        upperBound="-1" eType="#//LaneSet" eOpposite="#//LaneSet/flowElementsContainer"/>
+        upperBound="-1" eType="#//LaneSet" changeable="false" volatile="true" transient="true"
+        derived="true" eOpposite="#//LaneSet/flowElementsContainer"/>
     <eStructuralFeatures xsi:type="ecore:EReference" name="flowElements" ordered="false"
         upperBound="-1" eType="#//FlowElement" changeable="false" volatile="true"
         transient="true" derived="true" eOpposite="#//FlowElement/container"/>
@@ -197,7 +198,8 @@
         upperBound="-1" eType="#//Lane" changeable="false" volatile="true" transient="true"
         derived="true"/>
     <eStructuralFeatures xsi:type="ecore:EReference" name="flowElementsContainer"
-        ordered="false" eType="#//FlowElementsContainer" eOpposite="#//FlowElementsContainer/laneSets"/>
+        ordered="false" eType="#//FlowElementsContainer" volatile="true" transient="true"
+        derived="true" eOpposite="#//FlowElementsContainer/laneSets"/>
   </eClassifiers>
   <eClassifiers xsi:type="ecore:EClass" name="Lane" eSuperTypes="#//BaseElement">
     <eOperations name="LanelaneSet" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean">
diff --git a/org.eclipse.papyrus.bpmn/src/org/eclipse/papyrus/bpmn/BPMNProfile/impl/BPMNProfilePackageImpl.java b/org.eclipse.papyrus.bpmn/src/org/eclipse/papyrus/bpmn/BPMNProfile/impl/BPMNProfilePackageImpl.java
index ab1b69d..f0e3e0d 100755
--- a/org.eclipse.papyrus.bpmn/src/org/eclipse/papyrus/bpmn/BPMNProfile/impl/BPMNProfilePackageImpl.java
+++ b/org.eclipse.papyrus.bpmn/src/org/eclipse/papyrus/bpmn/BPMNProfile/impl/BPMNProfilePackageImpl.java
@@ -15,12 +15,14 @@
 import org.eclipse.emf.ecore.EPackage;
 import org.eclipse.emf.ecore.EReference;
 import org.eclipse.emf.ecore.EValidator;
+import org.eclipse.emf.ecore.EcorePackage;
 import org.eclipse.emf.ecore.impl.EPackageImpl;
 import org.eclipse.emf.ecore.resource.Resource;
 import org.eclipse.emf.ecore.xmi.impl.EcoreResourceFactoryImpl;
 import org.eclipse.papyrus.bpmn.BPMNProfile.BPMNProfileFactory;
 import org.eclipse.papyrus.bpmn.BPMNProfile.BPMNProfilePackage;
 import org.eclipse.papyrus.bpmn.BPMNProfile.util.BPMNProfileValidator;
+import org.eclipse.uml2.types.TypesPackage;
 import org.eclipse.uml2.uml.UMLPackage;
 
 /**
@@ -1048,6 +1050,8 @@
 		isInited = true;
 
 		// Initialize simple dependencies
+		EcorePackage.eINSTANCE.eClass();
+		TypesPackage.eINSTANCE.eClass();
 		UMLPackage.eINSTANCE.eClass();
 
 		// Load packages
diff --git a/org.eclipse.papyrus.bpmn/src/org/eclipse/papyrus/bpmn/BPMNProfile/impl/FlowElementsContainerImpl.java b/org.eclipse.papyrus.bpmn/src/org/eclipse/papyrus/bpmn/BPMNProfile/impl/FlowElementsContainerImpl.java
index e47b653..aa2ff80 100755
--- a/org.eclipse.papyrus.bpmn/src/org/eclipse/papyrus/bpmn/BPMNProfile/impl/FlowElementsContainerImpl.java
+++ b/org.eclipse.papyrus.bpmn/src/org/eclipse/papyrus/bpmn/BPMNProfile/impl/FlowElementsContainerImpl.java
@@ -2,14 +2,8 @@
  */
 package org.eclipse.papyrus.bpmn.BPMNProfile.impl;
 
-import java.util.Collection;
-
-import org.eclipse.emf.common.notify.NotificationChain;
 import org.eclipse.emf.common.util.EList;
 import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.InternalEObject;
-import org.eclipse.emf.ecore.util.EObjectWithInverseResolvingEList;
-import org.eclipse.emf.ecore.util.InternalEList;
 import org.eclipse.papyrus.bpmn.BPMNProfile.BPMNProfilePackage;
 import org.eclipse.papyrus.bpmn.BPMNProfile.FlowElement;
 import org.eclipse.papyrus.bpmn.BPMNProfile.FlowElementsContainer;
@@ -31,15 +25,6 @@
  */
 public abstract class FlowElementsContainerImpl extends BaseElementImpl implements FlowElementsContainer {
 	/**
-	 * The cached value of the '{@link #getLaneSets() <em>Lane Sets</em>}' reference list.
-	 * <!-- begin-user-doc -->
-	 * <!-- end-user-doc -->
-	 * @see #getLaneSets()
-	 * @generated
-	 * @ordered
-	 */
-	protected EList<LaneSet> laneSets;
-	/**
 	 * <!-- begin-user-doc -->
 	 * <!-- end-user-doc -->
 	 * @generated
@@ -64,10 +49,9 @@
 	 * @generated
 	 */
 	public EList<LaneSet> getLaneSets() {
-		if (laneSets == null) {
-			laneSets = new EObjectWithInverseResolvingEList<LaneSet>(LaneSet.class, this, BPMNProfilePackage.FLOW_ELEMENTS_CONTAINER__LANE_SETS, BPMNProfilePackage.LANE_SET__FLOW_ELEMENTS_CONTAINER);
-		}
-		return laneSets;
+		// TODO: implement this method to return the 'Lane Sets' reference list
+		// Ensure that you remove @generated or mark it @generated NOT
+		throw new UnsupportedOperationException();
 	}
 
 	/**
@@ -86,35 +70,6 @@
 	 * <!-- end-user-doc -->
 	 * @generated
 	 */
-	@SuppressWarnings("unchecked")
-	@Override
-	public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
-		switch (featureID) {
-			case BPMNProfilePackage.FLOW_ELEMENTS_CONTAINER__LANE_SETS:
-				return ((InternalEList<InternalEObject>)(InternalEList<?>)getLaneSets()).basicAdd(otherEnd, msgs);
-		}
-		return super.eInverseAdd(otherEnd, featureID, msgs);
-	}
-
-	/**
-	 * <!-- begin-user-doc -->
-	 * <!-- end-user-doc -->
-	 * @generated
-	 */
-	@Override
-	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
-		switch (featureID) {
-			case BPMNProfilePackage.FLOW_ELEMENTS_CONTAINER__LANE_SETS:
-				return ((InternalEList<?>)getLaneSets()).basicRemove(otherEnd, msgs);
-		}
-		return super.eInverseRemove(otherEnd, featureID, msgs);
-	}
-
-	/**
-	 * <!-- begin-user-doc -->
-	 * <!-- end-user-doc -->
-	 * @generated
-	 */
 	@Override
 	public Object eGet(int featureID, boolean resolve, boolean coreType) {
 		switch (featureID) {
@@ -131,43 +86,11 @@
 	 * <!-- end-user-doc -->
 	 * @generated
 	 */
-	@SuppressWarnings("unchecked")
-	@Override
-	public void eSet(int featureID, Object newValue) {
-		switch (featureID) {
-			case BPMNProfilePackage.FLOW_ELEMENTS_CONTAINER__LANE_SETS:
-				getLaneSets().clear();
-				getLaneSets().addAll((Collection<? extends LaneSet>)newValue);
-				return;
-		}
-		super.eSet(featureID, newValue);
-	}
-
-	/**
-	 * <!-- begin-user-doc -->
-	 * <!-- end-user-doc -->
-	 * @generated
-	 */
-	@Override
-	public void eUnset(int featureID) {
-		switch (featureID) {
-			case BPMNProfilePackage.FLOW_ELEMENTS_CONTAINER__LANE_SETS:
-				getLaneSets().clear();
-				return;
-		}
-		super.eUnset(featureID);
-	}
-
-	/**
-	 * <!-- begin-user-doc -->
-	 * <!-- end-user-doc -->
-	 * @generated
-	 */
 	@Override
 	public boolean eIsSet(int featureID) {
 		switch (featureID) {
 			case BPMNProfilePackage.FLOW_ELEMENTS_CONTAINER__LANE_SETS:
-				return laneSets != null && !laneSets.isEmpty();
+				return !getLaneSets().isEmpty();
 			case BPMNProfilePackage.FLOW_ELEMENTS_CONTAINER__FLOW_ELEMENTS:
 				return !getFlowElements().isEmpty();
 		}
diff --git a/org.eclipse.papyrus.bpmn/src/org/eclipse/papyrus/bpmn/BPMNProfile/impl/LaneSetImpl.java b/org.eclipse.papyrus.bpmn/src/org/eclipse/papyrus/bpmn/BPMNProfile/impl/LaneSetImpl.java
index 7a8c61f..275ea5a 100755
--- a/org.eclipse.papyrus.bpmn/src/org/eclipse/papyrus/bpmn/BPMNProfile/impl/LaneSetImpl.java
+++ b/org.eclipse.papyrus.bpmn/src/org/eclipse/papyrus/bpmn/BPMNProfile/impl/LaneSetImpl.java
@@ -6,7 +6,6 @@
 import java.util.Map;
 
 import org.eclipse.emf.common.notify.Notification;
-import org.eclipse.emf.common.notify.NotificationChain;
 import org.eclipse.emf.common.util.BasicDiagnostic;
 import org.eclipse.emf.common.util.Diagnostic;
 import org.eclipse.emf.common.util.DiagnosticChain;
@@ -51,16 +50,6 @@
 	protected ActivityPartition base_ActivityPartition;
 
 	/**
-	 * The cached value of the '{@link #getFlowElementsContainer() <em>Flow Elements Container</em>}' reference.
-	 * <!-- begin-user-doc -->
-	 * <!-- end-user-doc -->
-	 * @see #getFlowElementsContainer()
-	 * @generated
-	 * @ordered
-	 */
-	protected FlowElementsContainer flowElementsContainer;
-
-	/**
 	 * <!-- begin-user-doc -->
 	 * <!-- end-user-doc -->
 	 * @generated
@@ -141,15 +130,8 @@
 	 * @generated
 	 */
 	public FlowElementsContainer getFlowElementsContainer() {
-		if (flowElementsContainer != null && flowElementsContainer.eIsProxy()) {
-			InternalEObject oldFlowElementsContainer = (InternalEObject)flowElementsContainer;
-			flowElementsContainer = (FlowElementsContainer)eResolveProxy(oldFlowElementsContainer);
-			if (flowElementsContainer != oldFlowElementsContainer) {
-				if (eNotificationRequired())
-					eNotify(new ENotificationImpl(this, Notification.RESOLVE, BPMNProfilePackage.LANE_SET__FLOW_ELEMENTS_CONTAINER, oldFlowElementsContainer, flowElementsContainer));
-			}
-		}
-		return flowElementsContainer;
+		FlowElementsContainer flowElementsContainer = basicGetFlowElementsContainer();
+		return flowElementsContainer != null && flowElementsContainer.eIsProxy() ? (FlowElementsContainer)eResolveProxy((InternalEObject)flowElementsContainer) : flowElementsContainer;
 	}
 
 	/**
@@ -158,22 +140,10 @@
 	 * @generated
 	 */
 	public FlowElementsContainer basicGetFlowElementsContainer() {
-		return flowElementsContainer;
-	}
-
-	/**
-	 * <!-- begin-user-doc -->
-	 * <!-- end-user-doc -->
-	 * @generated
-	 */
-	public NotificationChain basicSetFlowElementsContainer(FlowElementsContainer newFlowElementsContainer, NotificationChain msgs) {
-		FlowElementsContainer oldFlowElementsContainer = flowElementsContainer;
-		flowElementsContainer = newFlowElementsContainer;
-		if (eNotificationRequired()) {
-			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, BPMNProfilePackage.LANE_SET__FLOW_ELEMENTS_CONTAINER, oldFlowElementsContainer, newFlowElementsContainer);
-			if (msgs == null) msgs = notification; else msgs.add(notification);
-		}
-		return msgs;
+		// TODO: implement this method to return the 'Flow Elements Container' reference
+		// -> do not perform proxy resolution
+		// Ensure that you remove @generated or mark it @generated NOT
+		throw new UnsupportedOperationException();
 	}
 
 	/**
@@ -182,17 +152,9 @@
 	 * @generated
 	 */
 	public void setFlowElementsContainer(FlowElementsContainer newFlowElementsContainer) {
-		if (newFlowElementsContainer != flowElementsContainer) {
-			NotificationChain msgs = null;
-			if (flowElementsContainer != null)
-				msgs = ((InternalEObject)flowElementsContainer).eInverseRemove(this, BPMNProfilePackage.FLOW_ELEMENTS_CONTAINER__LANE_SETS, FlowElementsContainer.class, msgs);
-			if (newFlowElementsContainer != null)
-				msgs = ((InternalEObject)newFlowElementsContainer).eInverseAdd(this, BPMNProfilePackage.FLOW_ELEMENTS_CONTAINER__LANE_SETS, FlowElementsContainer.class, msgs);
-			msgs = basicSetFlowElementsContainer(newFlowElementsContainer, msgs);
-			if (msgs != null) msgs.dispatch();
-		}
-		else if (eNotificationRequired())
-			eNotify(new ENotificationImpl(this, Notification.SET, BPMNProfilePackage.LANE_SET__FLOW_ELEMENTS_CONTAINER, newFlowElementsContainer, newFlowElementsContainer));
+		// TODO: implement this method to set the 'Flow Elements Container' reference
+		// Ensure that you remove @generated or mark it @generated NOT
+		throw new UnsupportedOperationException();
 	}
 
 	/**
@@ -300,37 +262,6 @@
 	 * <!-- end-user-doc -->
 	 * @generated
 	 */
-	@SuppressWarnings("unchecked")
-	@Override
-	public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
-		switch (featureID) {
-			case BPMNProfilePackage.LANE_SET__FLOW_ELEMENTS_CONTAINER:
-				if (flowElementsContainer != null)
-					msgs = ((InternalEObject)flowElementsContainer).eInverseRemove(this, BPMNProfilePackage.FLOW_ELEMENTS_CONTAINER__LANE_SETS, FlowElementsContainer.class, msgs);
-				return basicSetFlowElementsContainer((FlowElementsContainer)otherEnd, msgs);
-		}
-		return super.eInverseAdd(otherEnd, featureID, msgs);
-	}
-
-	/**
-	 * <!-- begin-user-doc -->
-	 * <!-- end-user-doc -->
-	 * @generated
-	 */
-	@Override
-	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
-		switch (featureID) {
-			case BPMNProfilePackage.LANE_SET__FLOW_ELEMENTS_CONTAINER:
-				return basicSetFlowElementsContainer(null, msgs);
-		}
-		return super.eInverseRemove(otherEnd, featureID, msgs);
-	}
-
-	/**
-	 * <!-- begin-user-doc -->
-	 * <!-- end-user-doc -->
-	 * @generated
-	 */
 	@Override
 	public Object eGet(int featureID, boolean resolve, boolean coreType) {
 		switch (featureID) {
@@ -400,7 +331,7 @@
 			case BPMNProfilePackage.LANE_SET__PARENT_LANE:
 				return !getParentLane().isEmpty();
 			case BPMNProfilePackage.LANE_SET__FLOW_ELEMENTS_CONTAINER:
-				return flowElementsContainer != null;
+				return basicGetFlowElementsContainer() != null;
 		}
 		return super.eIsSet(featureID);
 	}
diff --git a/org.eclipse.papyrus.bpmn/src/org/eclipse/papyrus/bpmn/BPMNProfile/impl/SubProcessImpl.java b/org.eclipse.papyrus.bpmn/src/org/eclipse/papyrus/bpmn/BPMNProfile/impl/SubProcessImpl.java
index fd3b26c..c985abd 100755
--- a/org.eclipse.papyrus.bpmn/src/org/eclipse/papyrus/bpmn/BPMNProfile/impl/SubProcessImpl.java
+++ b/org.eclipse.papyrus.bpmn/src/org/eclipse/papyrus/bpmn/BPMNProfile/impl/SubProcessImpl.java
@@ -7,7 +7,6 @@
 import java.util.Map;
 
 import org.eclipse.emf.common.notify.Notification;
-import org.eclipse.emf.common.notify.NotificationChain;
 import org.eclipse.emf.common.util.BasicDiagnostic;
 import org.eclipse.emf.common.util.Diagnostic;
 import org.eclipse.emf.common.util.DiagnosticChain;
@@ -18,8 +17,6 @@
 import org.eclipse.emf.ecore.plugin.EcorePlugin;
 import org.eclipse.emf.ecore.util.EObjectResolvingEList;
 import org.eclipse.emf.ecore.util.EObjectValidator;
-import org.eclipse.emf.ecore.util.EObjectWithInverseResolvingEList;
-import org.eclipse.emf.ecore.util.InternalEList;
 import org.eclipse.papyrus.bpmn.BPMNProfile.BPMNProfilePackage;
 import org.eclipse.papyrus.bpmn.BPMNProfile.FlowElement;
 import org.eclipse.papyrus.bpmn.BPMNProfile.FlowElementsContainer;
@@ -47,16 +44,6 @@
  */
 public class SubProcessImpl extends BPMNActivityImpl implements SubProcess {
 	/**
-	 * The cached value of the '{@link #getLaneSets() <em>Lane Sets</em>}' reference list.
-	 * <!-- begin-user-doc -->
-	 * <!-- end-user-doc -->
-	 * @see #getLaneSets()
-	 * @generated
-	 * @ordered
-	 */
-	protected EList<LaneSet> laneSets;
-
-	/**
 	 * The default value of the '{@link #isTriggeredByEvent() <em>Triggered By Event</em>}' attribute.
 	 * <!-- begin-user-doc -->
 	 * <!-- end-user-doc -->
@@ -118,24 +105,19 @@
 	/**
 	 * <!-- begin-user-doc -->
 	 * <!-- end-user-doc -->
-	 * @generated
+	 * @generated NOT 
 	 */
 	public EList<LaneSet> getLaneSets() {
-		if (laneSets == null) {
-			laneSets = new EObjectWithInverseResolvingEList<LaneSet>(LaneSet.class, this, BPMNProfilePackage.SUB_PROCESS__LANE_SETS, BPMNProfilePackage.LANE_SET__FLOW_ELEMENTS_CONTAINER);
-		}
-		return laneSets;
+		return getHasLaneSets();
 	}
 
 	/**
 	 * <!-- begin-user-doc -->
 	 * <!-- end-user-doc -->
-	 * @generated
+	 * @generated NOT
 	 */
 	public EList<FlowElement> getFlowElements() {
-		// TODO: implement this method to return the 'Flow Elements' reference list
-		// Ensure that you remove @generated or mark it @generated NOT
-		throw new UnsupportedOperationException();
+		return SubProcessCustom.getFlowElements(this);
 	}
 
 	/**
@@ -239,35 +221,6 @@
 	 * <!-- end-user-doc -->
 	 * @generated
 	 */
-	@SuppressWarnings("unchecked")
-	@Override
-	public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
-		switch (featureID) {
-			case BPMNProfilePackage.SUB_PROCESS__LANE_SETS:
-				return ((InternalEList<InternalEObject>)(InternalEList<?>)getLaneSets()).basicAdd(otherEnd, msgs);
-		}
-		return super.eInverseAdd(otherEnd, featureID, msgs);
-	}
-
-	/**
-	 * <!-- begin-user-doc -->
-	 * <!-- end-user-doc -->
-	 * @generated
-	 */
-	@Override
-	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
-		switch (featureID) {
-			case BPMNProfilePackage.SUB_PROCESS__LANE_SETS:
-				return ((InternalEList<?>)getLaneSets()).basicRemove(otherEnd, msgs);
-		}
-		return super.eInverseRemove(otherEnd, featureID, msgs);
-	}
-
-	/**
-	 * <!-- begin-user-doc -->
-	 * <!-- end-user-doc -->
-	 * @generated
-	 */
 	@Override
 	public Object eGet(int featureID, boolean resolve, boolean coreType) {
 		switch (featureID) {
@@ -295,10 +248,6 @@
 	@Override
 	public void eSet(int featureID, Object newValue) {
 		switch (featureID) {
-			case BPMNProfilePackage.SUB_PROCESS__LANE_SETS:
-				getLaneSets().clear();
-				getLaneSets().addAll((Collection<? extends LaneSet>)newValue);
-				return;
 			case BPMNProfilePackage.SUB_PROCESS__TRIGGERED_BY_EVENT:
 				setTriggeredByEvent((Boolean)newValue);
 				return;
@@ -321,9 +270,6 @@
 	@Override
 	public void eUnset(int featureID) {
 		switch (featureID) {
-			case BPMNProfilePackage.SUB_PROCESS__LANE_SETS:
-				getLaneSets().clear();
-				return;
 			case BPMNProfilePackage.SUB_PROCESS__TRIGGERED_BY_EVENT:
 				setTriggeredByEvent(TRIGGERED_BY_EVENT_EDEFAULT);
 				return;
@@ -346,7 +292,7 @@
 	public boolean eIsSet(int featureID) {
 		switch (featureID) {
 			case BPMNProfilePackage.SUB_PROCESS__LANE_SETS:
-				return laneSets != null && !laneSets.isEmpty();
+				return !getLaneSets().isEmpty();
 			case BPMNProfilePackage.SUB_PROCESS__FLOW_ELEMENTS:
 				return !getFlowElements().isEmpty();
 			case BPMNProfilePackage.SUB_PROCESS__TRIGGERED_BY_EVENT: