[512862] Introduce contextual actions to setup CDO in the genmodel

Bug: 512862
Change-Id: If75f395243a68dcf898454c478fa86991119e4c5
diff --git a/org.eclipse.emf.ecoretools.design.ui/plugin.xml b/org.eclipse.emf.ecoretools.design.ui/plugin.xml
index f4407ce..a5fecf6 100644
--- a/org.eclipse.emf.ecoretools.design.ui/plugin.xml
+++ b/org.eclipse.emf.ecoretools.design.ui/plugin.xml
@@ -36,6 +36,10 @@
             actionClass="org.eclipse.emf.ecoretools.design.ui.action.GenerateAllAction"
             id="org.eclipse.emf.ecoretools.design.action.generateAllID">
       </javaActions>
+      <javaActions
+            actionClass="org.eclipse.emf.ecoretools.design.ui.action.OpenConfirmationDialogAction"
+            id="org.eclipse.emf.ecoretools.design.action.openConfirmationDialogID">
+      </javaActions>
    </extension>
    <!--
    <extension
diff --git a/org.eclipse.emf.ecoretools.design.ui/src/org/eclipse/emf/ecoretools/design/ui/action/OpenConfirmationDialogAction.java b/org.eclipse.emf.ecoretools.design.ui/src/org/eclipse/emf/ecoretools/design/ui/action/OpenConfirmationDialogAction.java
new file mode 100644
index 0000000..ffd76e0
--- /dev/null
+++ b/org.eclipse.emf.ecoretools.design.ui/src/org/eclipse/emf/ecoretools/design/ui/action/OpenConfirmationDialogAction.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Obeo.
+ * 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:
+ *     Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.ecoretools.design.ui.action;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.sirius.tools.api.ui.IExternalJavaAction;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.PlatformUI;
+
+public class OpenConfirmationDialogAction implements IExternalJavaAction {
+
+	public boolean canExecute(Collection<? extends EObject> selections) {
+		return true;
+	}
+
+	public void execute(Collection<? extends EObject> selections, Map<String, Object> parameters) {
+		Object messageObj = parameters.get("message");
+		Object titleObj = parameters.get("title");
+		if (messageObj instanceof String) {
+			final String message = (String) messageObj;
+			final String title = getTitleFromParameter(titleObj);
+			Display.getDefault().syncExec(new Runnable() {
+
+				public void run() {
+					IEditorPart activeEditorPart = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage()
+							.getActiveEditor();
+
+					if (!MessageDialog.openConfirm(activeEditorPart.getSite().getShell(), title, message)) {
+
+						throw new OperationCanceledException("user canceled");
+					}
+
+				}
+			});
+
+		}
+
+	}
+
+	private String getTitleFromParameter(Object titleObj) {
+		String title = "Confirmation ?";
+		if (titleObj instanceof String) {
+			title = (String) titleObj;
+		}
+		return title;
+	}
+
+}
diff --git a/org.eclipse.emf.ecoretools.design/description/ecore.odesign b/org.eclipse.emf.ecoretools.design/description/ecore.odesign
index e84f8b3..880541a 100644
--- a/org.eclipse.emf.ecoretools.design/description/ecore.odesign
+++ b/org.eclipse.emf.ecoretools.design/description/ecore.odesign
@@ -240,6 +240,28 @@
               </initialOperation>
             </menuItemDescription>
           </ownedTools>
+          <ownedTools xsi:type="tool:PopupMenu" name="CDO Native" precondition="aql:self.hasCDOBundle()">
+            <menuItemDescription xsi:type="tool:OperationAction" name="Enable support" precondition="aql:OrderedSet{views.target}.eInverse().eContainerOrSelf(genmodel::GenModel)->asSet()->size() > 0">
+              <view name="views"/>
+              <initialOperation>
+                <firstModelOperations xsi:type="tool:ExternalJavaAction" name="OpenConfirmationDialog" id="org.eclipse.emf.ecoretools.design.action.openConfirmationDialogID">
+                  <subModelOperations xsi:type="tool:ChangeContext" browseExpression="aql:self.enableCDOGen(OrderedSet{views->filter(viewpoint::DSemanticDecorator).target}.eInverse().eContainerOrSelf(genmodel::GenModel)->asSet())"/>
+                  <parameters name="message" value="The selected generator model will be updated:&#xA;&#xA;Set Feature Delegation = Reflective&#xA;Set Root Extends Class = org.eclipse.emf.internal.cdo.CDOObjectImpl&#xA;Set Root Extends Interface = org.eclipse.emf.cdo.CDOObject&#xA;Added Model Plugin Variables = CDO=org.eclipse.emf.cdo &#xA;Created CDO.MF marker file&#xA;&#xA;You need to regenerate the code to make these changes effective. &#xA;"/>
+                  <parameters name="title" value="The selected generator model will be updated:&#xA;&#xA;Set Feature Delegation = Reflective&#xA;Set Root Extends Class = org.eclipse.emf.internal.cdo.CDOObjectImpl&#xA;Set Root Extends Interface = org.eclipse.emf.cdo.CDOObject&#xA;Add Model Plugin Variables = CDO=org.eclipse.emf.cdo &#xA;Create CDO.MF marker file&#xA;&#xA;You need to regenerate the code to make these changes effective. "/>
+                </firstModelOperations>
+              </initialOperation>
+            </menuItemDescription>
+            <menuItemDescription xsi:type="tool:OperationAction" name="Disable support" precondition="aql:OrderedSet{views.target}.eInverse().eContainerOrSelf(genmodel::GenModel)->asSet()->size() > 0">
+              <view name="views"/>
+              <initialOperation>
+                <firstModelOperations xsi:type="tool:ExternalJavaAction" name="OpenConfirmationDialog" id="org.eclipse.emf.ecoretools.design.action.openConfirmationDialogID">
+                  <subModelOperations xsi:type="tool:ChangeContext" browseExpression="aql:self.disableCDOGen(OrderedSet{views->filter(viewpoint::DSemanticDecorator).target}.eInverse().eContainerOrSelf(genmodel::GenModel)->asSet())"/>
+                  <parameters name="message" value="The selected generator model will be updated:..."/>
+                  <parameters name="title" value="Disable CDO Native support in .genmodel ?"/>
+                </firstModelOperations>
+              </initialOperation>
+            </menuItemDescription>
+          </ownedTools>
           <ownedTools xsi:type="tool:SelectionWizardDescription" name="Add" precondition="aql:container.oclIsKindOf(ecore::EPackage)" forceRefresh="true" candidatesExpression="aql:self.getValidsForDiagram(containerView)->asSet() - diagram.getDisplayedEClassifiers()" multiple="true" tree="true" rootExpression="service:rootEPackages" childrenExpression="feature:eContents" iconPath="/org.eclipse.emf.ecoretools.design/icons/full/etools16/search.gif" windowTitle="Select element to add in diagram">
             <element name="element"/>
             <containerView name="containerView"/>
diff --git a/org.eclipse.emf.ecoretools.design/src/org/eclipse/emf/ecoretools/design/service/DesignServices.java b/org.eclipse.emf.ecoretools.design/src/org/eclipse/emf/ecoretools/design/service/DesignServices.java
index 6697a6e..c64f29b 100644
--- a/org.eclipse.emf.ecoretools.design/src/org/eclipse/emf/ecoretools/design/service/DesignServices.java
+++ b/org.eclipse.emf.ecoretools.design/src/org/eclipse/emf/ecoretools/design/service/DesignServices.java
@@ -11,6 +11,10 @@
 
 package org.eclipse.emf.ecoretools.design.service;
 
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -18,8 +22,12 @@
 import java.util.List;
 import java.util.Set;
 
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.emf.codegen.ecore.genmodel.GenDelegationKind;
+import org.eclipse.emf.codegen.ecore.genmodel.GenModel;
 import org.eclipse.emf.common.command.Command;
 import org.eclipse.emf.common.util.Diagnostic;
+import org.eclipse.emf.common.util.URI;
 import org.eclipse.emf.ecore.EAnnotation;
 import org.eclipse.emf.ecore.EAttribute;
 import org.eclipse.emf.ecore.EClass;
@@ -38,6 +46,7 @@
 import org.eclipse.emf.ecore.EcorePackage;
 import org.eclipse.emf.ecore.impl.EStringToStringMapEntryImpl;
 import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.URIConverter;
 import org.eclipse.emf.ecore.util.Diagnostician;
 import org.eclipse.emf.ecore.util.EcoreUtil;
 import org.eclipse.emf.edit.command.AddCommand;
@@ -84,807 +93,893 @@
  * Generic Ecore services usable from a VSM.
  */
 public class DesignServices extends EReferenceServices {
-    private static final String CLASS_DIAGRAM_CLASS_MAPPINGID = "EC EClass";
+	private static final String CLASS_DIAGRAM_CLASS_MAPPINGID = "EC EClass";
 
-    /**
-     * Returns all the root objects of all the resources in the same
-     * resource-set as the specified object.
-     * 
-     * @param any
-     *            an EObject.
-     * @return all the root objects in the same resource-set as <code>any</code>
-     *         or an empty collection if <code>any</code> is not inside a
-     *         resource-set.
-     */
-    public Collection<EObject> allRoots(EObject any) {
-        Resource res = any.eResource();
-        if (res != null && res.getResourceSet() != null) {
-            Collection<EObject> roots = new ArrayList<EObject>();
-            for (Resource childRes : res.getResourceSet().getResources()) {
-                roots.addAll(childRes.getContents());
-            }
-            return roots;
-        } else {
-            return Collections.emptySet();
-        }
-    }
+	/**
+	 * Returns all the root objects of all the resources in the same
+	 * resource-set as the specified object.
+	 * 
+	 * @param any
+	 *            an EObject.
+	 * @return all the root objects in the same resource-set as <code>any</code>
+	 *         or an empty collection if <code>any</code> is not inside a
+	 *         resource-set.
+	 */
+	public Collection<EObject> allRoots(EObject any) {
+		Resource res = any.eResource();
+		if (res != null && res.getResourceSet() != null) {
+			Collection<EObject> roots = new ArrayList<EObject>();
+			for (Resource childRes : res.getResourceSet().getResources()) {
+				roots.addAll(childRes.getContents());
+			}
+			return roots;
+		} else {
+			return Collections.emptySet();
+		}
+	}
 
-    public Collection<EPackage> rootEPackages(EObject any) {
-        return Sets.newLinkedHashSet(Iterables.filter(allRoots(any), EPackage.class));
-    }
+	public Collection<EPackage> rootEPackages(EObject any) {
+		return Sets.newLinkedHashSet(Iterables.filter(allRoots(any), EPackage.class));
+	}
 
-    public Boolean isEOperation(EObject any) {
-        return any instanceof EOperation;
-    }
+	public Boolean isEOperation(EObject any) {
+		return any instanceof EOperation;
+	}
 
-    public Boolean isEStructuralFeature(EObject any) {
-        return any instanceof EStructuralFeature;
-    }
+	public Boolean isEStructuralFeature(EObject any) {
+		return any instanceof EStructuralFeature;
+	}
 
-    public Boolean isEPackage(EObject any) {
-        return any instanceof EPackage;
-    }
+	public Boolean isEPackage(EObject any) {
+		return any instanceof EPackage;
+	}
 
-    public Boolean isEClass(EObject any) {
-        return any instanceof EClass;
-    }
+	public Boolean isEClass(EObject any) {
+		return any instanceof EClass;
+	}
 
-    public Boolean isEEnum(EObject any) {
-        return any instanceof EEnum;
-    }
+	public Boolean isEEnum(EObject any) {
+		return any instanceof EEnum;
+	}
 
-    protected static final String GEN_MODEL_PACKAGE_NS_URI = "http://www.eclipse.org/emf/2002/GenModel";
+	protected static final String GEN_MODEL_PACKAGE_NS_URI = "http://www.eclipse.org/emf/2002/GenModel";
 
-    protected static final String ECORE_PACKAGE_NS_URI = "http://www.eclipse.org/emf/2002/Ecore";
+	protected static final String ECORE_PACKAGE_NS_URI = "http://www.eclipse.org/emf/2002/Ecore";
 
-    public EObject markForAutosize(EObject any) {
-        if (any != null) {
-            any.eAdapters().add(AutosizeTrigger.AUTO_SIZE_MARKER);
-        }
-        return any;
-    }
+	public EObject markForAutosize(EObject any) {
+		if (any != null) {
+			any.eAdapters().add(AutosizeTrigger.AUTO_SIZE_MARKER);
+		}
+		return any;
+	}
 
-    public EObject eContainerEContainer(EObject any) {
-        if (any.eContainer() != null)
-            return any.eContainer().eContainer();
-        return null;
-    }
+	public EObject eContainerEContainer(EObject any) {
+		if (any.eContainer() != null)
+			return any.eContainer().eContainer();
+		return null;
+	}
 
-    public Collection<EStringToStringMapEntryImpl> getVisibleDocAnnotations(EObject self, DSemanticDiagram diag) {
-        // [diagram.getDisplayedEModelElements().oclAsType(ecore::EModelElement).eAnnotations.details->select(key
-        // = 'documentation')/]
-        Set<EStringToStringMapEntryImpl> result = Sets.newLinkedHashSet();
-        for (EModelElement displayed : getDisplayedEModelElements(diag)) {
-            if (!(displayed instanceof EAttribute) && !(displayed instanceof EEnumLiteral) && !(displayed instanceof EOperation)) {
-                EAnnotation eAnnot = displayed.getEAnnotation(GEN_MODEL_PACKAGE_NS_URI);
-                if (eAnnot != null) {
-                    for (EStringToStringMapEntryImpl mapEntry : Iterables.filter(eAnnot.getDetails(), EStringToStringMapEntryImpl.class)) {
-                        if ("documentation".equals(mapEntry.getKey())) {
-                            result.add(mapEntry);
-                        }
-                    }
-                }
-            }
+	public Collection<EStringToStringMapEntryImpl> getVisibleDocAnnotations(EObject self, DSemanticDiagram diag) {
+		// [diagram.getDisplayedEModelElements().oclAsType(ecore::EModelElement).eAnnotations.details->select(key
+		// = 'documentation')/]
+		Set<EStringToStringMapEntryImpl> result = Sets.newLinkedHashSet();
+		for (EModelElement displayed : getDisplayedEModelElements(diag)) {
+			if (!(displayed instanceof EAttribute) && !(displayed instanceof EEnumLiteral)
+					&& !(displayed instanceof EOperation)) {
+				EAnnotation eAnnot = displayed.getEAnnotation(GEN_MODEL_PACKAGE_NS_URI);
+				if (eAnnot != null) {
+					for (EStringToStringMapEntryImpl mapEntry : Iterables.filter(eAnnot.getDetails(),
+							EStringToStringMapEntryImpl.class)) {
+						if ("documentation".equals(mapEntry.getKey())) {
+							result.add(mapEntry);
+						}
+					}
+				}
+			}
 
-        }
-        return result;
-    }
+		}
+		return result;
+	}
 
-    public Collection<EStringToStringMapEntryImpl> getVisibleConstraintsAnnotations(EObject self, DSemanticDiagram diag) {
-        Set<EStringToStringMapEntryImpl> result = Sets.newLinkedHashSet();
-        for (EModelElement displayed : getDisplayedEModelElements(diag)) {
-            if (!(displayed instanceof EAttribute) && !(displayed instanceof EEnumLiteral) && !(displayed instanceof EOperation)) {
-                EAnnotation eAnnot = displayed.getEAnnotation(ECORE_PACKAGE_NS_URI);
-                if (eAnnot != null) {
-                    for (EStringToStringMapEntryImpl mapEntry : Iterables.filter(eAnnot.getDetails(), EStringToStringMapEntryImpl.class)) {
-                        if ("constraints".equals(mapEntry.getKey())) {
-                            result.add(mapEntry);
-                        }
-                    }
-                }
-            }
+	public Collection<EStringToStringMapEntryImpl> getVisibleConstraintsAnnotations(EObject self,
+			DSemanticDiagram diag) {
+		Set<EStringToStringMapEntryImpl> result = Sets.newLinkedHashSet();
+		for (EModelElement displayed : getDisplayedEModelElements(diag)) {
+			if (!(displayed instanceof EAttribute) && !(displayed instanceof EEnumLiteral)
+					&& !(displayed instanceof EOperation)) {
+				EAnnotation eAnnot = displayed.getEAnnotation(ECORE_PACKAGE_NS_URI);
+				if (eAnnot != null) {
+					for (EStringToStringMapEntryImpl mapEntry : Iterables.filter(eAnnot.getDetails(),
+							EStringToStringMapEntryImpl.class)) {
+						if ("constraints".equals(mapEntry.getKey())) {
+							result.add(mapEntry);
+						}
+					}
+				}
+			}
 
-        }
-        return result;
-    }
+		}
+		return result;
+	}
 
-    public boolean hasNoClassifier(DSemanticDiagram diagram) {
-        Iterator<DSemanticDecorator> it = Iterators.filter(diagram.getOwnedDiagramElements().iterator(), DSemanticDecorator.class);
-        while (it.hasNext()) {
-            DSemanticDecorator dec = it.next();
-            if (dec.getTarget() instanceof EClassifier)
-                return true;
-        }
-        return false;
-    }
+	public boolean hasNoClassifier(DSemanticDiagram diagram) {
+		Iterator<DSemanticDecorator> it = Iterators.filter(diagram.getOwnedDiagramElements().iterator(),
+				DSemanticDecorator.class);
+		while (it.hasNext()) {
+			DSemanticDecorator dec = it.next();
+			if (dec.getTarget() instanceof EClassifier)
+				return true;
+		}
+		return false;
+	}
 
-    public Set<EReference> getNonDisplayedEReferences(EClass self, DSemanticDiagram diag) {
-        Set<EReference> result = Sets.newLinkedHashSet();
-        Set<EClass> displayedEClasses = null;
-        for (EReference eReference : self.getEAllReferences()) {
-            if (eReference.getEType() != null) {
-                if (displayedEClasses == null) {
-                    displayedEClasses = getDisplayedEClasses(diag);
-                }
-                /*
-                 * if the target of the EReference is not visible, we *have* to
-                 * display it as a node except if it iis from a supertype which
-                 * is visible itself, then the reference will be already
-                 * displayed. but if the reference is owned by a super type and
-                 * this supertype is not visible, even if the target is visible,
-                 * then we have to display it as a node to!
-                 */
-                boolean targetTypeIsVisible = displayedEClasses.contains(eReference.getEType());
-                boolean referenceIsInherited = eReference.getEContainingClass() != self;
-                boolean referenceHostIsVisible = displayedEClasses.contains(eReference.getEContainingClass());
-                if (!referenceIsInherited && !targetTypeIsVisible) {
-                    result.add(eReference);
-                }
-                if (referenceIsInherited && (!referenceHostIsVisible)) {
-                    result.add(eReference);
-                }
-            }
-        }
-        return result;
-    }
+	public Set<EReference> getNonDisplayedEReferences(EClass self, DSemanticDiagram diag) {
+		Set<EReference> result = Sets.newLinkedHashSet();
+		Set<EClass> displayedEClasses = null;
+		for (EReference eReference : self.getEAllReferences()) {
+			if (eReference.getEType() != null) {
+				if (displayedEClasses == null) {
+					displayedEClasses = getDisplayedEClasses(diag);
+				}
+				/*
+				 * if the target of the EReference is not visible, we *have* to
+				 * display it as a node except if it iis from a supertype which
+				 * is visible itself, then the reference will be already
+				 * displayed. but if the reference is owned by a super type and
+				 * this supertype is not visible, even if the target is visible,
+				 * then we have to display it as a node to!
+				 */
+				boolean targetTypeIsVisible = displayedEClasses.contains(eReference.getEType());
+				boolean referenceIsInherited = eReference.getEContainingClass() != self;
+				boolean referenceHostIsVisible = displayedEClasses.contains(eReference.getEContainingClass());
+				if (!referenceIsInherited && !targetTypeIsVisible) {
+					result.add(eReference);
+				}
+				if (referenceIsInherited && (!referenceHostIsVisible)) {
+					result.add(eReference);
+				}
+			}
+		}
+		return result;
+	}
 
-    public Set<EClass> getDisplayedEClasses(DSemanticDiagram diagram) {
-        Set<EClass> result = Sets.newLinkedHashSet();
-        Iterator<DNodeList> it = Iterators.filter(new DDiagramQuery(diagram).getAllDiagramElements().iterator(), DNodeList.class);
-        while (it.hasNext()) {
-            DNodeList dec = it.next();
-            if (dec.getTarget() instanceof EClass && dec.isVisible()) {
-                result.add((EClass) dec.getTarget());
-            }
-        }
-        return result;
-    }
-    
-    public Set<EClassifier> getDisplayedEClassifiers(DSemanticDiagram diagram) {
-        Set<EClassifier> result = Sets.newLinkedHashSet();
-        Iterator<DNodeList> it = Iterators.filter(new DDiagramQuery(diagram).getAllDiagramElements().iterator(), DNodeList.class);
-        while (it.hasNext()) {
-            DNodeList dec = it.next();
-            if (dec.getTarget() instanceof EClassifier && dec.isVisible()) {
-                result.add((EClassifier) dec.getTarget());
-            }
-        }
-        return result;
-    }
+	public Set<EClass> getDisplayedEClasses(DSemanticDiagram diagram) {
+		Set<EClass> result = Sets.newLinkedHashSet();
+		Iterator<DNodeList> it = Iterators.filter(new DDiagramQuery(diagram).getAllDiagramElements().iterator(),
+				DNodeList.class);
+		while (it.hasNext()) {
+			DNodeList dec = it.next();
+			if (dec.getTarget() instanceof EClass && dec.isVisible()) {
+				result.add((EClass) dec.getTarget());
+			}
+		}
+		return result;
+	}
 
-    private Set<EClass> getInternalEClasses(DSemanticDiagram diagram) {
-        Set<EClass> result = Sets.newLinkedHashSet();
-        Iterator<DNodeList> it = Iterators.filter(new DDiagramQuery(diagram).getAllDiagramElements().iterator(), DNodeList.class);
-        while (it.hasNext()) {
-            DNodeList dec = it.next();
-            if (dec.getTarget() instanceof EClass) {
-                if (dec.getActualMapping() != null && CLASS_DIAGRAM_CLASS_MAPPINGID.equals(dec.getActualMapping().getName())) {
-                    result.add((EClass) dec.getTarget());
-                }
-            }
-        }
-        return result;
-    }
+	public Set<EClassifier> getDisplayedEClassifiers(DSemanticDiagram diagram) {
+		Set<EClassifier> result = Sets.newLinkedHashSet();
+		Iterator<DNodeList> it = Iterators.filter(new DDiagramQuery(diagram).getAllDiagramElements().iterator(),
+				DNodeList.class);
+		while (it.hasNext()) {
+			DNodeList dec = it.next();
+			if (dec.getTarget() instanceof EClassifier && dec.isVisible()) {
+				result.add((EClassifier) dec.getTarget());
+			}
+		}
+		return result;
+	}
 
-    public Set<EClass> getDirectSuperTypesOrMostSpecificVisibleOnes(EClass self, DSemanticDiagram diagram) {
-        Set<EClass> result = Sets.newLinkedHashSet();
-        Set<EClass> displayed = getDisplayedEClasses(diagram);
-        for (EClass directSuperType : self.getESuperTypes()) {
-            if (displayed.contains(directSuperType)) {
-                result.add(directSuperType);
-            } else {
-                Set<EClass> mostSpecificDisplayed = findMostSpecificAndVisible(directSuperType.getESuperTypes(), displayed);
-                if (mostSpecificDisplayed != null) {
-                    result.addAll(mostSpecificDisplayed);
-                }
-            }
-        }
-        return result;
-    }
+	private Set<EClass> getInternalEClasses(DSemanticDiagram diagram) {
+		Set<EClass> result = Sets.newLinkedHashSet();
+		Iterator<DNodeList> it = Iterators.filter(new DDiagramQuery(diagram).getAllDiagramElements().iterator(),
+				DNodeList.class);
+		while (it.hasNext()) {
+			DNodeList dec = it.next();
+			if (dec.getTarget() instanceof EClass) {
+				if (dec.getActualMapping() != null
+						&& CLASS_DIAGRAM_CLASS_MAPPINGID.equals(dec.getActualMapping().getName())) {
+					result.add((EClass) dec.getTarget());
+				}
+			}
+		}
+		return result;
+	}
 
-    private Set<EClass> findMostSpecificAndVisible(Collection<EClass> superTypes, Set<EClass> displayed) {
-        Set<EClass> result = Sets.newLinkedHashSet();
-        for (EClass eClass : superTypes) {
-            if (displayed.contains(eClass)) {
-                result.add(eClass);
-            } else {
-                result.addAll(findMostSpecificAndVisible(eClass.getESuperTypes(), displayed));
-            }
-        }
-        return result;
-    }
+	public Set<EClass> getDirectSuperTypesOrMostSpecificVisibleOnes(EClass self, DSemanticDiagram diagram) {
+		Set<EClass> result = Sets.newLinkedHashSet();
+		Set<EClass> displayed = getDisplayedEClasses(diagram);
+		for (EClass directSuperType : self.getESuperTypes()) {
+			if (displayed.contains(directSuperType)) {
+				result.add(directSuperType);
+			} else {
+				Set<EClass> mostSpecificDisplayed = findMostSpecificAndVisible(directSuperType.getESuperTypes(),
+						displayed);
+				if (mostSpecificDisplayed != null) {
+					result.addAll(mostSpecificDisplayed);
+				}
+			}
+		}
+		return result;
+	}
 
-    public Collection<EClass> getExternalEClasses(EPackage root, DSemanticDiagram diagram) {
+	private Set<EClass> findMostSpecificAndVisible(Collection<EClass> superTypes, Set<EClass> displayed) {
+		Set<EClass> result = Sets.newLinkedHashSet();
+		for (EClass eClass : superTypes) {
+			if (displayed.contains(eClass)) {
+				result.add(eClass);
+			} else {
+				result.addAll(findMostSpecificAndVisible(eClass.getESuperTypes(), displayed));
+			}
+		}
+		return result;
+	}
 
-        Set<EClass> related = Sets.newLinkedHashSet();
-        Set<EClass> eClasses = getInternalEClasses(diagram);
-        RelatedElementsSwitch relations = new RelatedElementsSwitch();
-        for (EClass eClass : eClasses) {
-            for (EClass other : Iterables.filter(relations.getRelatedElements(eClass), EClass.class)) {
-                related.add(other);
-            }
-        }
+	public Collection<EClass> getExternalEClasses(EPackage root, DSemanticDiagram diagram) {
 
-        return Sets.difference(related, eClasses);
-    }
+		Set<EClass> related = Sets.newLinkedHashSet();
+		Set<EClass> eClasses = getInternalEClasses(diagram);
+		RelatedElementsSwitch relations = new RelatedElementsSwitch();
+		for (EClass eClass : eClasses) {
+			for (EClass other : Iterables.filter(relations.getRelatedElements(eClass), EClass.class)) {
+				related.add(other);
+			}
+		}
 
-    public Collection<EReference> getEReferencesToDisplay(EPackage root, DSemanticDiagram diagram) {
-        // [diagram.getDisplayedEClasses().oclAsType(ecore::EClass).eAllReferences->flatten()/]
-        Collection<EClass> eClasses = getDisplayedEClasses(diagram);
-        Set<EReference> eRefs = Sets.newLinkedHashSet();
-        for (EClass clazz : eClasses) {
-            eRefs.addAll(clazz.getEAllReferences());
-        }
-        return eRefs;
-    }
+		return Sets.difference(related, eClasses);
+	}
 
-    public Boolean targetIsInterface(EClass clazz, EObject view) {
-        if (view instanceof DEdge) {
-            EdgeTarget target = ((DEdge) view).getTargetNode();
-            if (target instanceof DSemanticDecorator && ((DSemanticDecorator) target).getTarget() instanceof EClass) {
-                return ((EClass) ((DSemanticDecorator) target).getTarget()).isInterface();
-            }
-        }
-        return false;
-    }
+	public Collection<EReference> getEReferencesToDisplay(EPackage root, DSemanticDiagram diagram) {
+		// [diagram.getDisplayedEClasses().oclAsType(ecore::EClass).eAllReferences->flatten()/]
+		Collection<EClass> eClasses = getDisplayedEClasses(diagram);
+		Set<EReference> eRefs = Sets.newLinkedHashSet();
+		for (EClass clazz : eClasses) {
+			eRefs.addAll(clazz.getEAllReferences());
+		}
+		return eRefs;
+	}
 
-    public List<EReference> getEOppositeSemanticElements(EReference ref) {
-        Set<EReference> allRefs = Sets.newLinkedHashSet();
-        allRefs.add(ref);
-        if (ref.getEOpposite() != null)
-            allRefs.add(ref.getEOpposite());
-        return Ordering.natural().onResultOf(new Function<EReference, String>() {
+	public Boolean targetIsInterface(EClass clazz, EObject view) {
+		if (view instanceof DEdge) {
+			EdgeTarget target = ((DEdge) view).getTargetNode();
+			if (target instanceof DSemanticDecorator && ((DSemanticDecorator) target).getTarget() instanceof EClass) {
+				return ((EClass) ((DSemanticDecorator) target).getTarget()).isInterface();
+			}
+		}
+		return false;
+	}
 
-            public String apply(EReference input) {
-                return input.getName();
-            }
-        }).sortedCopy(allRefs);
-    }
+	public List<EReference> getEOppositeSemanticElements(EReference ref) {
+		Set<EReference> allRefs = Sets.newLinkedHashSet();
+		allRefs.add(ref);
+		if (ref.getEOpposite() != null)
+			allRefs.add(ref.getEOpposite());
+		return Ordering.natural().onResultOf(new Function<EReference, String>() {
 
-    public Collection<EModelElement> getDisplayedEModelElements(DSemanticDiagram diagram) {
-        Set<EModelElement> modelelements = Sets.newLinkedHashSet();
-        Iterator<DSemanticDecorator> it = Iterators.filter(Iterators.concat(Iterators.singletonIterator(diagram), new DDiagramQuery(diagram).getAllDiagramElements().iterator()),
-                DSemanticDecorator.class);
-        while (it.hasNext()) {
-            DSemanticDecorator dec = it.next();
-            if (dec.getTarget() instanceof EModelElement)
-                modelelements.add((EModelElement) dec.getTarget());
-        }
-        return modelelements;
-    }
+			public String apply(EReference input) {
+				return input.getName();
+			}
+		}).sortedCopy(allRefs);
+	}
 
-    public List<EObject> getValidsForDiagram(final EObject element, final DSemanticDecorator containerView) {
-        Predicate<EObject> validForClassDiagram = new Predicate<EObject>() {
+	public Collection<EModelElement> getDisplayedEModelElements(DSemanticDiagram diagram) {
+		Set<EModelElement> modelelements = Sets.newLinkedHashSet();
+		Iterator<DSemanticDecorator> it = Iterators.filter(Iterators.concat(Iterators.singletonIterator(diagram),
+				new DDiagramQuery(diagram).getAllDiagramElements().iterator()), DSemanticDecorator.class);
+		while (it.hasNext()) {
+			DSemanticDecorator dec = it.next();
+			if (dec.getTarget() instanceof EModelElement)
+				modelelements.add((EModelElement) dec.getTarget());
+		}
+		return modelelements;
+	}
 
-            public boolean apply(EObject input) {
-                return input instanceof EPackage || input instanceof EClassifier;
-            }
-        };
-        return allValidSessionElements(element, validForClassDiagram);
-    }
+	public List<EObject> getValidsForDiagram(final EObject element, final DSemanticDecorator containerView) {
+		Predicate<EObject> validForClassDiagram = new Predicate<EObject>() {
 
-    public Collection<EObject> getRelated(EObject firstView, List<EObject> allSelectedViews, DDiagram diag) {
-        Set<EObject> relateds = Sets.newLinkedHashSet();
-        for (DSemanticDecorator decorator : Iterables.filter(allSelectedViews, DSemanticDecorator.class)) {
-            relateds.addAll(new RelatedElementsSwitch().getRelatedElements(decorator.getTarget()));
-        }
-        return relateds;
-    }
+			public boolean apply(EObject input) {
+				return input instanceof EPackage || input instanceof EClassifier;
+			}
+		};
+		return allValidSessionElements(element, validForClassDiagram);
+	}
 
-    public Collection<EObject> getRelated(EObject firstView, EObject aView, DDiagram diag) {
-        return getRelated(firstView, Lists.newArrayList(aView), diag);
-    }
+	public Collection<EObject> getRelated(EObject firstView, List<EObject> allSelectedViews, DDiagram diag) {
+		Set<EObject> relateds = Sets.newLinkedHashSet();
+		for (DSemanticDecorator decorator : Iterables.filter(allSelectedViews, DSemanticDecorator.class)) {
+			relateds.addAll(new RelatedElementsSwitch().getRelatedElements(decorator.getTarget()));
+		}
+		return relateds;
+	}
 
-    private List<EObject> allValidSessionElements(EObject cur, Predicate<EObject> validForClassDiagram) {
-        Session found = SessionManager.INSTANCE.getSession(cur);
-        List<EObject> result = Lists.newArrayList();
-        if (found != null) {
-            for (Resource res : found.getSemanticResources()) {
-                if (res.getURI().isPlatformResource() || res.getURI().isPlatformPlugin()) {
-                    Iterators.addAll(result, Iterators.filter(res.getAllContents(), validForClassDiagram));
-                }
-            }
-        }
-        return result;
-    }
+	public Collection<EObject> getRelated(EObject firstView, EObject aView, DDiagram diag) {
+		return getRelated(firstView, Lists.newArrayList(aView), diag);
+	}
 
-    /**
-     * Gets the containing resource name, or null.
-     * 
-     * @param current
-     *            is the object
-     * @return the resource
-     */
-    public String eResourceName(final EObject current) {
-        if (current != null && current.eResource() != null) {
-            return current.eResource().getURI().lastSegment();
-        } else {
-            return null;
-        }
-    }
+	private List<EObject> allValidSessionElements(EObject cur, Predicate<EObject> validForClassDiagram) {
+		Session found = SessionManager.INSTANCE.getSession(cur);
+		List<EObject> result = Lists.newArrayList();
+		if (found != null) {
+			for (Resource res : found.getSemanticResources()) {
+				if (res.getURI().isPlatformResource() || res.getURI().isPlatformPlugin()) {
+					Iterators.addAll(result, Iterators.filter(res.getAllContents(), validForClassDiagram));
+				}
+			}
+		}
+		return result;
+	}
 
-    /**
-     * Replace spaces by camel case value.
-     * 
-     * @param any
-     * @param from
-     * @return
-     */
-    public String toCamelCase(EObject any, String from) {
-        if (from != null) {
-            StringBuffer buffer = new StringBuffer(from.length());
-            for (String word : Splitter.on(CharMatcher.WHITESPACE).trimResults().split(from)) {
-                buffer.append(toU1Case(word));
-            }
-            return buffer.toString();
-        }
-        return from;
-    }
+	/**
+	 * Gets the containing resource name, or null.
+	 * 
+	 * @param current
+	 *            is the object
+	 * @return the resource
+	 */
+	public String eResourceName(final EObject current) {
+		if (current != null && current.eResource() != null) {
+			return current.eResource().getURI().lastSegment();
+		} else {
+			return null;
+		}
+	}
 
-    private String toU1Case(String word) {
-        if (word != null && word.length() > 0) {
-            return new StringBuilder(word.length()).append(Ascii.toUpperCase(word.charAt(0))).append(word.substring(1)).toString();
-        }
-        return word;
-    }
+	/**
+	 * Replace spaces by camel case value.
+	 * 
+	 * @param any
+	 * @param from
+	 * @return
+	 */
+	public String toCamelCase(EObject any, String from) {
+		if (from != null) {
+			StringBuffer buffer = new StringBuffer(from.length());
+			for (String word : Splitter.on(CharMatcher.WHITESPACE).trimResults().split(from)) {
+				buffer.append(toU1Case(word));
+			}
+			return buffer.toString();
+		}
+		return from;
+	}
 
-    /**
-     * Computes the label of an EAttribute.
-     */
-    public String render(EAttribute attr) {
-        return new EAttributeServices().render(attr);
-    }
+	private String toU1Case(String word) {
+		if (word != null && word.length() > 0) {
+			return new StringBuilder(word.length()).append(Ascii.toUpperCase(word.charAt(0))).append(word.substring(1))
+					.toString();
+		}
+		return word;
+	}
 
-    /**
-     * Performs a "direct edit" operation on an EAttribute.
-     */
-    public EStructuralFeature performEdit(EAttribute attr, String editString) {
-        return new EAttributeServices().performEdit(attr, editString);
-    }
+	/**
+	 * Computes the label of an EAttribute.
+	 */
+	public String render(EAttribute attr) {
+		return new EAttributeServices().render(attr);
+	}
 
-    /**
-     * Performs a "direct edit" operation on an EAttribute.
-     */
-    public EStructuralFeature performEditAsAttribute(EStructuralFeature attr, String editString) {
-        return new EAttributeServices().performEdit(attr, editString);
-    }
+	/**
+	 * Performs a "direct edit" operation on an EAttribute.
+	 */
+	public EStructuralFeature performEdit(EAttribute attr, String editString) {
+		return new EAttributeServices().performEdit(attr, editString);
+	}
 
-    /**
-     * Computes the label of an EOperation.
-     */
-    public String render(EOperation op) {
-        return new EOperationServices().render(op);
-    }
+	/**
+	 * Performs a "direct edit" operation on an EAttribute.
+	 */
+	public EStructuralFeature performEditAsAttribute(EStructuralFeature attr, String editString) {
+		return new EAttributeServices().performEdit(attr, editString);
+	}
+
+	/**
+	 * Computes the label of an EOperation.
+	 */
+	public String render(EOperation op) {
+		return new EOperationServices().render(op);
+	}
+
+	public String renderTooltip(EObject current) {
+		String result = "";
+		Optional<Diagnostic> diag = DiagnosticAttachment.get(current);
+		if (diag.isPresent()) {
+			result += prettyMessage(diag.get());
+		}
+		return result;
+	}
+
+	private String prettyMessage(Diagnostic diag) {
+		String result = "";
+		for (Diagnostic child : diag.getChildren()) {
+			String message = child.getMessage();
+			/*
+			 * we remove any substring which could be the toString of some data
+			 * and replace it with something which will not change on subsequent
+			 * executions.
+			 */
+			for (EObject data : Iterables.filter(child.getData(), EObject.class)) {
+				String instanceVariableString = data.getClass().getName() + "@" + Integer.toHexString(data.hashCode());
+				message = message.replace(instanceVariableString, data.eClass().getName());
+			}
+
+			result += "\n" + severityLabel(child.getSeverity()) + " : " + message;
+			result += prettyMessage(child);
+		}
+		return result;
+	}
+
+	private String severityLabel(int severity) {
+		switch (severity) {
+		case Diagnostic.ERROR:
+			return "ERROR";
+		case Diagnostic.CANCEL:
+			return "CANCEL";
+		case Diagnostic.INFO:
+			return "INFO";
+		case Diagnostic.WARNING:
+			return "WARNING";
+		case Diagnostic.OK:
+			return "OK";
+
+		}
+		return "UNKNOWN";
+	}
+
+	/**
+	 * Computes the tooltip of an EOperation.
+	 * 
+	 * @param op
+	 *            the operation to get the tooltip from
+	 * @return the tooltip of the given EOperation.
+	 */
+	public String renderEOperationTooltip(EOperation op) {
+		String validationTooltip = renderTooltip(op);
+		String operationSignature = new EOperationServices().renderEOperationTooltip(op);
+		if (validationTooltip != null && validationTooltip.length() > 0) {
+			return validationTooltip + "\n" + operationSignature;
+		} else {
+			return operationSignature;
+		}
+	}
+
+	/**
+	 * Performs a "direct edit" operation on an EOperation.
+	 */
+	public EOperation performEdit(EOperation op, String editString) {
+		return new EOperationServices().performEdit(op, editString);
+	}
+
+	public List<ENamedElement> getAllAssociatedElements(EOperation op) {
+		return new EOperationServices().getAllAssociatedElements(op);
+	}
+
+	/**
+	 * Computes the label of an EReference.
+	 */
+	@Override
+	public String render(EReference ref) {
+		return new EReferenceServices().render(ref);
+	}
+
+	/**
+	 * Computes the label of an EReference.
+	 */
+	@Override
+	public String renderAsNode(EReference ref) {
+		return new EReferenceServices().renderAsNode(ref);
+	}
 
-    public String renderTooltip(EObject current) {
-        String result = "";
-        Optional<Diagnostic> diag = DiagnosticAttachment.get(current);
-        if (diag.isPresent()) {
-            result += prettyMessage(diag.get());
-        }
-        return result;
-    }
+	public String renderEOpposite(EReference ref) {
+		if (ref.getEOpposite() != null) {
+			return new EReferenceServices().render(ref.getEOpposite());
+		}
+		return "";
+	}
 
-    private String prettyMessage(Diagnostic diag) {
-        String result = "";
-        for (Diagnostic child : diag.getChildren()) {
-            String message = child.getMessage();
-            /*
-             * we remove any substring which could be the toString of some data
-             * and replace it with something which will not change on subsequent
-             * executions.
-             */
-            for (EObject data : Iterables.filter(child.getData(), EObject.class)) {
-                String instanceVariableString = data.getClass().getName() + "@" + Integer.toHexString(data.hashCode());
-                message = message.replace(instanceVariableString, data.eClass().getName());
-            }
+	/**
+	 * Performs a "direct edit" operation on an EReference.
+	 */
+	@Override
+	public EReference performEdit(EReference ref, String editString) {
+		return new EReferenceServices().performEdit(ref, editString);
+	}
 
-            result += "\n" + severityLabel(child.getSeverity()) + " : " + message;
-            result += prettyMessage(child);
-        }
-        return result;
-    }
+	/**
+	 * Finds a type matching the specified name (case-insensitive) in the same
+	 * resource-set as obj, or inside Ecore itself if none could be found.
+	 * 
+	 * @param obj
+	 *            the object defining the context in which to look.
+	 * @param name
+	 *            the name of the type to look for (case-insensitive). Only
+	 *            basic type names are supported (no qualified names).
+	 *            Whitespace before or after the name is ignored.
+	 * @return the first type found in the resource set or Ecore itself which
+	 *         matches the specified name.
+	 */
+	public EClassifier findTypeByName(EObject obj, String name) {
+		EClassifier result = findTypeByName(allRoots(obj), name);
+		if (result == null) {
+			result = findTypeByNameFrom(EcorePackage.eINSTANCE, name);
+		}
+		return result;
+	}
 
-    private String severityLabel(int severity) {
-        switch (severity) {
-        case Diagnostic.ERROR:
-            return "ERROR";
-        case Diagnostic.CANCEL:
-            return "CANCEL";
-        case Diagnostic.INFO:
-            return "INFO";
-        case Diagnostic.WARNING:
-            return "WARNING";
-        case Diagnostic.OK:
-            return "OK";
+	/**
+	 * Returns the root container; it may be this object itself
+	 * 
+	 * @param eObject
+	 *            the object to get the root container for.
+	 * @return the root container.
+	 */
+	public EObject getRootContainer(EObject eObject) {
+		return EcoreUtil.getRootContainer(eObject);
+	}
 
-        }
-        return "UNKNOWN";
-    }
+	private EClassifier findTypeByName(Iterable<EObject> roots, String name) {
+		for (EObject root : roots) {
+			EClassifier result = findTypeByNameFrom(root, name);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
 
-    /**
-     * Computes the tooltip of an EOperation.
-     * 
-     * @param op
-     *            the operation to get the tooltip from
-     * @return the tooltip of the given EOperation.
-     */
-    public String renderEOperationTooltip(EOperation op) {
-        String validationTooltip = renderTooltip(op);
-        String operationSignature = new EOperationServices().renderEOperationTooltip(op);
-        if (validationTooltip != null && validationTooltip.length() > 0) {
-            return validationTooltip + "\n" + operationSignature;
-        } else {
-            return operationSignature;
-        }
-    }
+	private EClassifier findTypeByNameFrom(EObject root, String name) {
+		if (root instanceof EClassifier && nameMatches((EClassifier) root, name)) {
+			return (EClassifier) root;
+		}
+		for (EObject obj : AllContents.of(root)) {
+			if (obj instanceof EClassifier && nameMatches((EClassifier) obj, name)) {
+				return (EClassifier) obj;
+			}
+		}
+		return null;
+	}
 
-    /**
-     * Performs a "direct edit" operation on an EOperation.
-     */
-    public EOperation performEdit(EOperation op, String editString) {
-        return new EOperationServices().performEdit(op, editString);
-    }
+	private boolean nameMatches(EClassifier type, String name) {
+		if (type != null && type.getName() != null && name != null) {
+			return type.getName().trim().equalsIgnoreCase(name.trim());
+		} else {
+			return false;
+		}
+	}
 
-    public List<ENamedElement> getAllAssociatedElements(EOperation op) {
-        return new EOperationServices().getAllAssociatedElements(op);
-    }
+	public Boolean hasError(EObject eObj) {
+		if (eObj instanceof EClass || eObj instanceof EStructuralFeature) {
+			DiagnosticAttachment attachment = DiagnosticAttachment.getAttachment(eObj);
+			if (attachment == null) {
+				Diagnostic diagnostic = Diagnostician.INSTANCE.validate(eObj);
+				attachment = DiagnosticAttachment.getOrCreate(eObj, diagnostic);
+			}
+			Diagnostic diag = attachment.getDiagnostic();
+			if (diag != null) {
+				return diag.getSeverity() == Diagnostic.ERROR;
+			}
+		}
+		return false;
+	}
 
-    /**
-     * Computes the label of an EReference.
-     */
-    @Override
-    public String render(EReference ref) {
-        return new EReferenceServices().render(ref);
-    }
+	public Boolean isEDataType(EObject eObj) {
+		return eObj.eClass() == EcorePackage.eINSTANCE.getEDataType();
+	}
 
-    /**
-     * Computes the label of an EReference.
-     */
-    @Override
-    public String renderAsNode(EReference ref) {
-        return new EReferenceServices().renderAsNode(ref);
-    }
+	public Boolean isDDiagram(EObject any, EObject view) {
+		return view instanceof DDiagram;
+	}
 
-    public String renderEOpposite(EReference ref) {
-        if (ref.getEOpposite() != null) {
-            return new EReferenceServices().render(ref.getEOpposite());
-        }
-        return "";
-    }
+	public List<EObject> eOperationSemanticElements(EOperation eOp) {
+		List result = Lists.newArrayList(Ordering.natural().onResultOf(new Function<EParameter, String>() {
 
-    /**
-     * Performs a "direct edit" operation on an EReference.
-     */
-    @Override
-    public EReference performEdit(EReference ref, String editString) {
-        return new EReferenceServices().performEdit(ref, editString);
-    }
+			public String apply(EParameter arg0) {
+				return arg0.getName();
+			}
+		}).sortedCopy(eOp.getEParameters()));
+		result.add(0, eOp);
+		return result;
+	}
 
-    /**
-     * Finds a type matching the specified name (case-insensitive) in the same
-     * resource-set as obj, or inside Ecore itself if none could be found.
-     * 
-     * @param obj
-     *            the object defining the context in which to look.
-     * @param name
-     *            the name of the type to look for (case-insensitive). Only
-     *            basic type names are supported (no qualified names).
-     *            Whitespace before or after the name is ignored.
-     * @return the first type found in the resource set or Ecore itself which
-     *         matches the specified name.
-     */
-    public EClassifier findTypeByName(EObject obj, String name) {
-        EClassifier result = findTypeByName(allRoots(obj), name);
-        if (result == null) {
-            result = findTypeByNameFrom(EcorePackage.eINSTANCE, name);
-        }
-        return result;
-    }
+	public Boolean viewContainerNotSemanticContainer(EObject self, DSemanticDiagram diag,
+			DSemanticDecorator containerView) {
+		return containerView.getTarget() != self.eContainer();
+	}
 
-    /**
-     * Returns the root container; it may be this object itself
-     * 
-     * @param eObject
-     *            the object to get the root container for.
-     * @return the root container.
-     */
-    public EObject getRootContainer(EObject eObject) {
-        return EcoreUtil.getRootContainer(eObject);
-    }
+	public Boolean noEOpposite(EReference ref) {
+		return ref.getEOpposite() == null;
+	}
 
-    private EClassifier findTypeByName(Iterable<EObject> roots, String name) {
-        for (EObject root : roots) {
-            EClassifier result = findTypeByNameFrom(root, name);
-            if (result != null) {
-                return result;
-            }
-        }
-        return null;
-    }
+	public boolean hasNoDocAnnotation(EObject eObj) {
+		// Error[eAnnotations.details->select(key = 'documentation')->size() =
+		// 0/]
+		if (eObj instanceof EModelElement) {
+			return EcoreUtil.getDocumentation((EModelElement) eObj) == null;
+		}
+		return true;
+	}
 
-    private EClassifier findTypeByNameFrom(EObject root, String name) {
-        if (root instanceof EClassifier && nameMatches((EClassifier) root, name)) {
-            return (EClassifier) root;
-        }
-        for (EObject obj : AllContents.of(root)) {
-            if (obj instanceof EClassifier && nameMatches((EClassifier) obj, name)) {
-                return (EClassifier) obj;
-            }
-        }
-        return null;
-    }
+	public EdgeArrows arrowsFillDiamond(EObject any) {
+		return EdgeArrows.FILL_DIAMOND_LITERAL;
+	}
 
-    private boolean nameMatches(EClassifier type, String name) {
-        if (type != null && type.getName() != null && name != null) {
-            return type.getName().trim().equalsIgnoreCase(name.trim());
-        } else {
-            return false;
-        }
-    }
+	public FontFormat fontFormatBold(EObject any) {
+		return FontFormat.BOLD_LITERAL;
+	}
 
-    public Boolean hasError(EObject eObj) {
-        if (eObj instanceof EClass || eObj instanceof EStructuralFeature) {
-            DiagnosticAttachment attachment = DiagnosticAttachment.getAttachment(eObj);
-            if (attachment == null) {
-                Diagnostic diagnostic = Diagnostician.INSTANCE.validate(eObj);
-                attachment = DiagnosticAttachment.getOrCreate(eObj, diagnostic);
-            }
-            Diagnostic diag = attachment.getDiagnostic();
-            if (diag != null) {
-                return diag.getSeverity() == Diagnostic.ERROR;
-            }
-        }
-        return false;
-    }
+	public void reconnectESuperTypeSource(EObject element, EObject target, EObject source, EObject otherEnd,
+			EObject edgeView, EObject sourceView) {
+		if (edgeView instanceof DEdge && ((DEdge) edgeView).getSourceNode() instanceof DSemanticDecorator
+				&& ((DEdge) edgeView).getTargetNode() instanceof DSemanticDecorator) {
+			EObject newSource = ((DSemanticDecorator) ((DEdge) edgeView).getSourceNode()).getTarget();
+			EObject newTarget = ((DSemanticDecorator) ((DEdge) edgeView).getTargetNode()).getTarget();
 
-    public Boolean isEDataType(EObject eObj) {
-        return eObj.eClass() == EcorePackage.eINSTANCE.getEDataType();
-    }
+			/*
+			 * reconnect source:
+			 */
+			if (newSource instanceof EClass && newTarget instanceof EClass && source instanceof EClass) {
+				((EClass) source).getESuperTypes().remove(newTarget);
+				((EClass) newSource).getESuperTypes().add((EClass) newTarget);
 
-    public Boolean isDDiagram(EObject any, EObject view) {
-        return view instanceof DDiagram;
-    }
+			}
+		}
 
-    public List<EObject> eOperationSemanticElements(EOperation eOp) {
-        List result = Lists.newArrayList(Ordering.natural().onResultOf(new Function<EParameter, String>() {
+	}
 
-            public String apply(EParameter arg0) {
-                return arg0.getName();
-            }
-        }).sortedCopy(eOp.getEParameters()));
-        result.add(0, eOp);
-        return result;
-    }
+	public void reconnectESuperTypeTarget(EObject element, EObject target, EObject source, EObject otherEnd,
+			EObject edgeView, EObject sourceView) {
+		if (edgeView instanceof DEdge && ((DEdge) edgeView).getSourceNode() instanceof DSemanticDecorator
+				&& ((DEdge) edgeView).getTargetNode() instanceof DSemanticDecorator) {
+			EObject newTarget = ((DSemanticDecorator) ((DEdge) edgeView).getTargetNode()).getTarget();
 
-    public Boolean viewContainerNotSemanticContainer(EObject self, DSemanticDiagram diag, DSemanticDecorator containerView) {
-        return containerView.getTarget() != self.eContainer();
-    }
+			/*
+			 * reconnect target:
+			 */
+			if (newTarget instanceof EClass && target instanceof EClass && element instanceof EClass) {
+				((EClass) element).getESuperTypes().remove(newTarget);
+				((EClass) element).getESuperTypes().add((EClass) target);
 
-    public Boolean noEOpposite(EReference ref) {
-        return ref.getEOpposite() == null;
-    }
+			}
+		}
 
-    public boolean hasNoDocAnnotation(EObject eObj) {
-        // Error[eAnnotations.details->select(key = 'documentation')->size() =
-        // 0/]
-        if (eObj instanceof EModelElement) {
-            return EcoreUtil.getDocumentation((EModelElement) eObj) == null;
-        }
-        return true;
-    }
+	}
 
-    public EdgeArrows arrowsFillDiamond(EObject any) {
-        return EdgeArrows.FILL_DIAMOND_LITERAL;
-    }
+	public void reconnectEReferenceSource(EObject element, EObject newValue) {
+		if (newValue instanceof EClass && element instanceof EReference) {
 
-    public FontFormat fontFormatBold(EObject any) {
-        return FontFormat.BOLD_LITERAL;
-    }
+			EReference eRef = (EReference) element;
+			EClass srcClass = (EClass) newValue;
 
-    public void reconnectESuperTypeSource(EObject element, EObject target, EObject source, EObject otherEnd, EObject edgeView, EObject sourceView) {
-        if (edgeView instanceof DEdge && ((DEdge) edgeView).getSourceNode() instanceof DSemanticDecorator && ((DEdge) edgeView).getTargetNode() instanceof DSemanticDecorator) {
-            EObject newSource = ((DSemanticDecorator) ((DEdge) edgeView).getSourceNode()).getTarget();
-            EObject newTarget = ((DSemanticDecorator) ((DEdge) edgeView).getTargetNode()).getTarget();
+			if (eRef.eContainer() != srcClass) {
+				srcClass.getEStructuralFeatures().add(eRef);
+			}
 
-            /*
-             * reconnect source:
-             */
-            if (newSource instanceof EClass && newTarget instanceof EClass && source instanceof EClass) {
-                ((EClass) source).getESuperTypes().remove(newTarget);
-                ((EClass) newSource).getESuperTypes().add((EClass) newTarget);
+		}
+	}
 
-            }
-        }
+	public void reconnectEReferenceTarget(EObject element, EObject newValue) {
+		if (newValue != null && element instanceof EReference) {
 
-    }
+			EReference eRef = (EReference) element;
 
-    public void reconnectESuperTypeTarget(EObject element, EObject target, EObject source, EObject otherEnd, EObject edgeView, EObject sourceView) {
-        if (edgeView instanceof DEdge && ((DEdge) edgeView).getSourceNode() instanceof DSemanticDecorator && ((DEdge) edgeView).getTargetNode() instanceof DSemanticDecorator) {
-            EObject newTarget = ((DSemanticDecorator) ((DEdge) edgeView).getTargetNode()).getTarget();
+			if (newValue instanceof EClass) {
+				EClass targetClass = (EClass) newValue;
+				if (eRef.getEType() != newValue) {
+					eRef.setEType(targetClass);
+				}
+			} else if (newValue instanceof ETypeParameter) {
+				if (eRef.getEType() != newValue) {
+					EGenericsServices.setETypeWithGenerics(eRef, newValue);
+				}
+			}
 
-            /*
-             * reconnect target:
-             */
-            if (newTarget instanceof EClass && target instanceof EClass && element instanceof EClass) {
-                ((EClass) element).getESuperTypes().remove(newTarget);
-                ((EClass) element).getESuperTypes().add((EClass) target);
+		}
+	}
 
-            }
-        }
+	/**
+	 * Create view.
+	 * 
+	 * @param semanticElement
+	 *            Semantic element
+	 * @param containerView
+	 *            Container view
+	 * @param session
+	 *            Session
+	 * @param containerViewVariable
+	 *            Name of the container view variable
+	 */
+	private void createView(final EObject semanticElement, final DSemanticDecorator containerView,
+			final Session session, final String containerViewVariable) {
+		// Get all available mappings applicable for the copiedElement in the
+		// current container
+		List<DiagramElementMapping> semanticElementMappings = getMappings(semanticElement, containerView, session);
 
-    }
+		// Build a createView tool
+		final CreateView createViewOp = ToolFactory.eINSTANCE.createCreateView();
+		for (DiagramElementMapping copiedElementMapping : semanticElementMappings) {
+			final DiagramElementMapping tmpCopiedElementMapping = copiedElementMapping;
+			createViewOp.setMapping(tmpCopiedElementMapping);
+			final String containerViewExpression = "var:" + containerViewVariable;
+			createViewOp.setContainerViewExpression(containerViewExpression);
 
-    public void reconnectEReferenceSource(EObject element, EObject newValue) {
-        if (newValue instanceof EClass && element instanceof EReference) {
+			session.getTransactionalEditingDomain().getCommandStack()
+					.execute(new RecordingCommand(session.getTransactionalEditingDomain()) {
 
-            EReference eRef = (EReference) element;
-            EClass srcClass = (EClass) newValue;
+						@SuppressWarnings("restriction")
+						@Override
+						protected void doExecute() {
+							try {
+								// Get the command context
+								DRepresentation representation = null;
+								if (containerView instanceof DRepresentation) {
+									representation = (DRepresentation) containerView;
+								} else if (containerView instanceof DDiagramElement) {
+									representation = ((DDiagramElement) containerView).getParentDiagram();
+								}
 
-            if (eRef.eContainer() != srcClass) {
-                srcClass.getEStructuralFeatures().add(eRef);
-            }
+								final CommandContext context = new CommandContext(semanticElement, representation);
 
-        }
-    }
+								// Execute the create view task
+								new CreateViewTask(context, session.getModelAccessor(), createViewOp,
+										session.getInterpreter()).execute();
+							} catch (MetaClassNotFoundException e) {
+								EcoreToolsDesignPlugin.INSTANCE.log(e);
+							} catch (FeatureNotFoundException e) {
+								EcoreToolsDesignPlugin.INSTANCE.log(e);
+							}
+						}
+					});
+		}
+	}
 
-    public void reconnectEReferenceTarget(EObject element, EObject newValue) {
-        if (newValue != null && element instanceof EReference) {
+	/**
+	 * Paste a semantic element and create the corresponding view in the given
+	 * container
+	 * 
+	 * @param container
+	 *            Semantic container
+	 * @param semanticElement
+	 *            Element to paste
+	 * @param containerView
+	 *            Container view
+	 */
+	public void paste(final EObject container, final EObject semanticElement, final DSemanticDecorator elementView,
+			final DSemanticDecorator containerView) {
+		// Paste the semantic element from the clipboard to the selected
+		// container
+		final Session session = SessionManager.INSTANCE.getSession(container);
+		TransactionalEditingDomain domain = session.getTransactionalEditingDomain();
+		// The feature is set to null because the domain will deduce it
+		Command cmd = AddCommand.create(domain, container, null, semanticElement);
+		if (cmd.canExecute()) {
+			cmd.execute();
+		}
+		// Create the view for the pasted element
+		createView(semanticElement, containerView, session, "containerView");
+	}
 
-            EReference eRef = (EReference) element;
+	/**
+	 * Get mappings available for a semantic element and a given container view.
+	 * 
+	 * @param semanticElement
+	 *            Semantic element
+	 * @param containerView
+	 *            Container view
+	 * @param session
+	 *            Session
+	 * @return List of mappings which could not be null
+	 */
+	@SuppressWarnings("restriction")
+	private List<DiagramElementMapping> getMappings(final EObject semanticElement,
+			final DSemanticDecorator containerView, Session session) {
+		ModelAccessor modelAccessor = session.getModelAccessor();
+		List<DiagramElementMapping> mappings = new ArrayList<DiagramElementMapping>();
 
-            if (newValue instanceof EClass) {
-                EClass targetClass = (EClass) newValue;
-                if (eRef.getEType() != newValue) {
-                    eRef.setEType(targetClass);
-                }
-            } else if (newValue instanceof ETypeParameter) {
-                if (eRef.getEType() != newValue) {
-                    EGenericsServices.setETypeWithGenerics(eRef, newValue);
-                }
-            }
+		if (containerView instanceof DSemanticDiagram) {
 
-        }
-    }
+			for (DiagramElementMapping mapping : (((DSemanticDiagram) containerView).getDescription()
+					.getAllContainerMappings())) {
+				String domainClass = ((AbstractNodeMapping) mapping).getDomainClass();
+				if (modelAccessor.eInstanceOf(semanticElement, domainClass) && !mapping.isCreateElements()) {
+					mappings.add(mapping);
+				}
+			}
+			for (DiagramElementMapping mapping : (((DSemanticDiagram) containerView).getDescription()
+					.getAllNodeMappings())) {
+				String domainClass = ((AbstractNodeMapping) mapping).getDomainClass();
+				if (modelAccessor.eInstanceOf(semanticElement, domainClass) && !mapping.isCreateElements()) {
+					mappings.add(mapping);
+				}
+			}
+		} else if (containerView instanceof DNodeContainer) {
+			for (DiagramElementMapping mapping : (((DNodeContainer) containerView).getActualMapping()
+					.getAllContainerMappings())) {
+				String domainClass = ((AbstractNodeMapping) mapping).getDomainClass();
+				if (modelAccessor.eInstanceOf(semanticElement, domainClass) && !mapping.isCreateElements()) {
+					mappings.add(mapping);
+				}
+			}
+			for (DiagramElementMapping mapping : (((DNodeContainer) containerView).getActualMapping()
+					.getAllNodeMappings())) {
+				String domainClass = ((AbstractNodeMapping) mapping).getDomainClass();
+				if (modelAccessor.eInstanceOf(semanticElement, domainClass) && !mapping.isCreateElements()) {
+					mappings.add(mapping);
+				}
+			}
+		}
+		return mappings;
+	}
 
-    /**
-     * Create view.
-     * 
-     * @param semanticElement
-     *            Semantic element
-     * @param containerView
-     *            Container view
-     * @param session
-     *            Session
-     * @param containerViewVariable
-     *            Name of the container view variable
-     */
-    private void createView(final EObject semanticElement, final DSemanticDecorator containerView, final Session session, final String containerViewVariable) {
-        // Get all available mappings applicable for the copiedElement in the
-        // current container
-        List<DiagramElementMapping> semanticElementMappings = getMappings(semanticElement, containerView, session);
+	public String getClassesTableName(EObject cur) {
+		// [(if (oclIsKindOf(ecore::EStructuralFeature) and
+		// oclAsType(ecore::EStructuralFeature).derived) then '/' else '' endif)
+		// + name/]
+		if (cur instanceof EStructuralFeature) {
+			if (((EStructuralFeature) cur).isDerived()) {
+				return "/" + ((EStructuralFeature) cur).getName();
+			}
+		}
+		if (cur instanceof ENamedElement) {
+			return ((ENamedElement) cur).getName();
+		}
+		return cur.eClass().getName();
+	}
 
-        // Build a createView tool
-        final CreateView createViewOp = ToolFactory.eINSTANCE.createCreateView();
-        for (DiagramElementMapping copiedElementMapping : semanticElementMappings) {
-            final DiagramElementMapping tmpCopiedElementMapping = copiedElementMapping;
-            createViewOp.setMapping(tmpCopiedElementMapping);
-            final String containerViewExpression = "var:" + containerViewVariable;
-            createViewOp.setContainerViewExpression(containerViewExpression);
+	public boolean hasCDOBundle(EObject cur) {
+		return Platform.getBundle("org.eclipse.emf.cdo") != null;
+	}
 
-            session.getTransactionalEditingDomain().getCommandStack().execute(new RecordingCommand(session.getTransactionalEditingDomain()) {
+	public EObject enableCDOGen(EObject cur, Set<GenModel> genmodels) throws IOException {
+		for (GenModel genModel : genmodels) {
+			if (isNotFromPluginsOrRegistry(genModel)) {
+				genModel.getModelPluginVariables().add("CDO=org.eclipse.emf.cdo");
+				genModel.setRootExtendsInterface("org.eclipse.emf.cdo.CDOObject");
+				genModel.setRootExtendsClass("org.eclipse.emf.internal.cdo.CDOObjectImpl");
+				genModel.setFeatureDelegation(GenDelegationKind.REFLECTIVE_LITERAL);
+				genModel.setProviderRootExtendsClass("org.eclipse.emf.cdo.edit.CDOItemProviderAdapter");
 
-                @SuppressWarnings("restriction")
-                @Override
-                protected void doExecute() {
-                    try {
-                        // Get the command context
-                        DRepresentation representation = null;
-                        if (containerView instanceof DRepresentation) {
-                            representation = (DRepresentation) containerView;
-                        } else if (containerView instanceof DDiagramElement) {
-                            representation = ((DDiagramElement) containerView).getParentDiagram();
-                        }
+				if (genModel.eResource().getURI().isPlatformResource()) {
+					URI cdoMFURI = getCDOMFUri(genModel);
+					if (!URIConverter.INSTANCE.exists(cdoMFURI, Collections.EMPTY_MAP)) {
+						try (OutputStream out = URIConverter.INSTANCE.createOutputStream(cdoMFURI,
+								Collections.EMPTY_MAP)) {
+							new PrintWriter(out).write("This is a marker file for bundles with CDO native models.");
+						}
+					}
 
-                        final CommandContext context = new CommandContext(semanticElement, representation);
+				}
 
-                        // Execute the create view task
-                        new CreateViewTask(context, session.getModelAccessor(), createViewOp, session.getInterpreter()).execute();
-                    } catch (MetaClassNotFoundException e) {
-                        EcoreToolsDesignPlugin.INSTANCE.log(e);
-                    } catch (FeatureNotFoundException e) {
-                        EcoreToolsDesignPlugin.INSTANCE.log(e);
-                    }
-                }
-            });
-        }
-    }
+			}
+		}
+		return cur;
+	}
 
-    /**
-     * Paste a semantic element and create the corresponding view in the given
-     * container
-     * 
-     * @param container
-     *            Semantic container
-     * @param semanticElement
-     *            Element to paste
-     * @param containerView
-     *            Container view
-     */
-    public void paste(final EObject container, final EObject semanticElement, final DSemanticDecorator elementView, final DSemanticDecorator containerView) {
-        // Paste the semantic element from the clipboard to the selected
-        // container
-        final Session session = SessionManager.INSTANCE.getSession(container);
-        TransactionalEditingDomain domain = session.getTransactionalEditingDomain();
-        // The feature is set to null because the domain will deduce it
-        Command cmd = AddCommand.create(domain, container, null, semanticElement);
-        if (cmd.canExecute()) {
-            cmd.execute();
-        }
-        // Create the view for the pasted element
-        createView(semanticElement, containerView, session, "containerView");
-    }
+	private boolean isNotFromPluginsOrRegistry(GenModel genModel) {
+		return genModel.eResource() != null && genModel.eResource().getURI() != null
+				&& !genModel.eResource().getURI().isPlatformPlugin();
+	}
 
-    /**
-     * Get mappings available for a semantic element and a given container view.
-     * 
-     * @param semanticElement
-     *            Semantic element
-     * @param containerView
-     *            Container view
-     * @param session
-     *            Session
-     * @return List of mappings which could not be null
-     */
-    @SuppressWarnings("restriction")
-    private List<DiagramElementMapping> getMappings(final EObject semanticElement, final DSemanticDecorator containerView, Session session) {
-        ModelAccessor modelAccessor = session.getModelAccessor();
-        List<DiagramElementMapping> mappings = new ArrayList<DiagramElementMapping>();
+	private URI getCDOMFUri(GenModel genModel) {
+		return URI.createPlatformResourceURI(genModel.eResource().getURI().segment(1), true).appendSegment("META-INF")
+				.appendSegment("CDO.MF");
+	}
 
-        if (containerView instanceof DSemanticDiagram) {
+	public EObject disableCDOGen(EObject cur, Set<GenModel> genmodels) throws IOException {
+		for (GenModel genModel : genmodels) {
+			if (isNotFromPluginsOrRegistry(genModel)) {
+				genModel.getModelPluginVariables().remove("CDO=org.eclipse.emf.cdo");
+				genModel.setRootExtendsInterface("org.eclipse.emf.ecore.EObject");
+				genModel.setRootExtendsClass("org.eclipse.emf.ecore.impl.MinimalEObjectImpl$Container");
+				genModel.setFeatureDelegation(GenDelegationKind.NONE_LITERAL);
+				genModel.setProviderRootExtendsClass(null);
 
-            for (DiagramElementMapping mapping : (((DSemanticDiagram) containerView).getDescription().getAllContainerMappings())) {
-                String domainClass = ((AbstractNodeMapping) mapping).getDomainClass();
-                if (modelAccessor.eInstanceOf(semanticElement, domainClass) && !mapping.isCreateElements()) {
-                    mappings.add(mapping);
-                }
-            }
-            for (DiagramElementMapping mapping : (((DSemanticDiagram) containerView).getDescription().getAllNodeMappings())) {
-                String domainClass = ((AbstractNodeMapping) mapping).getDomainClass();
-                if (modelAccessor.eInstanceOf(semanticElement, domainClass) && !mapping.isCreateElements()) {
-                    mappings.add(mapping);
-                }
-            }
-        } else if (containerView instanceof DNodeContainer) {
-            for (DiagramElementMapping mapping : (((DNodeContainer) containerView).getActualMapping().getAllContainerMappings())) {
-                String domainClass = ((AbstractNodeMapping) mapping).getDomainClass();
-                if (modelAccessor.eInstanceOf(semanticElement, domainClass) && !mapping.isCreateElements()) {
-                    mappings.add(mapping);
-                }
-            }
-            for (DiagramElementMapping mapping : (((DNodeContainer) containerView).getActualMapping().getAllNodeMappings())) {
-                String domainClass = ((AbstractNodeMapping) mapping).getDomainClass();
-                if (modelAccessor.eInstanceOf(semanticElement, domainClass) && !mapping.isCreateElements()) {
-                    mappings.add(mapping);
-                }
-            }
-        }
-        return mappings;
-    }
+				if (genModel.eResource().getURI().isPlatformResource()) {
+					URI cdoMFURI = getCDOMFUri(genModel);
+					if (URIConverter.INSTANCE.exists(cdoMFURI, Collections.EMPTY_MAP)) {
+						URIConverter.INSTANCE.delete(cdoMFURI, Collections.EMPTY_MAP);
+					}
 
-    public String getClassesTableName(EObject cur) {
-        // [(if (oclIsKindOf(ecore::EStructuralFeature) and
-        // oclAsType(ecore::EStructuralFeature).derived) then '/' else '' endif)
-        // + name/]
-        if (cur instanceof EStructuralFeature) {
-            if (((EStructuralFeature) cur).isDerived()) {
-                return "/" + ((EStructuralFeature) cur).getName();
-            }
-        }
-        if (cur instanceof ENamedElement) {
-            return ((ENamedElement) cur).getName();
-        }
-        return cur.eClass().getName();
-    }
+				}
+			}
+		}
+		return cur;
+	}
 
 }
diff --git a/org.eclipse.emf.ecoretools.design/src/org/eclipse/emf/ecoretools/design/service/GenerationServices.java b/org.eclipse.emf.ecoretools.design/src/org/eclipse/emf/ecoretools/design/service/GenerationServices.java
index dbd2873..c860ddc 100644
--- a/org.eclipse.emf.ecoretools.design/src/org/eclipse/emf/ecoretools/design/service/GenerationServices.java
+++ b/org.eclipse.emf.ecoretools.design/src/org/eclipse/emf/ecoretools/design/service/GenerationServices.java
@@ -1,5 +1,11 @@
 package org.eclipse.emf.ecoretools.design.service;
 
+import java.util.Set;
+
+import org.eclipse.emf.codegen.ecore.genmodel.GenDelegationKind;
+import org.eclipse.emf.codegen.ecore.genmodel.GenModel;
+
 public class GenerationServices extends DesignServices {
 
+
 }