Add pullup and pushdown for subprocesses
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..1d92979 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
@@ -886,6 +886,11 @@
 
 	@SuppressWarnings("unchecked")
 	public <T> List<T> getAll(final Class<T> class1) {
+		return getAll(this.resource, class1);
+	}
+
+	@SuppressWarnings("unchecked")
+	public static <T> List<T> getAll(Resource resource, final Class<T> class1) {
 		ArrayList<T> l = new ArrayList<T>();
 		TreeIterator<EObject> contents = resource.getAllContents();
 		for (; contents.hasNext();) {
@@ -897,12 +902,12 @@
 		return l;
 	}
 
-	public DiagramElement findDIElement(BaseElement element) {
+	public static DiagramElement findDIElement(BaseElement element) {
 		String id = element.getId();
 		if (id==null || id.isEmpty())
 			return null;
 
-		List<BPMNDiagram> diagrams = getAll(BPMNDiagram.class);
+		List<BPMNDiagram> diagrams = getAll(element.eResource(), BPMNDiagram.class);
 		for (BPMNDiagram d : diagrams) {
 			// Process elements correspond to BPMNPlane DI elements
 			BPMNPlane plane = d.getPlane();
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 230ab0c..13824a6 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
@@ -13,6 +13,7 @@
 package org.eclipse.bpmn2.modeler.core.di;
 
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.List;
 
 import org.eclipse.bpmn2.BaseElement;
@@ -47,6 +48,9 @@
 import org.eclipse.graphiti.dt.IDiagramTypeProvider;
 import org.eclipse.graphiti.features.IFeatureProvider;
 import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm;
+import org.eclipse.graphiti.mm.algorithms.styles.Color;
+import org.eclipse.graphiti.mm.algorithms.styles.Font;
+import org.eclipse.graphiti.mm.algorithms.styles.Style;
 import org.eclipse.graphiti.mm.pictograms.Anchor;
 import org.eclipse.graphiti.mm.pictograms.Connection;
 import org.eclipse.graphiti.mm.pictograms.ContainerShape;
@@ -281,11 +285,31 @@
 	public static void deleteDiagram(final IDiagramEditor editor, final BPMNDiagram bpmnDiagram) {
 		Diagram diagram = DIUtils.findDiagram(editor, bpmnDiagram);
 		if (diagram!=null) {
-			int n = diagram.getPictogramLinks().size();
-			for (int i=n-1; i>=0; --i) {
-				PictogramLink link = diagram.getPictogramLinks().remove(i);
-				EcoreUtil.delete(link);
+			List<EObject> list = new ArrayList<EObject>();
+			TreeIterator<EObject> iter = diagram.eAllContents();
+			while (iter.hasNext()) {
+				EObject o = iter.next();
+				if (o instanceof PictogramLink) {
+					((PictogramLink)o).getBusinessObjects().clear();
+					if (!list.contains(o))
+						list.add(o);
+				}
+				else if (o instanceof Color) {
+					if (!list.contains(o))
+						list.add(o);
+				}
+				else if (o instanceof Font) {
+					if (!list.contains(o))
+						list.add(o);
+				}
+				else if (o instanceof Style) {
+					if (!list.contains(o))
+						list.add(o);
+				}
 			}
+			for (EObject o : list)
+				EcoreUtil.delete(o);
+			
 			EcoreUtil.delete(diagram);
 			EcoreUtil.delete(bpmnDiagram);
 		}	
@@ -315,5 +339,24 @@
 		}
 		return null;
 	}
+	
+	public static BPMNDiagram createBPMNDiagram(Definitions definitions, BaseElement container) {
+		
+		Resource resource = definitions.eResource();
+        BPMNDiagram bpmnDiagram = BpmnDiFactory.eINSTANCE.createBPMNDiagram();
+		ModelUtil.setID(bpmnDiagram, resource);
+        bpmnDiagram.setName(ModelUtil.getDisplayName(container));
 
+		BPMNPlane plane = BpmnDiFactory.eINSTANCE.createBPMNPlane();
+		ModelUtil.setID(plane, resource);
+		plane.setBpmnElement(container);
+		
+		bpmnDiagram.setPlane(plane);
+		
+		// this has to happen last because the IResourceChangeListener in the DesignEditor
+		// looks for add/remove to Definitions.diagrams
+        definitions.getDiagrams().add(bpmnDiagram);
+
+		return bpmnDiagram;
+	}
 }
\ No newline at end of file
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/utils/GraphicsUtil.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/utils/GraphicsUtil.java
index b1339f8..8634ef8 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/utils/GraphicsUtil.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/utils/GraphicsUtil.java
@@ -1169,4 +1169,8 @@
 		}
 		return true;
 	}
+	
+	public static Color clone(Color c) {
+		return c;
+	}
 }
\ No newline at end of file
diff --git a/org.eclipse.bpmn2.modeler.ui/icons/16/pullup.png b/org.eclipse.bpmn2.modeler.ui/icons/16/pullup.png
new file mode 100644
index 0000000..c6ef26e
--- /dev/null
+++ b/org.eclipse.bpmn2.modeler.ui/icons/16/pullup.png
Binary files differ
diff --git a/org.eclipse.bpmn2.modeler.ui/icons/16/pushdown.png b/org.eclipse.bpmn2.modeler.ui/icons/16/pushdown.png
new file mode 100644
index 0000000..de94fa0
--- /dev/null
+++ b/org.eclipse.bpmn2.modeler.ui/icons/16/pushdown.png
Binary files differ
diff --git a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/ImageProvider.java b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/ImageProvider.java
index 6be2187..049657c 100644
--- a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/ImageProvider.java
+++ b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/ImageProvider.java
@@ -152,6 +152,8 @@
 	public static final String IMG_16_ROTATE = PREFIX + "rotate" + dot16;
 	public static final String IMG_16_WHITEBOX = PREFIX + "whitebox" + dot16;
 	public static final String IMG_16_BLACKBOX = PREFIX + "blackbox" + dot16;
+	public static final String IMG_16_PUSHDOWN = PREFIX + "pushdown" + dot16;
+	public static final String IMG_16_PULLUP = PREFIX + "pullup" + dot16;
 
 	public final String IMG_16_PROPERTIES = "org.eclipse.bpmn2.modeler.icons." + "properties" + dot16; //$NON-NLS-1$
 
@@ -220,6 +222,8 @@
 
 		addImageFilePath(IMG_16_WHITEBOX, ICONS_16 + "whitebox.png");
 		addImageFilePath(IMG_16_BLACKBOX, ICONS_16 + "blackbox.png");
+		addImageFilePath(IMG_16_PUSHDOWN, ICONS_16 + "pushdown.png");
+		addImageFilePath(IMG_16_PULLUP, ICONS_16 + "pullup.png");
 	}
 
 }
diff --git a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/activity/subprocess/AbstractExpandableActivityFeatureContainer.java b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/activity/subprocess/AbstractExpandableActivityFeatureContainer.java
index 9055bbe..8adef34 100644
--- a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/activity/subprocess/AbstractExpandableActivityFeatureContainer.java
+++ b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/activity/subprocess/AbstractExpandableActivityFeatureContainer.java
@@ -15,6 +15,7 @@
 import org.eclipse.bpmn2.BaseElement;
 import org.eclipse.bpmn2.CallActivity;
 import org.eclipse.bpmn2.CallChoreography;
+import org.eclipse.bpmn2.FlowElementsContainer;
 import org.eclipse.bpmn2.SubChoreography;
 import org.eclipse.bpmn2.SubProcess;
 import org.eclipse.bpmn2.modeler.core.features.AbstractUpdateBaseElementFeature;
@@ -61,18 +62,19 @@
 	@Override
 	public ICustomFeature[] getCustomFeatures(IFeatureProvider fp) {
 		ICustomFeature[] superFeatures = super.getCustomFeatures(fp);
-		ICustomFeature[] thisFeatures = new ICustomFeature[2 + superFeatures.length];
+		ICustomFeature[] thisFeatures = new ICustomFeature[4 + superFeatures.length];
 		thisFeatures[0] = new ExpandFlowNodeFeature(fp);
 		thisFeatures[1] = new CollapseFlowNodeFeature(fp);
+		thisFeatures[2] = new PushdownFeature(fp);
+		thisFeatures[3] = new PullupFeature(fp);
 		for (int i=0; i<superFeatures.length; ++i)
-			thisFeatures[2+i] = superFeatures[i];
+			thisFeatures[4+i] = superFeatures[i];
 		return thisFeatures;
 	}
 	
 	public static boolean isExpandableElement(Object be) {
-		return be instanceof SubProcess
+		return be instanceof FlowElementsContainer
 				|| be instanceof CallActivity
-				|| be instanceof SubChoreography
 				|| be instanceof CallChoreography;
 	}
 }
\ No newline at end of file
diff --git a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/activity/subprocess/PullupFeature.java b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/activity/subprocess/PullupFeature.java
new file mode 100644
index 0000000..1365bfb
--- /dev/null
+++ b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/activity/subprocess/PullupFeature.java
@@ -0,0 +1,188 @@
+/*******************************************************************************
+ * 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.features.activity.subprocess;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.bpmn2.BaseElement;
+import org.eclipse.bpmn2.Bpmn2Package;
+import org.eclipse.bpmn2.Choreography;
+import org.eclipse.bpmn2.ChoreographyTask;
+import org.eclipse.bpmn2.Collaboration;
+import org.eclipse.bpmn2.Definitions;
+import org.eclipse.bpmn2.FlowElement;
+import org.eclipse.bpmn2.FlowElementsContainer;
+import org.eclipse.bpmn2.Message;
+import org.eclipse.bpmn2.MessageFlow;
+import org.eclipse.bpmn2.Participant;
+import org.eclipse.bpmn2.Process;
+import org.eclipse.bpmn2.RootElement;
+import org.eclipse.bpmn2.SubProcess;
+import org.eclipse.bpmn2.di.BPMNDiagram;
+import org.eclipse.bpmn2.di.BPMNEdge;
+import org.eclipse.bpmn2.di.BPMNLabel;
+import org.eclipse.bpmn2.di.BPMNPlane;
+import org.eclipse.bpmn2.di.BPMNShape;
+import org.eclipse.bpmn2.di.BpmnDiFactory;
+import org.eclipse.bpmn2.modeler.core.ModelHandler;
+import org.eclipse.bpmn2.modeler.core.ModelHandlerLocator;
+import org.eclipse.bpmn2.modeler.core.di.DIUtils;
+import org.eclipse.bpmn2.modeler.core.utils.BusinessObjectUtil;
+import org.eclipse.bpmn2.modeler.core.utils.ModelUtil;
+import org.eclipse.bpmn2.modeler.ui.Activator;
+import org.eclipse.bpmn2.modeler.ui.ImageProvider;
+import org.eclipse.dd.di.DiagramElement;
+import org.eclipse.emf.common.util.TreeIterator;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.graphiti.features.IFeatureProvider;
+import org.eclipse.graphiti.features.context.IContext;
+import org.eclipse.graphiti.features.context.ICustomContext;
+import org.eclipse.graphiti.features.custom.AbstractCustomFeature;
+import org.eclipse.graphiti.mm.algorithms.styles.Color;
+import org.eclipse.graphiti.mm.algorithms.styles.Font;
+import org.eclipse.graphiti.mm.algorithms.styles.Style;
+import org.eclipse.graphiti.mm.pictograms.Connection;
+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.PictogramLink;
+import org.eclipse.graphiti.mm.pictograms.Shape;
+import org.eclipse.graphiti.services.Graphiti;
+import org.eclipse.graphiti.ui.editor.DiagramEditor;
+import org.eclipse.graphiti.ui.internal.util.ui.PopupMenu;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * @author Bob Brodt
+ *
+ */
+public class PullupFeature extends AbstractCustomFeature {
+
+	/**
+	 * @param fp
+	 */
+	public PullupFeature(IFeatureProvider fp) {
+		super(fp);
+	}
+	
+	@Override
+	public String getName() {
+	    return "Pull up";
+	}
+	
+	@Override
+	public String getDescription() {
+	    return "Pull the contents of the Diagram for this Activity Container back into the container";
+	}
+
+	@Override
+	public String getImageId() {
+		return ImageProvider.IMG_16_PULLUP;
+	}
+
+	@Override
+	public boolean isAvailable(IContext context) {
+		return true;
+	}
+
+	@Override
+	public boolean canExecute(ICustomContext context) {
+		PictogramElement[] pes = context.getPictogramElements();
+		if (pes != null && pes.length == 1) {
+			PictogramElement pe = pes[0];
+			Object bo = getBusinessObjectForPictogramElement(pe);
+			if (bo instanceof FlowElementsContainer) {
+				return DIUtils.findBPMNDiagram(getDiagramEditor(), (BaseElement)bo) != null;
+			}
+		}
+		return false;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.graphiti.features.custom.ICustomFeature#execute(org.eclipse.graphiti.features.context.ICustomContext)
+	 */
+	@Override
+	public void execute(ICustomContext context) {
+		// we already know there's one and only one PE element in canExecute() and that it's
+		// a ContainerShape for an expandable activity
+		PictogramElement pe = context.getPictogramElements()[0];
+		FlowElementsContainer container = (FlowElementsContainer)getBusinessObjectForPictogramElement(pe);
+		Definitions definitions = ModelUtil.getDefinitions(container);
+		
+		// find out which BPMNPlane this sub process lives in - this will be the new home
+		// for the DI elements in the existing BPMNDiagram.
+		BPMNDiagram newBpmnDiagram = (BPMNDiagram)ModelHandler.findDIElement(container).eContainer().eContainer();
+		BPMNPlane newPlane = newBpmnDiagram.getPlane();
+		Diagram newDiagram = DIUtils.findDiagram(getDiagramEditor(), newBpmnDiagram);
+		
+		BPMNDiagram oldBpmnDiagram = DIUtils.findBPMNDiagram(getDiagramEditor(), container);
+		BPMNPlane oldPlane = oldBpmnDiagram.getPlane();
+		Diagram oldDiagram = DIUtils.findDiagram(getDiagramEditor(), oldBpmnDiagram);
+		
+		// copy the elements into the same plane as the sub process
+		while (oldPlane.getPlaneElement().size()>0) {
+			DiagramElement de = oldPlane.getPlaneElement().get(0);
+			newPlane.getPlaneElement().add(de);
+		}
+		
+		// copy the Graphiti diagram elements: first find the ContainerShape for the sub process
+		List <PictogramElement> pes = Graphiti.getLinkService().getPictogramElements(newDiagram, container);
+		for (PictogramElement p : pes) {
+			if (p instanceof ContainerShape) {
+				if (BusinessObjectUtil.getFirstElementOfType(p, BPMNShape.class)!=null) {
+					// this is it!
+					List <EObject> moved = new ArrayList<EObject>();
+					for (Shape shape : oldDiagram.getChildren()) {
+						TreeIterator<EObject> iter = shape.eAllContents();
+						while (iter.hasNext()) {
+							EObject o = iter.next();
+							if (o instanceof PictogramLink || o instanceof Color || o instanceof Font || o instanceof Style)
+								moved.add(o);
+						}
+					}
+					for (Connection connection : oldDiagram.getConnections()) {
+						TreeIterator<EObject> iter = connection.eAllContents();
+						while (iter.hasNext()) {
+							EObject o = iter.next();
+							if (o instanceof PictogramLink || o instanceof Color || o instanceof Font || o instanceof Style)
+								moved.add(o);
+						}
+					}
+					((ContainerShape)p).getChildren().addAll( oldDiagram.getChildren() );
+					newDiagram.getConnections().addAll( oldDiagram.getConnections() );
+					
+					oldDiagram.getPictogramLinks().removeAll(moved);
+					oldDiagram.getColors().removeAll(moved);
+					oldDiagram.getFonts().removeAll(moved);
+					oldDiagram.getStyles().removeAll(moved);
+					
+					break;
+				}
+			}
+		}
+		
+		// get rid of the old BPMNDiagram
+		DIUtils.deleteDiagram(getDiagramEditor(), oldBpmnDiagram);
+		
+		// now expand the sub process
+		ExpandFlowNodeFeature expandFeature = new ExpandFlowNodeFeature(getFeatureProvider());
+		expandFeature.execute(context);
+	}
+}
diff --git a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/activity/subprocess/PushdownFeature.java b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/activity/subprocess/PushdownFeature.java
new file mode 100644
index 0000000..201cf6c
--- /dev/null
+++ b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/activity/subprocess/PushdownFeature.java
@@ -0,0 +1,188 @@
+/*******************************************************************************
+ * 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.features.activity.subprocess;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.bpmn2.BaseElement;
+import org.eclipse.bpmn2.Bpmn2Package;
+import org.eclipse.bpmn2.CallActivity;
+import org.eclipse.bpmn2.CallChoreography;
+import org.eclipse.bpmn2.CallableElement;
+import org.eclipse.bpmn2.Choreography;
+import org.eclipse.bpmn2.ChoreographyTask;
+import org.eclipse.bpmn2.Collaboration;
+import org.eclipse.bpmn2.Definitions;
+import org.eclipse.bpmn2.FlowElement;
+import org.eclipse.bpmn2.FlowElementsContainer;
+import org.eclipse.bpmn2.Message;
+import org.eclipse.bpmn2.MessageFlow;
+import org.eclipse.bpmn2.Participant;
+import org.eclipse.bpmn2.Process;
+import org.eclipse.bpmn2.RootElement;
+import org.eclipse.bpmn2.SubProcess;
+import org.eclipse.bpmn2.di.BPMNDiagram;
+import org.eclipse.bpmn2.di.BPMNEdge;
+import org.eclipse.bpmn2.di.BPMNPlane;
+import org.eclipse.bpmn2.di.BPMNShape;
+import org.eclipse.bpmn2.di.BpmnDiFactory;
+import org.eclipse.bpmn2.modeler.core.ModelHandler;
+import org.eclipse.bpmn2.modeler.core.ModelHandlerLocator;
+import org.eclipse.bpmn2.modeler.core.di.DIUtils;
+import org.eclipse.bpmn2.modeler.core.merrimac.dialogs.ModelSubclassSelectionDialog;
+import org.eclipse.bpmn2.modeler.core.utils.BusinessObjectUtil;
+import org.eclipse.bpmn2.modeler.core.utils.GraphicsUtil;
+import org.eclipse.bpmn2.modeler.core.utils.ModelUtil;
+import org.eclipse.bpmn2.modeler.ui.Activator;
+import org.eclipse.bpmn2.modeler.ui.ImageProvider;
+import org.eclipse.dd.di.DiagramElement;
+import org.eclipse.emf.common.util.TreeIterator;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.graphiti.features.IFeatureProvider;
+import org.eclipse.graphiti.features.context.IContext;
+import org.eclipse.graphiti.features.context.ICustomContext;
+import org.eclipse.graphiti.features.custom.AbstractCustomFeature;
+import org.eclipse.graphiti.mm.algorithms.styles.Color;
+import org.eclipse.graphiti.mm.algorithms.styles.Font;
+import org.eclipse.graphiti.mm.algorithms.styles.Style;
+import org.eclipse.graphiti.mm.pictograms.Connection;
+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.PictogramLink;
+import org.eclipse.graphiti.mm.pictograms.Shape;
+import org.eclipse.graphiti.services.Graphiti;
+import org.eclipse.graphiti.ui.editor.DiagramEditor;
+import org.eclipse.graphiti.ui.internal.util.ui.PopupMenu;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * @author Bob Brodt
+ *
+ */
+public class PushdownFeature extends AbstractCustomFeature {
+
+	/**
+	 * @param fp
+	 */
+	public PushdownFeature(IFeatureProvider fp) {
+		super(fp);
+	}
+	
+	@Override
+	public String getName() {
+	    return "Push down";
+	}
+	
+	@Override
+	public String getDescription() {
+	    return "Push the contents of this Activity Container into a new Diagram";
+	}
+
+	@Override
+	public String getImageId() {
+		return ImageProvider.IMG_16_PUSHDOWN;
+	}
+
+	@Override
+	public boolean isAvailable(IContext context) {
+		return true;
+	}
+
+	@Override
+	public boolean canExecute(ICustomContext context) {
+		PictogramElement[] pes = context.getPictogramElements();
+		if (pes != null && pes.length == 1) {
+			PictogramElement pe = pes[0];
+			Object bo = getBusinessObjectForPictogramElement(pe);
+			if (bo instanceof FlowElementsContainer) {
+				return DIUtils.findBPMNDiagram(getDiagramEditor(), (BaseElement)bo) == null;
+			}
+		}
+		return false;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.graphiti.features.custom.ICustomFeature#execute(org.eclipse.graphiti.features.context.ICustomContext)
+	 */
+	@Override
+	public void execute(ICustomContext context) {
+		// we already know there's one and only one PE element in canExecute() and that it's
+		// a ContainerShape for an expandable activity
+		PictogramElement pe = context.getPictogramElements()[0];
+		FlowElementsContainer container = (FlowElementsContainer)getBusinessObjectForPictogramElement(pe);
+		Definitions definitions = ModelUtil.getDefinitions(container);
+
+		BPMNDiagram oldBpmnDiagram = (BPMNDiagram)ModelHandler.findDIElement(container).eContainer().eContainer();
+		Diagram oldDiagram = DIUtils.findDiagram(getDiagramEditor(), oldBpmnDiagram);
+		
+		// the contents of this expandable element is in the flowElements list 
+        BPMNDiagram newBpmnDiagram = DIUtils.createBPMNDiagram(definitions, container);
+		BPMNPlane newPlane = newBpmnDiagram.getPlane();
+
+		Diagram newDiagram = DIUtils.getOrCreateDiagram(getDiagramEditor(), newBpmnDiagram);
+		
+		for (FlowElement fe : container.getFlowElements()) {
+			DiagramElement de = ModelHandler.findDIElement(fe);
+			newPlane.getPlaneElement().add(de);
+			
+			List <PictogramElement> pes = Graphiti.getLinkService().getPictogramElements(oldDiagram, fe);
+			List <EObject> moved = new ArrayList<EObject>();
+			for (PictogramElement p : pes) {
+				PictogramElement pictogramElement = null;
+				if (p instanceof Shape) {
+					if (BusinessObjectUtil.getFirstElementOfType(p, BPMNShape.class)!=null) {
+						newDiagram.getChildren().add((Shape)p);
+						pictogramElement = p;
+					}
+					else if (Graphiti.getPeService().getPropertyValue(p, GraphicsUtil.LABEL_PROPERTY) != null) {
+						newDiagram.getChildren().add((Shape)p);
+						pictogramElement = p;
+					}
+				}
+				else if (p instanceof Connection) {
+					if (BusinessObjectUtil.getFirstElementOfType(p, BPMNEdge.class)!=null) {
+						newDiagram.getConnections().add((Connection)p);
+						pictogramElement = p;
+					}
+				}
+				if (pictogramElement!=null) {
+					TreeIterator<EObject> iter = pictogramElement.eAllContents();
+					while (iter.hasNext()) {
+						EObject o = iter.next();
+						if (o instanceof PictogramLink || o instanceof Color || o instanceof Font || o instanceof Style)
+							moved.add(o);
+					}
+				}
+			}
+			oldDiagram.getPictogramLinks().removeAll(moved);
+			oldDiagram.getColors().removeAll(moved);
+			oldDiagram.getFonts().removeAll(moved);
+			oldDiagram.getStyles().removeAll(moved);
+		}
+
+		// now collapse the sub process
+		CollapseFlowNodeFeature collapseFeature = new CollapseFlowNodeFeature(getFeatureProvider());
+		collapseFeature.execute(context);
+	}
+}
diff --git a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/choreography/WhiteboxFeature.java b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/choreography/WhiteboxFeature.java
index d06ce7f..b60dc8f 100644
--- a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/choreography/WhiteboxFeature.java
+++ b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/choreography/WhiteboxFeature.java
@@ -18,6 +18,8 @@
 import java.util.List;
 
 import org.eclipse.bpmn2.Bpmn2Package;
+import org.eclipse.bpmn2.CallActivity;
+import org.eclipse.bpmn2.CallableElement;
 import org.eclipse.bpmn2.Choreography;
 import org.eclipse.bpmn2.ChoreographyTask;
 import org.eclipse.bpmn2.Collaboration;
@@ -32,6 +34,7 @@
 import org.eclipse.bpmn2.di.BpmnDiFactory;
 import org.eclipse.bpmn2.modeler.core.ModelHandler;
 import org.eclipse.bpmn2.modeler.core.ModelHandlerLocator;
+import org.eclipse.bpmn2.modeler.core.di.DIUtils;
 import org.eclipse.bpmn2.modeler.core.utils.ModelUtil;
 import org.eclipse.bpmn2.modeler.ui.Activator;
 import org.eclipse.bpmn2.modeler.ui.ImageProvider;
@@ -69,7 +72,7 @@
 	
 	@Override
 	public String getDescription() {
-	    return "Create a new Diagram for this Participant";
+	    return "Create a new Diagram for this Participant or CallActivity";
 	}
 
 	@Override
@@ -87,21 +90,27 @@
 		PictogramElement[] pes = context.getPictogramElements();
 		if (pes != null && pes.length == 1) {
 			PictogramElement pe = pes[0];
+			Process process = null;
 			Object bo = getBusinessObjectForPictogramElement(pe);
 			if (bo instanceof Participant) {
-				Participant participant = (Participant)bo;
-				Process process = participant.getProcessRef();
-				if (process!=null) {
-					try {
-						ModelHandler mh = ModelHandlerLocator.getModelHandler(participant.eResource());
-						DiagramElement de = mh.findDIElement(process);
-						return de==null;
-					}
-					catch (Exception e){
-					}
-				}
-				return true;
+				process = ((Participant)bo).getProcessRef();
 			}
+			else if (bo instanceof CallActivity) {
+				CallableElement ce = ((CallActivity)bo).getCalledElementRef();
+				if (ce instanceof Process)
+					process = (Process)ce;
+			}
+			
+			if (process!=null) {
+				try {
+					ModelHandler mh = ModelHandlerLocator.getModelHandler(process.eResource());
+					DiagramElement de = mh.findDIElement(process);
+					return de==null;
+				}
+				catch (Exception e){
+				}
+			}
+			return true;
 		}
 		return false;
 	}
@@ -111,50 +120,36 @@
 	 */
 	@Override
 	public void execute(ICustomContext context) {
-		PictogramElement[] pes = context.getPictogramElements();
-		if (pes != null && pes.length == 1) {
-			PictogramElement pe = pes[0];
-			Object bo = getBusinessObjectForPictogramElement(pe);
-			if (bo instanceof Participant) {
-				Participant participant = (Participant)bo;
-				Definitions definitions = ModelUtil.getDefinitions(participant);
-				Resource resource = definitions.eResource();
-				Process process = participant.getProcessRef();
+		PictogramElement pe = context.getPictogramElements()[0];
+		Object bo = getBusinessObjectForPictogramElement(pe);
+		if (bo instanceof Participant) {
+			Participant participant = (Participant)bo;
+			Definitions definitions = ModelUtil.getDefinitions(participant);
+			Resource resource = definitions.eResource();
+			Process process = participant.getProcessRef();
 
-				if (process==null) {
-			        // create a Process for this Participant
-			        process = (Process) ModelUtil.createObject(resource, Bpmn2Package.eINSTANCE.getProcess());
-			        participant.setProcessRef(process);
-			        
-			        // NOTE: this is needed because it fires the InsertionAdapter, which adds the new Process
-			        // to Definitions.rootElements, otherwise the Process would be a dangling object
-			        process.setName("Process for "+participant.getName());
-				}
-				
-		        // add the Participant to the first Choreography or Collaboration we find.
-		        // TODO: when (and if) multipage editor allows additional Choreography or
-		        // Collaboration diagrams to be created, this will be the specific diagram
-		        // that is being rendered on the current page.
-		        List<RootElement> rootElements = definitions.getRootElements();
-		        for (RootElement element : rootElements) {
-		            if (element instanceof Collaboration || element instanceof Choreography) {
-		            	((Collaboration)element).getParticipants().add(participant);
-		                break;
-		            }
-		        }
-				
-		        BPMNDiagram bpmnDiagram = BpmnDiFactory.eINSTANCE.createBPMNDiagram();
-				ModelUtil.setID(bpmnDiagram, resource);
-		        bpmnDiagram.setName(process.getName());
-
-		        definitions.getDiagrams().add(bpmnDiagram);
+			if (process==null) {
+		        // create a Process for this Participant
+		        process = (Process) ModelUtil.createObject(resource, Bpmn2Package.eINSTANCE.getProcess());
+		        participant.setProcessRef(process);
 		        
-				BPMNPlane plane = BpmnDiFactory.eINSTANCE.createBPMNPlane();
-				ModelUtil.setID(plane, resource);
-				plane.setBpmnElement(process);
-
-				bpmnDiagram.setPlane(plane);
+		        // NOTE: this is needed because it fires the InsertionAdapter, which adds the new Process
+		        // to Definitions.rootElements, otherwise the Process would be a dangling object
+		        process.setName("Process for "+participant.getName());
 			}
+			
+	        // add the Participant to the first Choreography or Collaboration we find.
+	        // TODO: when (and if) multipage editor allows additional Choreography or
+	        // Collaboration diagrams to be created, this will be the specific diagram
+	        // that is being rendered on the current page.
+	        List<RootElement> rootElements = definitions.getRootElements();
+	        for (RootElement element : rootElements) {
+	            if (element instanceof Collaboration || element instanceof Choreography) {
+	            	((Collaboration)element).getParticipants().add(participant);
+	                break;
+	            }
+	        }
+			DIUtils.createBPMNDiagram(definitions, process);
 		}
 	}
 }