diff --git a/org.fortiss.tooling.base.ui/META-INF/MANIFEST.MF b/org.fortiss.tooling.base.ui/META-INF/MANIFEST.MF
index 791aa8d77355695d76da7a1ea13c3e00bd1cffee..42280c20dac8696d2d983387342bc6c3f3fef1cb 100644
--- a/org.fortiss.tooling.base.ui/META-INF/MANIFEST.MF
+++ b/org.fortiss.tooling.base.ui/META-INF/MANIFEST.MF
@@ -25,7 +25,9 @@ Export-Package: org.fortiss.tooling.base.ui,
  org.fortiss.tooling.base.ui.editor,
  org.fortiss.tooling.base.ui.editor.annotations,
  org.fortiss.tooling.base.ui.editor.fx,
- org.fortiss.tooling.base.ui.editor.fx.visuals,
+ org.fortiss.tooling.base.ui.editor.fx.controller,
+ org.fortiss.tooling.base.ui.editor.fx.model,
+ org.fortiss.tooling.base.ui.editor.fx.visual,
  org.fortiss.tooling.base.ui.editpart,
  org.fortiss.tooling.base.ui.editpart.allocation,
  org.fortiss.tooling.base.ui.editpart.command,
diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/.ratings b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/.ratings
new file mode 100644
index 0000000000000000000000000000000000000000..4811e9c2991d2e451beef74b3519eb1eeb70d8b0
--- /dev/null
+++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/.ratings
@@ -0,0 +1,10 @@
+ContextMenuUtil.java 7be87ce47b775d90c533078e22d4d445d9864caf GREEN
+EObjectDiagramController.java 66b14c1c77953cad7caecae1e04f455958943f28 GREEN
+EObjectModelChangeProvider.java f4b60cebb088a5c81ca92a41614e1a5d40030502 GREEN
+EObjectRectangularResizableContentControllerBase.java 787a540213f29e8daaecd9afe98af8b3f4088db7 GREEN
+KernelServiceBasedModelChangeProviderBase.java 18e48f17ea8dfba90de024a8959fc5a4b0d05d45 GREEN
+LayoutModelChangeProvider.java b5449d02eaf39086909720c43e21bd061005fc9e GREEN
+LayoutedContentAnchorageController.java 3794b41d76e9ce14ead0bd812cde5c1a6d348d5c GREEN
+LayoutedDiagramAnchorageController.java 1e1ac7c5fa26c632736f5023e90f05d09bc0710d GREEN
+LayoutedLinkBendPointController.java a8372485ae96f2abf773d1baeb1f8c7b2b25985f GREEN
+LayoutedRectangularResizableContentController.java 1e18af3ee10dd3754325ed389fed664da65a0b61 GREEN
diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/ContextMenuUtil.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/ContextMenuUtil.java
similarity index 98%
rename from org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/ContextMenuUtil.java
rename to org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/ContextMenuUtil.java
index 3e04dbd52ee99a59735d39b4087c55b07fb91076..7be87ce47b775d90c533078e22d4d445d9864caf 100644
--- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/ContextMenuUtil.java
+++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/ContextMenuUtil.java
@@ -13,7 +13,7 @@
 | See the License for the specific language governing permissions and      |
 | limitations under the License.                                           |
 +--------------------------------------------------------------------------*/
-package org.fortiss.tooling.base.ui.editor.fx;
+package org.fortiss.tooling.base.ui.editor.fx.controller;
 
 import static org.fortiss.tooling.base.utils.LayoutModelElementFactory.createPoint;
 
diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/EObjectBasedDiagramControllerBase.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/EObjectDiagramController.java
similarity index 71%
rename from org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/EObjectBasedDiagramControllerBase.java
rename to org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/EObjectDiagramController.java
index 3564ece9b3cac29caaf9201e0be3451a6a3c2b21..66b14c1c77953cad7caecae1e04f455958943f28 100644
--- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/EObjectBasedDiagramControllerBase.java
+++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/EObjectDiagramController.java
@@ -11,12 +11,13 @@
  *     Florian Hoelzl (fortiss GmbH) - initial implementation
  *
  *******************************************************************************/
-package org.fortiss.tooling.base.ui.editor.fx;
+package org.fortiss.tooling.base.ui.editor.fx.controller;
 
 import static java.lang.Math.max;
-import static org.fortiss.tooling.base.ui.editor.fx.ContextMenuUtil.createDisplayMenu;
-import static org.fortiss.tooling.base.ui.editor.fx.ContextMenuUtil.createElementCompositionContext;
-import static org.fortiss.tooling.base.ui.editor.fx.ContextMenuUtil.createPrototypeMenu;
+import static java.util.Objects.requireNonNull;
+import static org.fortiss.tooling.base.ui.editor.fx.controller.ContextMenuUtil.createDisplayMenu;
+import static org.fortiss.tooling.base.ui.editor.fx.controller.ContextMenuUtil.createElementCompositionContext;
+import static org.fortiss.tooling.base.ui.editor.fx.controller.ContextMenuUtil.createPrototypeMenu;
 
 import java.util.List;
 
@@ -39,18 +40,20 @@ import javafx.scene.control.MenuItem;
  * 
  * @author hoelzl
  */
-public abstract class EObjectBasedDiagramControllerBase extends ControllerBase {
+public class EObjectDiagramController<T extends EObject> extends ControllerBase {
 
 	/** The model change provider. */
 	private final EObjectModelChangeProvider modelChangeProvider;
 
 	/** Constructor. */
-	public EObjectBasedDiagramControllerBase(IMVCBundle mvcb) {
+	public EObjectDiagramController(IMVCBundle mvcb, Class<T> modelType) {
 		super(mvcb);
-		if(!(getModel() instanceof EObject)) {
-			throw new IllegalArgumentException("Model element must be an instance of an EObject.");
+		Object model = requireNonNull(mvcb.getModel(), "The given model is null!");
+		if(!modelType.isAssignableFrom(model.getClass())) {
+			throw new IllegalArgumentException("Expected model of type " +
+					modelType.getSimpleName() + ", but was " + model.getClass().getSimpleName());
 		}
-		this.modelChangeProvider = new EObjectModelChangeProvider(getEObject());
+		this.modelChangeProvider = new EObjectModelChangeProvider(getModelElement());
 	}
 
 	/** {@inheritDoc} */
@@ -60,9 +63,10 @@ public abstract class EObjectBasedDiagramControllerBase extends ControllerBase {
 	}
 
 	/** Returns the {@link EObject} model element. */
-	protected EObject getEObject() {
+	@SuppressWarnings("unchecked")
+	protected T getModelElement() {
 		// wild cast works: see constructor check with exception
-		return (EObject)getModel();
+		return (T)getModel();
 	}
 
 	/** {@inheritDoc} */
@@ -74,7 +78,7 @@ public abstract class EObjectBasedDiagramControllerBase extends ControllerBase {
 		double y = max(features.getVerticalSpacing(), diagramLocation.getY());
 
 		// wild cast works: see constructor exception
-		EObject modelParent = getEObject();
+		T modelParent = getModelElement();
 		IElementCompositionContext edc = createElementCompositionContext(modelParent, x, y, true,
 				getViewer().getFeatures().getCurrentZoomFactor());
 		List<MenuItem> result = createPrototypeMenu(modelParent, edc);
diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/EObjectModelChangeProvider.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/EObjectModelChangeProvider.java
similarity index 97%
rename from org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/EObjectModelChangeProvider.java
rename to org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/EObjectModelChangeProvider.java
index 664e4db2e32124832682aff8235ac380ed4db1c0..f4b60cebb088a5c81ca92a41614e1a5d40030502 100644
--- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/EObjectModelChangeProvider.java
+++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/EObjectModelChangeProvider.java
@@ -13,7 +13,7 @@
 | See the License for the specific language governing permissions and      |
 | limitations under the License.                                           |
 +--------------------------------------------------------------------------*/
-package org.fortiss.tooling.base.ui.editor.fx;
+package org.fortiss.tooling.base.ui.editor.fx.controller;
 
 import org.eclipse.emf.common.notify.Adapter;
 import org.eclipse.emf.common.notify.Notification;
diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/EObjectBasedRectangularResizableContentControllerBase.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/EObjectRectangularResizableContentControllerBase.java
similarity index 61%
rename from org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/EObjectBasedRectangularResizableContentControllerBase.java
rename to org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/EObjectRectangularResizableContentControllerBase.java
index a263a6c123ee96015e0a5c37b6e3c13ebd0e8a75..787a540213f29e8daaecd9afe98af8b3f4088db7 100644
--- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/EObjectBasedRectangularResizableContentControllerBase.java
+++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/EObjectRectangularResizableContentControllerBase.java
@@ -11,11 +11,14 @@
  *     Florian Hoelzl (fortiss GmbH) - initial implementation
  *
  *******************************************************************************/
-package org.fortiss.tooling.base.ui.editor.fx;
+package org.fortiss.tooling.base.ui.editor.fx.controller;
 
 import static java.lang.Math.max;
-import static org.fortiss.tooling.base.ui.editor.fx.ContextMenuUtil.createElementCompositionContext;
-import static org.fortiss.tooling.base.ui.editor.fx.ContextMenuUtil.createPrototypeMenu;
+import static java.util.Objects.requireNonNull;
+import static org.fortiss.tooling.base.layout.DefaultLayoutConstants.DEFAULT_SHAPE_MINIMUM_HEIGHT;
+import static org.fortiss.tooling.base.layout.DefaultLayoutConstants.DEFAULT_SHAPE_MINIMUM_WIDTH;
+import static org.fortiss.tooling.base.ui.editor.fx.controller.ContextMenuUtil.createElementCompositionContext;
+import static org.fortiss.tooling.base.ui.editor.fx.controller.ContextMenuUtil.createPrototypeMenu;
 
 import java.util.List;
 
@@ -25,9 +28,12 @@ import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.DiagramCoordinate;
 import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.DiagramViewerFeatures;
 import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.change.Change;
 import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.controller.IClickController;
+import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.controller.IDragController;
 import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.controller.base.ClickControllerBase;
+import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.controller.rectangular.RectangularContentAnchorageMoveController;
 import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.controller.rectangular.RectangularResizableContentControllerBase;
 import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.model.IModelChangeProvider;
+import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.IContentAnchorageMVCBundle;
 import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.IContentMVCBundle;
 import org.fortiss.tooling.base.model.element.ElementPackage;
 import org.fortiss.tooling.base.model.layout.ILayoutedModelElement;
@@ -37,6 +43,7 @@ import org.fortiss.tooling.kernel.ui.extension.IModelElementHandler;
 import org.fortiss.tooling.kernel.ui.service.IModelEditorBindingService;
 import org.fortiss.tooling.kernel.ui.service.IModelElementHandlerService;
 
+import javafx.geometry.Dimension2D;
 import javafx.scene.Node;
 import javafx.scene.control.MenuItem;
 import javafx.scene.input.MouseEvent;
@@ -47,28 +54,29 @@ import javafx.scene.input.MouseEvent;
  * 
  * @author hoelzl
  */
-public abstract class EObjectBasedRectangularResizableContentControllerBase
+public abstract class EObjectRectangularResizableContentControllerBase<T extends EObject>
 		extends RectangularResizableContentControllerBase {
+
 	/** {@link IModelChangeProvider} for this controller */
-	private final LayoutModelElementModelChangeProvider layoutModelChangeProvider;
+	private final LayoutModelChangeProvider layoutModelChangeProvider;
 	/** The click controller handling double-click to open editor. */
 	private final IClickController openEditorDoubleClickController = new ClickControllerBase() {
 		@Override
 		public Change singleClick(MouseEvent event, Node node, DiagramCoordinate diagramLocation) {
-			return EObjectBasedRectangularResizableContentControllerBase.super.getClickController(
-					node, diagramLocation).singleClick(event, node, diagramLocation);
+			return EObjectRectangularResizableContentControllerBase.super.getClickController(node,
+					diagramLocation).singleClick(event, node, diagramLocation);
 		}
 
 		@Override
 		public Change secondaryClick(MouseEvent event, Node node,
 				DiagramCoordinate diagramLocation) {
-			return EObjectBasedRectangularResizableContentControllerBase.super.getClickController(
-					node, diagramLocation).secondaryClick(event, node, diagramLocation);
+			return EObjectRectangularResizableContentControllerBase.super.getClickController(node,
+					diagramLocation).secondaryClick(event, node, diagramLocation);
 		}
 
 		@Override
 		public Change doubleClick(MouseEvent event, Node node, DiagramCoordinate diagramLocation) {
-			EObject eo = getLayoutedME();
+			EObject eo = getModelElement();
 			IModelElementHandler<EObject> handler =
 					IModelElementHandlerService.getInstance().getModelElementHandler(eo);
 			if(handler != null) {
@@ -80,18 +88,22 @@ public abstract class EObjectBasedRectangularResizableContentControllerBase
 	};
 
 	/** Constructor. */
-	public EObjectBasedRectangularResizableContentControllerBase(IContentMVCBundle mvcb) {
+	public EObjectRectangularResizableContentControllerBase(IContentMVCBundle mvcb,
+			Class<T> modelType) {
 		super(mvcb);
-		if(!(mvcb.getModel() instanceof ILayoutedModelElement)) {
-			throw new IllegalArgumentException(
-					"Model element must be an instance of an ILayoutedModelElement.");
+
+		Object model = requireNonNull(mvcb.getModel(), "The given model is null!");
+		if(!modelType.isAssignableFrom(model.getClass())) {
+			throw new IllegalArgumentException("Expected model of type " +
+					modelType.getSimpleName() + ", but was " + model.getClass().getSimpleName());
 		}
+
 		ILayoutedModelElement lme = (ILayoutedModelElement)mvcb.getModel();
-		this.layoutModelChangeProvider = new LayoutModelElementModelChangeProvider(lme) {
+		this.layoutModelChangeProvider = new LayoutModelChangeProvider(lme) {
 			/** {@inheritDoc} */
 			@Override
 			protected boolean acceptNotification(Notification notification) {
-				if(notification.getNotifier() != getLayoutedME()) {
+				if(notification.getNotifier() != getModelElement()) {
 					return false;
 				}
 				return isAnchorageFeature(notification.getFeature());
@@ -99,10 +111,11 @@ public abstract class EObjectBasedRectangularResizableContentControllerBase
 		};
 	}
 
-	/** Returns the {@link ILayoutedModelElement} model element. */
-	protected ILayoutedModelElement getLayoutedME() {
+	/** Returns the correctly casted model element. */
+	@SuppressWarnings("unchecked")
+	protected T getModelElement() {
 		// wild cast works: see constructor check with exception
-		return (ILayoutedModelElement)getModel();
+		return (T)getModel();
 	}
 
 	/** {@inheritDoc} */
@@ -111,6 +124,28 @@ public abstract class EObjectBasedRectangularResizableContentControllerBase
 		return layoutModelChangeProvider;
 	}
 
+	/** {@inheritDoc} */
+	@Override
+	protected IDragController createAnchorageMoveController(IContentAnchorageMVCBundle anchorage) {
+		// we need an overridden port move controller due to the frameworks default snapping
+		// behavior, which snaps to anchorage size while AF3 ports snap to half their size
+		return new RectangularContentAnchorageMoveController(this, anchorage) {
+			/** {@inheritDoc} */
+			@Override
+			protected Dimension2D overrideBorderSnap(Dimension2D anchorageSize) {
+				// this override is required because ports can be moved by half their size
+				// while the default implementation would only allow for full size of the port
+				return new Dimension2D(anchorageSize.getWidth() / 2, anchorageSize.getHeight() / 2);
+			}
+		};
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	protected Dimension2D getMinimumSize() {
+		return new Dimension2D(DEFAULT_SHAPE_MINIMUM_WIDTH, DEFAULT_SHAPE_MINIMUM_HEIGHT);
+	}
+
 	/** {@inheritDoc} */
 	@Override
 	public List<MenuItem> contextMenuContributions(Node node, DiagramCoordinate diagramLocation) {
@@ -129,7 +164,7 @@ public abstract class EObjectBasedRectangularResizableContentControllerBase
 	/** {@inheritDoc} */
 	@Override
 	public void delete() {
-		IElementCompositorService.getInstance().decompose(getLayoutedME());
+		IElementCompositorService.getInstance().decompose(getModelElement());
 	}
 
 	/** Checks whether the given feature corresponds to an anchorage model element. */
diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/KernelServiceBasedModelChangeProviderBase.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/KernelServiceBasedModelChangeProviderBase.java
similarity index 98%
rename from org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/KernelServiceBasedModelChangeProviderBase.java
rename to org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/KernelServiceBasedModelChangeProviderBase.java
index 7c30347fb0c7cc4aacc79aeaf85167872afc1958..18e48f17ea8dfba90de024a8959fc5a4b0d05d45 100644
--- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/KernelServiceBasedModelChangeProviderBase.java
+++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/KernelServiceBasedModelChangeProviderBase.java
@@ -13,7 +13,7 @@
 | See the License for the specific language governing permissions and      |
 | limitations under the License.                                           |
 +--------------------------------------------------------------------------*/
-package org.fortiss.tooling.base.ui.editor.fx;
+package org.fortiss.tooling.base.ui.editor.fx.controller;
 
 import java.util.ArrayList;
 import java.util.EventObject;
diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/LayoutModelElementModelChangeProvider.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/LayoutModelChangeProvider.java
similarity index 94%
rename from org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/LayoutModelElementModelChangeProvider.java
rename to org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/LayoutModelChangeProvider.java
index 70c50b789c0088a7e5363bf662bc707a5b5ddf10..b5449d02eaf39086909720c43e21bd061005fc9e 100644
--- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/LayoutModelElementModelChangeProvider.java
+++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/LayoutModelChangeProvider.java
@@ -13,7 +13,7 @@
 | See the License for the specific language governing permissions and      |
 | limitations under the License.                                           |
 +--------------------------------------------------------------------------*/
-package org.fortiss.tooling.base.ui.editor.fx;
+package org.fortiss.tooling.base.ui.editor.fx.controller;
 
 import static org.fortiss.tooling.base.model.layout.LayoutPackage.ILAYOUTED_MODEL_ELEMENT__LAYOUT_DATA;
 
@@ -26,11 +26,11 @@ import org.fortiss.tooling.base.model.layout.ILayoutedModelElement;
 import org.fortiss.tooling.base.model.layout.LayoutPackage;
 
 /**
- * An {@link KernelServiceBasedModelChangeProviderBase} for {@link ILayoutedModelElement}s.
+ * A {@link KernelServiceBasedModelChangeProviderBase} for {@link ILayoutedModelElement}s.
  * 
  * @author hoelzl
  */
-class LayoutModelElementModelChangeProvider
+class LayoutModelChangeProvider
 		extends KernelServiceBasedModelChangeProviderBase<ILayoutedModelElement> {
 	/** The layouted model element. */
 	private final ILayoutedModelElement modelElement;
@@ -38,7 +38,7 @@ class LayoutModelElementModelChangeProvider
 	private final LayoutModelElementAdapter notificationListener;
 
 	/** Constructor. */
-	public LayoutModelElementModelChangeProvider(ILayoutedModelElement modelElement) {
+	public LayoutModelChangeProvider(ILayoutedModelElement modelElement) {
 		this.modelElement = modelElement;
 		this.notificationListener = new LayoutModelElementAdapter();
 	}
diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/LayoutedModelElementBasedContentAnchorageController.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/LayoutedContentAnchorageController.java
similarity index 84%
rename from org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/LayoutedModelElementBasedContentAnchorageController.java
rename to org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/LayoutedContentAnchorageController.java
index c4dfb9dbcd16078c63321d5dec13a902e4088949..3794b41d76e9ce14ead0bd812cde5c1a6d348d5c 100644
--- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/LayoutedModelElementBasedContentAnchorageController.java
+++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/LayoutedContentAnchorageController.java
@@ -11,8 +11,9 @@
  *     Florian Hoelzl (fortiss GmbH) - initial implementation
  *
  *******************************************************************************/
-package org.fortiss.tooling.base.ui.editor.fx;
+package org.fortiss.tooling.base.ui.editor.fx.controller;
 
+import static java.util.Objects.requireNonNull;
 import static org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.DiagramViewerDefaultTags.LINK_TARGET_ALLOWED_TAG;
 import static org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.DiagramViewerDefaultTags.LINK_TARGET_DENIED_TAG;
 
@@ -34,20 +35,23 @@ import org.fortiss.tooling.kernel.service.IElementCompositorService;
  * 
  * @author hoelzl
  */
-public class LayoutedModelElementBasedContentAnchorageController
+public class LayoutedContentAnchorageController<T extends ILayoutedModelElement>
 		extends DelegatingContentAnchorageController {
 	/** {@link IModelChangeProvider} for this controller */
-	private final LayoutModelElementModelChangeProvider layoutModelChangeProvider;
+	private final LayoutModelChangeProvider layoutModelChangeProvider;
 
 	/** Constructor. */
-	public LayoutedModelElementBasedContentAnchorageController(IContentAnchorageMVCBundle mvcb) {
+	public LayoutedContentAnchorageController(IContentAnchorageMVCBundle mvcb, Class<T> modelType) {
 		super(mvcb);
-		if(!(mvcb.getModel() instanceof ILayoutedModelElement)) {
-			throw new IllegalArgumentException(
-					"Model element must be an instance of an ILayoutedModelElement.");
+
+		Object model = requireNonNull(mvcb.getModel(), "The given model is null!");
+		if(!modelType.isAssignableFrom(model.getClass())) {
+			throw new IllegalArgumentException("Expected model of type " +
+					modelType.getSimpleName() + ", but was " + model.getClass().getSimpleName());
 		}
+
 		ILayoutedModelElement lme = (ILayoutedModelElement)mvcb.getModel();
-		this.layoutModelChangeProvider = new LayoutModelElementModelChangeProvider(lme);
+		this.layoutModelChangeProvider = new LayoutModelChangeProvider(lme);
 	}
 
 	/** Returns the model element. */
diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/LayoutedModelElementBasedDiagramAnchorageController.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/LayoutedDiagramAnchorageController.java
similarity index 85%
rename from org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/LayoutedModelElementBasedDiagramAnchorageController.java
rename to org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/LayoutedDiagramAnchorageController.java
index 8e66f7d8207d2b6a03abaa151f94b51449ad66c7..1e1ac7c5fa26c632736f5023e90f05d09bc0710d 100644
--- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/LayoutedModelElementBasedDiagramAnchorageController.java
+++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/LayoutedDiagramAnchorageController.java
@@ -11,8 +11,9 @@
  *     Florian Hoelzl (fortiss GmbH) - initial implementation
  *
  *******************************************************************************/
-package org.fortiss.tooling.base.ui.editor.fx;
+package org.fortiss.tooling.base.ui.editor.fx.controller;
 
+import static java.util.Objects.requireNonNull;
 import static org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.DiagramViewerDefaultTags.LINK_TARGET_ALLOWED_TAG;
 import static org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.DiagramViewerDefaultTags.LINK_TARGET_DENIED_TAG;
 import static org.fortiss.tooling.base.utils.LayoutDataUtils.moveNode;
@@ -34,19 +35,23 @@ import org.fortiss.tooling.kernel.service.IElementCompositorService;
  * 
  * @author hoelzl
  */
-public class LayoutedModelElementBasedDiagramAnchorageController extends MoveControllerBase {
+public class LayoutedDiagramAnchorageController<T extends ILayoutedModelElement>
+		extends MoveControllerBase {
 	/** {@link IModelChangeProvider} for this controller */
-	private final LayoutModelElementModelChangeProvider layoutModelChangeProvider;
+	private final LayoutModelChangeProvider layoutModelChangeProvider;
 
 	/** Constructor. */
-	public LayoutedModelElementBasedDiagramAnchorageController(IMVCBundle mvcb) {
+	public LayoutedDiagramAnchorageController(IMVCBundle mvcb, Class<T> modelType) {
 		super(mvcb);
-		if(!(mvcb.getModel() instanceof ILayoutedModelElement)) {
-			throw new IllegalArgumentException(
-					"Model element must be an instance of an ILayoutedModelElement.");
+
+		Object model = requireNonNull(mvcb.getModel(), "The given model is null!");
+		if(!modelType.isAssignableFrom(model.getClass())) {
+			throw new IllegalArgumentException("Expected model of type " +
+					modelType.getSimpleName() + ", but was " + model.getClass().getSimpleName());
 		}
+
 		ILayoutedModelElement lme = (ILayoutedModelElement)mvcb.getModel();
-		this.layoutModelChangeProvider = new LayoutModelElementModelChangeProvider(lme);
+		this.layoutModelChangeProvider = new LayoutModelChangeProvider(lme);
 	}
 
 	/** Returns the model element. */
diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/LayoutedModelElementBasedLinkBendPointController.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/LayoutedLinkBendPointController.java
similarity index 70%
rename from org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/LayoutedModelElementBasedLinkBendPointController.java
rename to org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/LayoutedLinkBendPointController.java
index eb00b6119c02199b53b1a8e3cee2687f835b727c..a8372485ae96f2abf773d1baeb1f8c7b2b25985f 100644
--- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/LayoutedModelElementBasedLinkBendPointController.java
+++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/LayoutedLinkBendPointController.java
@@ -11,8 +11,9 @@
  *     Florian Hoelzl (fortiss GmbH) - initial implementation
  *
  *******************************************************************************/
-package org.fortiss.tooling.base.ui.editor.fx;
+package org.fortiss.tooling.base.ui.editor.fx.controller;
 
+import static java.util.Objects.requireNonNull;
 import static org.fortiss.tooling.base.ui.utils.LayoutDataUIUtils.addConnectionPoint;
 import static org.fortiss.tooling.base.ui.utils.LayoutDataUIUtils.getConnectionPoints;
 import static org.fortiss.tooling.base.ui.utils.LayoutDataUIUtils.removeConnectionPoint;
@@ -37,24 +38,43 @@ import org.fortiss.tooling.kernel.service.IConnectionCompositorService;
  * 
  * @author hoelzl
  */
-public class LayoutedModelElementBasedLinkBendPointController extends LinkControllerBase {
+public class LayoutedLinkBendPointController<T extends ILayoutedModelElement>
+		extends LinkControllerBase {
 	/** {@link IModelChangeProvider} for this controller */
-	private final LayoutModelElementModelChangeProvider layoutModelChangeProvider;
+	private final LayoutModelChangeProvider layoutModelChangeProvider;
 
 	/** Constructor. */
-	public LayoutedModelElementBasedLinkBendPointController(ILinkMVCBundle mvcb) {
+	public LayoutedLinkBendPointController(ILinkMVCBundle mvcb, Class<T> modelType) {
 		super(mvcb);
-		if(!(mvcb.getModel() instanceof ILayoutedModelElement)) {
-			throw new IllegalArgumentException(
-					"Model element must be an instance of an ILayoutedModelElement.");
+
+		Object model = requireNonNull(mvcb.getModel(), "The given model is null!");
+		if(!modelType.isAssignableFrom(model.getClass())) {
+			throw new IllegalArgumentException("Expected model of type " +
+					modelType.getSimpleName() + ", but was " + model.getClass().getSimpleName());
 		}
+
 		ILayoutedModelElement lme = (ILayoutedModelElement)mvcb.getModel();
-		this.layoutModelChangeProvider = new LayoutModelElementModelChangeProvider(lme);
+		this.layoutModelChangeProvider = new LayoutModelChangeProvider(lme);
 	}
 
 	/** Returns the model element. */
-	public ILayoutedModelElement getLayoutedME() {
-		return (ILayoutedModelElement)getModel();
+	@SuppressWarnings("unchecked")
+	public T getModelElement() {
+		return (T)getModel();
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	protected boolean clampAndSnapBendPointToGridCenter() {
+		// disable default mode
+		return false;
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	protected boolean clampAndSnapBendPointToGrid() {
+		// enable clamping mode
+		return true;
 	}
 
 	/** {@inheritDoc} */
@@ -66,7 +86,7 @@ public class LayoutedModelElementBasedLinkBendPointController extends LinkContro
 	/** {@inheritDoc} */
 	@Override
 	protected int getNumerOfBendPoints() {
-		return getBendPointList(getLayoutedME()).size();
+		return getBendPointList(getModelElement()).size();
 	}
 
 	/** Returns the list of bend-points. */
@@ -79,13 +99,13 @@ public class LayoutedModelElementBasedLinkBendPointController extends LinkContro
 	protected void createBendPointAt(int bpIndex, DiagramCoordinate location) {
 		int x = (int)location.getX();
 		int y = (int)location.getY();
-		addConnectionPoint(getLayoutedME(), bpIndex, x, y);
+		addConnectionPoint(getModelElement(), bpIndex, x, y);
 	}
 
 	/** {@inheritDoc} */
 	@Override
 	protected void updateModelAfterBendPointMove(int bpIndex, double dx, double dy) {
-		List<Point> oldPoints = getBendPointList(getLayoutedME());
+		List<Point> oldPoints = getBendPointList(getModelElement());
 		Point point = oldPoints.get(bpIndex);
 		int oldX = point.getX();
 		int oldY = point.getY();
@@ -98,7 +118,7 @@ public class LayoutedModelElementBasedLinkBendPointController extends LinkContro
 	/** {@inheritDoc} */
 	@Override
 	protected void deleteBendPoint(int bpIndex) {
-		removeConnectionPoint(getLayoutedME(), bpIndex);
+		removeConnectionPoint(getModelElement(), bpIndex);
 	}
 
 	/** {@inheritDoc} */
@@ -111,7 +131,7 @@ public class LayoutedModelElementBasedLinkBendPointController extends LinkContro
 	/** {@inheritDoc} */
 	@Override
 	protected void deleteLink() {
-		IConnectionCompositorService.getInstance().disconnect(getLayoutedME());
+		IConnectionCompositorService.getInstance().disconnect(getModelElement());
 	}
 
 	/** {@inheritDoc} */
diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/LayoutedRectangularResizableContentController.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/LayoutedRectangularResizableContentController.java
new file mode 100644
index 0000000000000000000000000000000000000000..1e18af3ee10dd3754325ed389fed664da65a0b61
--- /dev/null
+++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/LayoutedRectangularResizableContentController.java
@@ -0,0 +1,90 @@
+/*-------------------------------------------------------------------------+
+| Copyright 2019 fortiss GmbH                                              |
+|                                                                          |
+| Licensed under the Apache License, Version 2.0 (the "License");          |
+| you may not use this file except in compliance with the License.         |
+| You may obtain a copy of the License at                                  |
+|                                                                          |
+|    http://www.apache.org/licenses/LICENSE-2.0                            |
+|                                                                          |
+| Unless required by applicable law or agreed to in writing, software      |
+| distributed under the License is distributed on an "AS IS" BASIS,        |
+| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
+| See the License for the specific language governing permissions and      |
+| limitations under the License.                                           |
++--------------------------------------------------------------------------*/
+package org.fortiss.tooling.base.ui.editor.fx.controller;
+
+import static java.util.Objects.requireNonNull;
+import static org.fortiss.tooling.base.ui.utils.LWFXEditorUtils.convertSideToEOrientation;
+import static org.fortiss.tooling.base.utils.LayoutDataUtils.getNodeSize;
+import static org.fortiss.tooling.base.utils.LayoutDataUtils.moveNode;
+import static org.fortiss.tooling.base.utils.LayoutDataUtils.setNodeSize;
+import static org.fortiss.tooling.base.utils.LayoutDataUtils.setStickyConnectorLayoutData;
+
+import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.FeedbackChange;
+import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.controller.IController;
+import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.IContentAnchorageMVCBundle;
+import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.IContentMVCBundle;
+import org.fortiss.tooling.base.model.element.IConnector;
+import org.fortiss.tooling.base.model.layout.Dimension;
+import org.fortiss.tooling.base.model.layout.ILayoutedModelElement;
+
+import javafx.geometry.Dimension2D;
+import javafx.geometry.Side;
+
+/**
+ * {@link IController} for {@link ILayoutedModelElement}s that have a rectangular shape.
+ * 
+ * @author diewald
+ */
+public class LayoutedRectangularResizableContentController<T extends ILayoutedModelElement>
+		extends EObjectRectangularResizableContentControllerBase<T> {
+	/** Constructor. */
+	public LayoutedRectangularResizableContentController(IContentMVCBundle mvcb,
+			Class<T> modelType) {
+		super(mvcb, modelType);
+
+		Object model = requireNonNull(mvcb.getModel(), "The given model is null!");
+		if(!modelType.isAssignableFrom(model.getClass())) {
+			throw new IllegalArgumentException("Expected model of type " +
+					modelType.getSimpleName() + ", but was " + model.getClass().getSimpleName());
+		}
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	protected void moveAnchorageToSideOffset(IContentAnchorageMVCBundle anchorage, Side side,
+			double offset) {
+		Object connObj = anchorage.getModel();
+		if(connObj instanceof IConnector && connObj instanceof ILayoutedModelElement) {
+			ILayoutedModelElement conn = (ILayoutedModelElement)connObj;
+
+			Dimension2D portDim = anchorage.getVisual().getDimensions();
+			int correction;
+			if(side == Side.TOP || side == Side.BOTTOM) {
+				correction = (int)portDim.getWidth() / 2;
+			} else {
+				correction = (int)portDim.getHeight() / 2;
+			}
+			int corrected = (int)offset + correction;
+			setStickyConnectorLayoutData(conn, convertSideToEOrientation(side), corrected);
+		}
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	protected void move(FeedbackChange deltaChange) {
+		moveNode(getModelElement(), (int)deltaChange.getDeltaX(), (int)deltaChange.getDeltaY());
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	protected void resize(FeedbackChange delta) {
+		T element = getModelElement();
+		Dimension d = getNodeSize(element);
+		int w = d.getWidth() + (int)delta.getDeltaW();
+		int h = d.getHeight() + (int)delta.getDeltaH();
+		setNodeSize(element, w, h);
+	}
+}
diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/model/.ratings b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/model/.ratings
new file mode 100644
index 0000000000000000000000000000000000000000..1f94f2987b843eba33765b057f6d210e4bbbcbb4
--- /dev/null
+++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/model/.ratings
@@ -0,0 +1 @@
+HierarchicElementModelFactoryBase.java 9996bfc1402c27424f0ae69e64560acce0ef81f4 GREEN
diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/model/HierarchicElementModelFactoryBase.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/model/HierarchicElementModelFactoryBase.java
new file mode 100644
index 0000000000000000000000000000000000000000..9996bfc1402c27424f0ae69e64560acce0ef81f4
--- /dev/null
+++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/model/HierarchicElementModelFactoryBase.java
@@ -0,0 +1,106 @@
+/*-------------------------------------------------------------------------+
+| Copyright 2019 fortiss GmbH                                              |
+|                                                                          |
+| Licensed under the Apache License, Version 2.0 (the "License");          |
+| you may not use this file except in compliance with the License.         |
+| You may obtain a copy of the License at                                  |
+|                                                                          |
+|    http://www.apache.org/licenses/LICENSE-2.0                            |
+|                                                                          |
+| Unless required by applicable law or agreed to in writing, software      |
+| distributed under the License is distributed on an "AS IS" BASIS,        |
+| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
+| See the License for the specific language governing permissions and      |
+| limitations under the License.                                           |
++--------------------------------------------------------------------------*/
+package org.fortiss.tooling.base.ui.editor.fx.model;
+
+import static java.util.Collections.emptyList;
+import static java.util.Objects.requireNonNull;
+import static org.fortiss.tooling.common.util.LambdaUtils.filterList;
+
+import java.util.List;
+
+import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.model.IModelFactory;
+import org.fortiss.tooling.base.model.element.IConnection;
+import org.fortiss.tooling.base.model.element.IHierarchicElement;
+
+/**
+ * {@link IModelFactory} for {@link IHierarchicElement}s of editors.
+ * 
+ * @author diewald
+ */
+public abstract class HierarchicElementModelFactoryBase<T extends IHierarchicElement>
+		implements IModelFactory {
+	/** The currently edited element. */
+	private final T rootElement;
+
+	/** Constructor. */
+	public HierarchicElementModelFactoryBase(T root) {
+		this.rootElement = requireNonNull(root);
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public T getRootModel() {
+		return rootElement;
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public List<?> getDiagramAnchorageModels() {
+		return rootElement.getConnectors();
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public List<?> getContentAnchorageModels(Object parent) {
+		if(parent instanceof IHierarchicElement) {
+			return ((IHierarchicElement)parent).getConnectors();
+		}
+		return emptyList();
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public List<?> getLinkModels() {
+		return filterList(rootElement.getConnections(),
+				c -> filterPartiallyInitializedConnections(c));
+	}
+
+	/** Checks whether the given connection is only partially initialized. */
+	private boolean filterPartiallyInitializedConnections(IConnection c) {
+		return c.getSource() != null && c.getTarget() != null && c.eContainer() != null;
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public Object getLinkStart(Object link) {
+		if(link instanceof IConnection) {
+			return ((IConnection)link).getSource();
+		}
+		return null;
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public Object getLinkEnd(Object link) {
+		if(link instanceof IConnection) {
+			return ((IConnection)link).getTarget();
+		}
+		return null;
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public Object getParent(Object element) {
+		// Not used at the moment, so return null.
+		return null;
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public void update() {
+		// Not used at the moment.
+	}
+}
diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/.ratings b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/.ratings
new file mode 100644
index 0000000000000000000000000000000000000000..5a82836cd656dbc37a323c788161b6ffab643988
--- /dev/null
+++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/.ratings
@@ -0,0 +1,9 @@
+CoordinateCorrections.java c5cc475b45de38c56fc2e888a2d3093cd2efb52a GREEN
+LayoutedCircularAnchorageContentVisualBase.java 2aa292444671bf644e37bc923b877c92de0235b1 GREEN
+LayoutedCircularAnchorageDiagramVisualBase.java f06e3b908020408e3cd268a3c63edcd75ef74f8b GREEN
+LayoutedLineLinkVisual.java feea85e0bd288590fbe06c152a8a8b138ea85ca2 GREEN
+LayoutedRectangularContentVisualBase.java c2a3937b99284713e0bbcd3ce458874567b25ac5 GREEN
+NamedLayoutedCircularAnchorageContentVisual.java c680002469ce897679fa5a3f4af51d1b19cb53d6 GREEN
+NamedLayoutedCircularAnchorageDiagramVisual.java 714a176a0569a2049efb4009f710ca66bf3a57fb GREEN
+NamedLayoutedLineLinkVisual.java e66e5b2aaa40fe8b22a292e175bb8f3af4539b9d GREEN
+NamedLayoutedRectangularContentVisual.java 122e193ac587857d1dad23b42583a0bcf465f0d0 GREEN
diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visuals/CoordinateCorrections.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/CoordinateCorrections.java
similarity index 87%
rename from org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visuals/CoordinateCorrections.java
rename to org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/CoordinateCorrections.java
index f78a936ba49c5fc4daf29237ecb4e86a446316d4..c5cc475b45de38c56fc2e888a2d3093cd2efb52a 100644
--- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visuals/CoordinateCorrections.java
+++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/CoordinateCorrections.java
@@ -13,7 +13,7 @@
 | See the License for the specific language governing permissions and      |
 | limitations under the License.                                           |
 +--------------------------------------------------------------------------*/
-package org.fortiss.tooling.base.ui.editor.fx.visuals;
+package org.fortiss.tooling.base.ui.editor.fx.visual;
 
 import static org.fortiss.tooling.base.layout.DefaultLayoutConstants.DEFAULT_CONNECTOR_SIZE;
 
@@ -27,14 +27,15 @@ import javafx.geometry.Dimension2D;
  * This class contains corrections of {@link DefaultLayoutConstants}.
  * 
  * @author hoelzl
+ * @author diewald
  */
-class CoordinateCorrections {
+public class CoordinateCorrections {
 	/** The insets of the {@link RectangularContentVisualBase}s. */
-	/* package */ static final Dimension2D RECTANGLE_INSETS =
+	public static final Dimension2D RECTANGLE_INSETS =
 			new Dimension2D(DEFAULT_CONNECTOR_SIZE / 2, DEFAULT_CONNECTOR_SIZE / 2);
 	/** The default size of {@link ContentAnchorageVisualBase}s. */
-	/* package */ static final Dimension2D ANCHOR_DIMENSION =
+	public static final Dimension2D ANCHOR_DIMENSION =
 			new Dimension2D(DEFAULT_CONNECTOR_SIZE, DEFAULT_CONNECTOR_SIZE);
 	/** The insets of the {@link ContentAnchorageVisualBase}s. */
-	/* package */ static final double ANCHOR_INSET = DEFAULT_CONNECTOR_SIZE / 4.5;
+	public static final double ANCHOR_INSET = DEFAULT_CONNECTOR_SIZE / 4.5;
 }
diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visuals/LayoutedCircularContentAnchorageVisualBase.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/LayoutedCircularAnchorageContentVisualBase.java
similarity index 81%
rename from org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visuals/LayoutedCircularContentAnchorageVisualBase.java
rename to org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/LayoutedCircularAnchorageContentVisualBase.java
index aa546c0c9d975972a33cf22682b5d6634e56d271..2aa292444671bf644e37bc923b877c92de0235b1 100644
--- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visuals/LayoutedCircularContentAnchorageVisualBase.java
+++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/LayoutedCircularAnchorageContentVisualBase.java
@@ -13,14 +13,14 @@
 | See the License for the specific language governing permissions and      |
 | limitations under the License.                                           |
 +--------------------------------------------------------------------------*/
-package org.fortiss.tooling.base.ui.editor.fx.visuals;
+package org.fortiss.tooling.base.ui.editor.fx.visual;
 
 import static javafx.scene.paint.Color.BLACK;
 import static javafx.scene.paint.Color.rgb;
 import static org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.DiagramViewerDefaultTags.LINK_TARGET_ALLOWED_TAG;
 import static org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.DiagramViewerDefaultTags.LINK_TARGET_DENIED_TAG;
-import static org.fortiss.tooling.base.ui.editor.fx.visuals.CoordinateCorrections.ANCHOR_DIMENSION;
-import static org.fortiss.tooling.base.ui.editor.fx.visuals.CoordinateCorrections.ANCHOR_INSET;
+import static org.fortiss.tooling.base.ui.editor.fx.visual.CoordinateCorrections.ANCHOR_DIMENSION;
+import static org.fortiss.tooling.base.ui.editor.fx.visual.CoordinateCorrections.ANCHOR_INSET;
 import static org.fortiss.tooling.base.ui.utils.LWFXEditorUtils.convertEOrientationToSide;
 import static org.fortiss.tooling.base.ui.utils.LayoutDataUIUtils.getConnectorOffsetOrientation;
 
@@ -46,26 +46,36 @@ import javafx.scene.paint.Paint;
  * 
  * @author munaro
  */
-public abstract class LayoutedCircularContentAnchorageVisualBase
+public abstract class LayoutedCircularAnchorageContentVisualBase<T extends ILayoutedModelElement>
 		extends CircularContentAnchorageVisualBase implements ISideLayout, IOffsetLayout {
 
 	/** Constructor. */
-	public LayoutedCircularContentAnchorageVisualBase(IContentAnchorageMVCBundle mvcb) {
+	public LayoutedCircularAnchorageContentVisualBase(IContentAnchorageMVCBundle mvcb,
+			Class<T> modelType) {
 		super(mvcb);
+
 		// TODO(#3877): Move type checks to a common base class.
 		Object model = mvcb.getModel();
-		if(!(model instanceof ILayoutedModelElement)) {
-			throw new IllegalArgumentException(
-					"Expected model of type ILayoutedModelElement, but was " +
-							model.getClass().getSimpleName() + ".");
+		if(model == null) {
+			throw new IllegalArgumentException("The given model is null!");
+		}
+		if(!modelType.isAssignableFrom(model.getClass())) {
+			throw new IllegalArgumentException("Expected model of type " +
+					modelType.getSimpleName() + ", but was " + model.getClass().getSimpleName());
 		}
 	}
 
+	/** Returns the model element in the correct type. */
+	@SuppressWarnings("unchecked")
+	protected T getModelElement() {
+		return (T)getModel();
+	}
+
 	/** {@inheritDoc} */
 	@SuppressWarnings("unchecked")
 	@Override
-	public <T extends ILayout> T getLayout(Class<T> type) {
-		return (T)this;
+	public <S extends ILayout> S getLayout(Class<S> type) {
+		return (S)this;
 	}
 
 	/** {@inheritDoc} */
@@ -92,7 +102,7 @@ public abstract class LayoutedCircularContentAnchorageVisualBase
 	/** {@inheritDoc} */
 	@Override
 	public double getOffset() {
-		OffsetOrientation offsetOrientation = getConnectorOffsetOrientation(getLayoutedModelElement());
+		OffsetOrientation offsetOrientation = getConnectorOffsetOrientation(getModelElement());
 		double inset = getDimensions().getWidth() / 2;
 		return offsetOrientation.getOffset() - inset;
 	}
@@ -101,7 +111,7 @@ public abstract class LayoutedCircularContentAnchorageVisualBase
 	@Override
 	public Side getSide() {
 		// TODO (#3868): Remove null check.
-		OffsetOrientation offsetOrientation = getConnectorOffsetOrientation(getLayoutedModelElement());
+		OffsetOrientation offsetOrientation = getConnectorOffsetOrientation(getModelElement());
 		EOrientation orientation = EOrientation.NORTH;
 		if(offsetOrientation != null) {
 			orientation = offsetOrientation.getOrientation();
@@ -139,11 +149,4 @@ public abstract class LayoutedCircularContentAnchorageVisualBase
 		}
 		return super.getInteractionColor();
 	}
-
-	/** Return the {@link ILayoutedModelElement}. */
-	// TODO(#3877): Implement an equivalent, but generic method in a common base class.
-	private ILayoutedModelElement getLayoutedModelElement() {
-		// Safe wild cast due to type check in constructor
-		return (ILayoutedModelElement)getModel();
-	}
 }
diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visuals/LayoutedCircularDiagramAnchorageVisualBase.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/LayoutedCircularAnchorageDiagramVisualBase.java
similarity index 78%
rename from org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visuals/LayoutedCircularDiagramAnchorageVisualBase.java
rename to org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/LayoutedCircularAnchorageDiagramVisualBase.java
index c5cc5fb41777166bc169011324585e51acda04c3..f06e3b908020408e3cd268a3c63edcd75ef74f8b 100644
--- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visuals/LayoutedCircularDiagramAnchorageVisualBase.java
+++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/LayoutedCircularAnchorageDiagramVisualBase.java
@@ -13,14 +13,14 @@
 | See the License for the specific language governing permissions and      |
 | limitations under the License.                                           |
 +--------------------------------------------------------------------------*/
-package org.fortiss.tooling.base.ui.editor.fx.visuals;
+package org.fortiss.tooling.base.ui.editor.fx.visual;
 
 import static javafx.scene.paint.Color.BLACK;
 import static javafx.scene.paint.Color.rgb;
 import static org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.DiagramViewerDefaultTags.LINK_TARGET_ALLOWED_TAG;
 import static org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.DiagramViewerDefaultTags.LINK_TARGET_DENIED_TAG;
-import static org.fortiss.tooling.base.ui.editor.fx.visuals.CoordinateCorrections.ANCHOR_DIMENSION;
-import static org.fortiss.tooling.base.ui.editor.fx.visuals.CoordinateCorrections.ANCHOR_INSET;
+import static org.fortiss.tooling.base.ui.editor.fx.visual.CoordinateCorrections.ANCHOR_DIMENSION;
+import static org.fortiss.tooling.base.ui.editor.fx.visual.CoordinateCorrections.ANCHOR_INSET;
 import static org.fortiss.tooling.base.utils.LayoutDataUtils.getNodePosition;
 
 import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.IDiagramAnchorageMVCBundle;
@@ -39,26 +39,35 @@ import javafx.scene.paint.Paint;
  * 
  * @author munaro
  */
-public abstract class LayoutedCircularDiagramAnchorageVisualBase
+public abstract class LayoutedCircularAnchorageDiagramVisualBase<T extends ILayoutedModelElement>
 		extends CircularDiagramAnchorageVisualBase {
 
 	/** Constructor. */
-	public LayoutedCircularDiagramAnchorageVisualBase(
-			IDiagramAnchorageMVCBundle mvcb) {
+	public LayoutedCircularAnchorageDiagramVisualBase(IDiagramAnchorageMVCBundle mvcb,
+			Class<T> modelType) {
 		super(mvcb);
+
 		// TODO(#3877): Move type checks to a common base class.
 		Object model = mvcb.getModel();
-		if(!(model instanceof ILayoutedModelElement)) {
-			throw new IllegalArgumentException(
-					"Expected model of type ILayoutedModelElement, but was " +
-							model.getClass().getSimpleName());
+		if(model == null) {
+			throw new IllegalArgumentException("The given model is null!");
+		}
+		if(!modelType.isAssignableFrom(model.getClass())) {
+			throw new IllegalArgumentException("Expected model of type " +
+					modelType.getSimpleName() + ", but was " + model.getClass().getSimpleName());
 		}
 	}
 
+	/** Returns the wrapped model as the expected type. */
+	@SuppressWarnings("unchecked")
+	protected T getModelElement() {
+		return (T)getModel();
+	}
+
 	/** {@inheritDoc} */
 	@Override
 	public Rectangle2D getModelBounds() {
-		Point p = getNodePosition(getLayoutedModelElement());
+		Point p = getNodePosition(getModelElement());
 		Dimension2D dim = getDimensions();
 		return new Rectangle2D(p.getX(), p.getY(), dim.getWidth(), dim.getHeight());
 	}
@@ -105,11 +114,4 @@ public abstract class LayoutedCircularDiagramAnchorageVisualBase
 		}
 		return super.getInteractionColor();
 	}
-
-	/** Return the {@link ILayoutedModelElement}. */
-	// TODO(#3877): Move type checks to a common base class.
-	private ILayoutedModelElement getLayoutedModelElement() {
-		// Safe wild cast due to type check in constructor
-		return (ILayoutedModelElement)getModel();
-	}
 }
diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visuals/LayoutedLineLinkVisualBase.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/LayoutedLineLinkVisual.java
similarity index 78%
rename from org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visuals/LayoutedLineLinkVisualBase.java
rename to org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/LayoutedLineLinkVisual.java
index 429483c1222a26345fbc3bf5c9b2dbe41c6ad5f1..feea85e0bd288590fbe06c152a8a8b138ea85ca2 100644
--- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visuals/LayoutedLineLinkVisualBase.java
+++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/LayoutedLineLinkVisual.java
@@ -13,7 +13,7 @@
 | See the License for the specific language governing permissions and      |
 | limitations under the License.                                           |
 +--------------------------------------------------------------------------*/
-package org.fortiss.tooling.base.ui.editor.fx.visuals;
+package org.fortiss.tooling.base.ui.editor.fx.visual;
 
 import static java.util.Collections.emptyList;
 import static org.fortiss.tooling.base.ui.utils.LWFXEditorUtils.computeLinkToCircleLocation;
@@ -36,20 +36,33 @@ import javafx.geometry.Rectangle2D;
  * 
  * @author munaro
  */
-public abstract class LayoutedLineLinkVisualBase extends LineLinkVisualBase {
+// TODO (TM): As this class already requires the generic type to implement INamedElement
+// NamedLayoutedLineLinkVisual becomes useless. Remove INamedElement here and make class
+// abstract (consistent with the other Layouted*VisualBase classes)
+public abstract class LayoutedLineLinkVisual<T extends ILayoutedModelElement>
+		extends LineLinkVisualBase {
 
 	/** Constructor. */
-	public LayoutedLineLinkVisualBase(ILinkMVCBundle mvcb) {
+	public LayoutedLineLinkVisual(ILinkMVCBundle mvcb, Class<T> modelType) {
 		super(mvcb);
+
 		// TODO(#3877): Move type checks to a common base class.
 		Object model = mvcb.getModel();
-		if(!(model instanceof ILayoutedModelElement)) {
-			throw new IllegalArgumentException(
-					"Expected model of type ILayoutedModelElement, but was " +
-							model.getClass().getSimpleName());
+		if(model == null) {
+			throw new IllegalArgumentException("The given model is null!");
+		}
+		if(!modelType.isAssignableFrom(model.getClass())) {
+			throw new IllegalArgumentException("Expected model of type " +
+					modelType.getSimpleName() + ", but was " + model.getClass().getSimpleName());
 		}
 	}
 
+	/** Returns the model element with the expected type. */
+	@SuppressWarnings("unchecked")
+	protected T getModelElement() {
+		return (T)getModel();
+	}
+
 	/** {@inheritDoc} */
 	@Override
 	public DiagramCoordinate getBendPointLocation(int bpIndex) {
@@ -85,7 +98,7 @@ public abstract class LayoutedLineLinkVisualBase extends LineLinkVisualBase {
 
 	/** Returns the list of bend-points. */
 	private List<Point> getBendPointList() {
-		Points connectionPoints = getConnectionPoints(getLayoutedModelElement());
+		Points connectionPoints = getConnectionPoints(getModelElement());
 		if(connectionPoints == null) {
 			return emptyList();
 		}
@@ -107,11 +120,4 @@ public abstract class LayoutedLineLinkVisualBase extends LineLinkVisualBase {
 	protected double getInvisibleSelectionLineWidth() {
 		return 3;
 	}
-
-	/** Return the {@link ILayoutedModelElement}. */
-	// TODO(#3877): Move type checks to a common base class.
-	private ILayoutedModelElement getLayoutedModelElement() {
-		// Safe wild cast due to type check in constructor
-		return (ILayoutedModelElement)getModel();
-	}
 }
diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visuals/LayoutedRectangularContentVisualBase.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/LayoutedRectangularContentVisualBase.java
similarity index 83%
rename from org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visuals/LayoutedRectangularContentVisualBase.java
rename to org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/LayoutedRectangularContentVisualBase.java
index d4cd07a8056df99927b160f2d4ce1cf4778d1dfa..c2a3937b99284713e0bbcd3ce458874567b25ac5 100644
--- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visuals/LayoutedRectangularContentVisualBase.java
+++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/LayoutedRectangularContentVisualBase.java
@@ -13,10 +13,10 @@
 | See the License for the specific language governing permissions and      |
 | limitations under the License.                                           |
 +--------------------------------------------------------------------------*/
-package org.fortiss.tooling.base.ui.editor.fx.visuals;
+package org.fortiss.tooling.base.ui.editor.fx.visual;
 
 import static java.lang.Math.min;
-import static org.fortiss.tooling.base.ui.editor.fx.visuals.CoordinateCorrections.RECTANGLE_INSETS;
+import static org.fortiss.tooling.base.ui.editor.fx.visual.CoordinateCorrections.RECTANGLE_INSETS;
 import static org.fortiss.tooling.base.utils.LayoutDataUtils.getNodeBounds;
 
 import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.DiagramCoordinate;
@@ -39,24 +39,36 @@ import javafx.geometry.Side;
  * 
  * @author munaro
  */
-public abstract class LayoutedRectangularContentVisualBase extends RectangularContentVisualBase {
+public abstract class LayoutedRectangularContentVisualBase<T extends ILayoutedModelElement>
+		extends RectangularContentVisualBase {
 
 	/** Constructor. */
-	public LayoutedRectangularContentVisualBase(IContentMVCBundle mvcb) {
+	public LayoutedRectangularContentVisualBase(IContentMVCBundle mvcb, Class<T> modelType) {
 		super(mvcb);
+
 		// TODO(#3877): Move type checks to a common base class.
 		Object model = mvcb.getModel();
-		if(!(model instanceof ILayoutedModelElement)) {
-			throw new IllegalArgumentException(
-					"Expected model of type ILayoutedModelElement, but was " +
-							model.getClass().getSimpleName());
+		if(model == null) {
+			throw new IllegalArgumentException("The given model is null!");
+		}
+		if(!modelType.isAssignableFrom(model.getClass())) {
+			throw new IllegalArgumentException("Expected model of type " +
+					modelType.getSimpleName() + ", but was " + model.getClass().getSimpleName());
 		}
 	}
 
+	/** Returns the model element with the specified type. */
+	// TODO(#3877): Move type checks to a common base class.
+	@SuppressWarnings("unchecked")
+	protected T getModelElement() {
+		// Safe wild cast due to type check in constructor
+		return (T)getModel();
+	}
+
 	/** {@inheritDoc} */
 	@Override
 	public Rectangle2D getModelBounds() {
-		Rectangle rectangle = getNodeBounds(getLayoutedModelElement());
+		Rectangle rectangle = getNodeBounds(getModelElement());
 		double insetRadius = RECTANGLE_INSETS.getWidth();
 		double insetDiameter = insetRadius * 2;
 		return new Rectangle2D(rectangle.getX() + insetRadius, rectangle.getY() + insetRadius,
@@ -102,11 +114,4 @@ public abstract class LayoutedRectangularContentVisualBase extends RectangularCo
 	protected boolean requireSelectionForResizeGesture() {
 		return false;
 	}
-
-	/** Return the {@link ILayoutedModelElement}. */
-	// TODO(#3877): Move type checks to a common base class.
-	private ILayoutedModelElement getLayoutedModelElement() {
-		// Safe wild cast due to type check in constructor
-		return (ILayoutedModelElement)getModel();
-	}
 }
diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/NamedLayoutedCircularAnchorageContentVisual.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/NamedLayoutedCircularAnchorageContentVisual.java
new file mode 100644
index 0000000000000000000000000000000000000000..c680002469ce897679fa5a3f4af51d1b19cb53d6
--- /dev/null
+++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/NamedLayoutedCircularAnchorageContentVisual.java
@@ -0,0 +1,43 @@
+/*-------------------------------------------------------------------------+
+| Copyright 2019 fortiss GmbH                                              |
+|                                                                          |
+| Licensed under the Apache License, Version 2.0 (the "License");          |
+| you may not use this file except in compliance with the License.         |
+| You may obtain a copy of the License at                                  |
+|                                                                          |
+|    http://www.apache.org/licenses/LICENSE-2.0                            |
+|                                                                          |
+| Unless required by applicable law or agreed to in writing, software      |
+| distributed under the License is distributed on an "AS IS" BASIS,        |
+| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
+| See the License for the specific language governing permissions and      |
+| limitations under the License.                                           |
++--------------------------------------------------------------------------*/
+package org.fortiss.tooling.base.ui.editor.fx.visual;
+
+import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.IContentAnchorageMVCBundle;
+import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.visual.IVisual;
+import org.fortiss.tooling.base.model.element.IConnector;
+import org.fortiss.tooling.base.model.layout.ILayoutedModelElement;
+import org.fortiss.tooling.kernel.model.INamedElement;
+
+/**
+ * {@link IVisual} for layouted and named {@link IConnector}s of some content element within a
+ * diagram (sticky connectors).
+ * 
+ * @author diewald
+ */
+public class NamedLayoutedCircularAnchorageContentVisual<T extends ILayoutedModelElement & INamedElement>
+		extends LayoutedCircularAnchorageContentVisualBase<T> {
+
+	/** Constructor. */
+	public NamedLayoutedCircularAnchorageContentVisual(IContentAnchorageMVCBundle mvcb, Class<T> modelType) {
+		super(mvcb, modelType);
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	protected String getHoverText() {
+		return getModelElement().getName();
+	}
+}
diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/NamedLayoutedCircularAnchorageDiagramVisual.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/NamedLayoutedCircularAnchorageDiagramVisual.java
new file mode 100644
index 0000000000000000000000000000000000000000..714a176a0569a2049efb4009f710ca66bf3a57fb
--- /dev/null
+++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/NamedLayoutedCircularAnchorageDiagramVisual.java
@@ -0,0 +1,42 @@
+/*-------------------------------------------------------------------------+
+| Copyright 2019 fortiss GmbH                                              |
+|                                                                          |
+| Licensed under the Apache License, Version 2.0 (the "License");          |
+| you may not use this file except in compliance with the License.         |
+| You may obtain a copy of the License at                                  |
+|                                                                          |
+|    http://www.apache.org/licenses/LICENSE-2.0                            |
+|                                                                          |
+| Unless required by applicable law or agreed to in writing, software      |
+| distributed under the License is distributed on an "AS IS" BASIS,        |
+| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
+| See the License for the specific language governing permissions and      |
+| limitations under the License.                                           |
++--------------------------------------------------------------------------*/
+package org.fortiss.tooling.base.ui.editor.fx.visual;
+
+import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.IDiagramAnchorageMVCBundle;
+import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.visual.IVisual;
+import org.fortiss.tooling.base.model.element.IConnector;
+import org.fortiss.tooling.base.model.layout.ILayoutedModelElement;
+import org.fortiss.tooling.kernel.model.INamedElement;
+
+/**
+ * {@link IVisual} for layouted and named {@link IConnector}s within a diagram (free connectors).
+ * 
+ * @author diewald
+ */
+public class NamedLayoutedCircularAnchorageDiagramVisual<T extends ILayoutedModelElement & INamedElement>
+		extends LayoutedCircularAnchorageDiagramVisualBase<T> {
+
+	/** Constructor. */
+	public NamedLayoutedCircularAnchorageDiagramVisual(IDiagramAnchorageMVCBundle mvcb, Class<T> modelType) {
+		super(mvcb, modelType);
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	protected String getHoverText() {
+		return getModelElement().getName();
+	}
+}
diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/NamedLayoutedLineLinkVisual.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/NamedLayoutedLineLinkVisual.java
new file mode 100644
index 0000000000000000000000000000000000000000..e66e5b2aaa40fe8b22a292e175bb8f3af4539b9d
--- /dev/null
+++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/NamedLayoutedLineLinkVisual.java
@@ -0,0 +1,47 @@
+/*-------------------------------------------------------------------------+
+| Copyright 2019 fortiss GmbH                                              |
+|                                                                          |
+| Licensed under the Apache License, Version 2.0 (the "License");          |
+| you may not use this file except in compliance with the License.         |
+| You may obtain a copy of the License at                                  |
+|                                                                          |
+|    http://www.apache.org/licenses/LICENSE-2.0                            |
+|                                                                          |
+| Unless required by applicable law or agreed to in writing, software      |
+| distributed under the License is distributed on an "AS IS" BASIS,        |
+| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
+| See the License for the specific language governing permissions and      |
+| limitations under the License.                                           |
++--------------------------------------------------------------------------*/
+package org.fortiss.tooling.base.ui.editor.fx.visual;
+
+import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.ILinkMVCBundle;
+import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.visual.IVisual;
+import org.fortiss.tooling.base.model.element.IConnection;
+import org.fortiss.tooling.base.model.layout.ILayoutedModelElement;
+import org.fortiss.tooling.kernel.model.INamedElement;
+
+/**
+ * {@link IVisual} for layouted and named links within a diagram. Typically, those are
+ * {@link IConnection}s.
+ * 
+ * @author diewald
+ */
+// TODO (TM): See comment in LayoutedLineLinkVisual
+public class NamedLayoutedLineLinkVisual<T extends INamedElement & ILayoutedModelElement>
+		extends LayoutedLineLinkVisual<T> {
+
+	/** Constructor. */
+	public NamedLayoutedLineLinkVisual(ILinkMVCBundle mvcb, Class<T> modelType) {
+		super(mvcb, modelType);
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	protected String getLabelText(int currentSegment, int lastSegment) {
+		if(currentSegment == 0) {
+			return getModelElement().getName();
+		}
+		return null;
+	}
+}
diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/NamedLayoutedRectangularContentVisual.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/NamedLayoutedRectangularContentVisual.java
new file mode 100644
index 0000000000000000000000000000000000000000..122e193ac587857d1dad23b42583a0bcf465f0d0
--- /dev/null
+++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/NamedLayoutedRectangularContentVisual.java
@@ -0,0 +1,40 @@
+/*-------------------------------------------------------------------------+
+| Copyright 2019 fortiss GmbH                                              |
+|                                                                          |
+| Licensed under the Apache License, Version 2.0 (the "License");          |
+| you may not use this file except in compliance with the License.         |
+| You may obtain a copy of the License at                                  |
+|                                                                          |
+|    http://www.apache.org/licenses/LICENSE-2.0                            |
+|                                                                          |
+| Unless required by applicable law or agreed to in writing, software      |
+| distributed under the License is distributed on an "AS IS" BASIS,        |
+| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
+| See the License for the specific language governing permissions and      |
+| limitations under the License.                                           |
++--------------------------------------------------------------------------*/
+package org.fortiss.tooling.base.ui.editor.fx.visual;
+
+import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.IContentMVCBundle;
+import org.fortiss.tooling.base.model.layout.ILayoutedModelElement;
+import org.fortiss.tooling.kernel.model.INamedElement;
+
+/**
+ * {@link LayoutedRectangularContentVisualBase} that defines its name.
+ * 
+ * @author diewald
+ */
+public class NamedLayoutedRectangularContentVisual<T extends INamedElement & ILayoutedModelElement>
+		extends LayoutedRectangularContentVisualBase<T> {
+
+	/** Constructor. */
+	public NamedLayoutedRectangularContentVisual(IContentMVCBundle mvcb, Class<T> modelType) {
+		super(mvcb, modelType);
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	protected String getName() {
+		return getModelElement().getName();
+	}
+}
diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visuals/.ratings b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visuals/.ratings
deleted file mode 100644
index 22e27e4c1bc1b40ffc645ab0ee36503bb4188ce5..0000000000000000000000000000000000000000
--- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visuals/.ratings
+++ /dev/null
@@ -1,5 +0,0 @@
-CoordinateCorrections.java f78a936ba49c5fc4daf29237ecb4e86a446316d4 GREEN
-LayoutedCircularContentAnchorageVisualBase.java aa546c0c9d975972a33cf22682b5d6634e56d271 GREEN
-LayoutedCircularDiagramAnchorageVisualBase.java c5cc5fb41777166bc169011324585e51acda04c3 GREEN
-LayoutedLineLinkVisualBase.java 429483c1222a26345fbc3bf5c9b2dbe41c6ad5f1 GREEN
-LayoutedRectangularContentVisualBase.java d4cd07a8056df99927b160f2d4ce1cf4778d1dfa GREEN
diff --git a/org.fortiss.tooling.base/src/org/fortiss/tooling/base/migration/.ratings b/org.fortiss.tooling.base/src/org/fortiss/tooling/base/migration/.ratings
index 5633daf969db8251bbf77fd7418a1c19bf30868a..9d0d7f8df1b322b3005d555d7552e4aa62d05156 100644
--- a/org.fortiss.tooling.base/src/org/fortiss/tooling/base/migration/.ratings
+++ b/org.fortiss.tooling.base/src/org/fortiss/tooling/base/migration/.ratings
@@ -1,3 +1,3 @@
-AddMissingAnnotationsMigrationProvider.java a3f2b3cbcd39f85e15bc998650f899f55d9f563e GREEN
-RemoveDuplicatedAnnotationsMigrationProvider.java f1bdb4733d5b9c6003a2b7fee59b89240a0a3b61 GREEN
-RemoveOutdatedAnnotationInstanceMigrationProvider.java 29c29f2bb7515cad1de45a30ffc185001b47a016 GREEN
+AddMissingAnnotationsMigrationProvider.java ebc5b9348b61ffb23493942949ecccf1c1fa2ae1 GREEN
+RemoveDuplicatedAnnotationsMigrationProvider.java 6920909f8f211b9c5b5990644b5abcd8c4abaa3a GREEN
+RemoveOutdatedAnnotationInstanceMigrationProvider.java 245530d6026f9ff29ffc577983d9de03ae5e75e5 GREEN
diff --git a/org.fortiss.tooling.base/src/org/fortiss/tooling/base/migration/AddMissingAnnotationsMigrationProvider.java b/org.fortiss.tooling.base/src/org/fortiss/tooling/base/migration/AddMissingAnnotationsMigrationProvider.java
index a3f2b3cbcd39f85e15bc998650f899f55d9f563e..ebc5b9348b61ffb23493942949ecccf1c1fa2ae1 100644
--- a/org.fortiss.tooling.base/src/org/fortiss/tooling/base/migration/AddMissingAnnotationsMigrationProvider.java
+++ b/org.fortiss.tooling.base/src/org/fortiss/tooling/base/migration/AddMissingAnnotationsMigrationProvider.java
@@ -15,6 +15,7 @@
 +--------------------------------------------------------------------------*/
 package org.fortiss.tooling.base.migration;
 
+import static java.util.Collections.emptyMap;
 import static org.fortiss.tooling.base.utils.AnnotationUtils.instantiateAnnotationsRecursive;
 
 import java.util.ArrayList;
@@ -49,9 +50,11 @@ public class AddMissingAnnotationsMigrationProvider implements IMigrationProvide
 
 	/** {@inheritDoc} */
 	@Override
-	public void migrate(ITopLevelElement modelElement, Map<EObject, AnyType> unknownFeatures) {
+	public Map<EObject, AnyType> migrate(ITopLevelElement modelElement,
+			Map<EObject, AnyType> unknownFeatures) {
 		EObject rootElement = modelElement.getRootModelElement();
 		instantiateAnnotationsRecursive(rootElement);
 		migratedProjects.add(modelElement);
+		return emptyMap();
 	}
 }
diff --git a/org.fortiss.tooling.base/src/org/fortiss/tooling/base/migration/RemoveDuplicatedAnnotationsMigrationProvider.java b/org.fortiss.tooling.base/src/org/fortiss/tooling/base/migration/RemoveDuplicatedAnnotationsMigrationProvider.java
index f1bdb4733d5b9c6003a2b7fee59b89240a0a3b61..6920909f8f211b9c5b5990644b5abcd8c4abaa3a 100644
--- a/org.fortiss.tooling.base/src/org/fortiss/tooling/base/migration/RemoveDuplicatedAnnotationsMigrationProvider.java
+++ b/org.fortiss.tooling.base/src/org/fortiss/tooling/base/migration/RemoveDuplicatedAnnotationsMigrationProvider.java
@@ -15,6 +15,7 @@
 +--------------------------------------------------------------------------*/
 package org.fortiss.tooling.base.migration;
 
+import static java.util.Collections.emptyMap;
 import static org.fortiss.tooling.kernel.utils.EcoreUtils.getChildrenWithType;
 import static org.fortiss.tooling.kernel.utils.EcoreUtils.pickInstanceOf;
 import static org.fortiss.tooling.kernel.utils.LoggingUtils.error;
@@ -87,7 +88,8 @@ public class RemoveDuplicatedAnnotationsMigrationProvider implements IMigrationP
 
 	/** {@inheritDoc} */
 	@Override
-	public void migrate(ITopLevelElement topLevelElement, Map<EObject, AnyType> unknownFeatures) {
+	public Map<EObject, AnyType> migrate(ITopLevelElement topLevelElement,
+			Map<EObject, AnyType> unknownFeatures) {
 
 		doInternal(topLevelElement, true);
 
@@ -95,5 +97,6 @@ public class RemoveDuplicatedAnnotationsMigrationProvider implements IMigrationP
 		error(ToolingBaseActivator.getDefault(),
 				"Duplicate annotations have been removed from \"" + uri.lastSegment() +
 						"\". Please report this incident since it indicates an internal problem.");
+		return emptyMap();
 	}
 }
diff --git a/org.fortiss.tooling.base/src/org/fortiss/tooling/base/migration/RemoveOutdatedAnnotationInstanceMigrationProvider.java b/org.fortiss.tooling.base/src/org/fortiss/tooling/base/migration/RemoveOutdatedAnnotationInstanceMigrationProvider.java
index 29c29f2bb7515cad1de45a30ffc185001b47a016..245530d6026f9ff29ffc577983d9de03ae5e75e5 100644
--- a/org.fortiss.tooling.base/src/org/fortiss/tooling/base/migration/RemoveOutdatedAnnotationInstanceMigrationProvider.java
+++ b/org.fortiss.tooling.base/src/org/fortiss/tooling/base/migration/RemoveOutdatedAnnotationInstanceMigrationProvider.java
@@ -15,6 +15,7 @@
 +--------------------------------------------------------------------------*/
 package org.fortiss.tooling.base.migration;
 
+import static java.util.Collections.emptyMap;
 import static org.eclipse.emf.ecore.util.EcoreUtil.delete;
 import static org.fortiss.tooling.common.util.LambdaUtils.isAssignableFromAny;
 import static org.fortiss.tooling.kernel.utils.EcoreUtils.getChildrenWithType;
@@ -67,12 +68,14 @@ public abstract class RemoveOutdatedAnnotationInstanceMigrationProvider<T extend
 
 	/** {@inheritDoc} */
 	@Override
-	public void migrate(ITopLevelElement modelElement, Map<EObject, AnyType> unknownFeatures) {
+	public Map<EObject, AnyType> migrate(ITopLevelElement modelElement,
+			Map<EObject, AnyType> unknownFeatures) {
 		EObject rootModelElement = modelElement.getRootModelElement();
 		for(T annotation : getChildrenWithType(rootModelElement, annotationType)) {
 			if(!isAssignableFromAny(modelElementTypes, annotation.getSpecificationOf())) {
 				delete(annotation);
 			}
 		}
+		return emptyMap();
 	}
 }
diff --git a/org.fortiss.tooling.common.ui/.classpath b/org.fortiss.tooling.common.ui/.classpath
index cb4939f8345486a25a29b4f18626b12cc24eae60..d9ed18f5cea4deb235213896eef764feded19dee 100644
--- a/org.fortiss.tooling.common.ui/.classpath
+++ b/org.fortiss.tooling.common.ui/.classpath
@@ -3,8 +3,8 @@
 	<classpathentry kind="src" path="src"/>
 	<classpathentry kind="src" path="external-src"/>
 	<classpathentry kind="src" path="res"/>
-	<classpathentry exported="true" kind="lib" path="lib/org.eclipse.systemfocus.kernel.common_0.0.5.20191213.jar"/>
-	<classpathentry exported="true" kind="lib" path="lib/org.eclipse.systemfocus.kernel.common.ui_0.0.5.20191213.jar"/>
+	<classpathentry exported="true" kind="lib" path="lib/org.eclipse.systemfocus.kernel.common_0.0.5.20191219.jar"/>
+	<classpathentry exported="true" kind="lib" path="lib/org.eclipse.systemfocus.kernel.common.ui_0.0.5.20191219.jar"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
 		<attributes>
 			<attribute name="module" value="true"/>
diff --git a/org.fortiss.tooling.common.ui/META-INF/MANIFEST.MF b/org.fortiss.tooling.common.ui/META-INF/MANIFEST.MF
index 1898771c2202bd22a084d201e92eafb0f18d3b02..f158eb873beefe27aacb70e4e70c12c3efcf333b 100644
--- a/org.fortiss.tooling.common.ui/META-INF/MANIFEST.MF
+++ b/org.fortiss.tooling.common.ui/META-INF/MANIFEST.MF
@@ -25,8 +25,8 @@ Bundle-ClassPath: .,
  lib/org.conqat.ide.commons.gef.jar,
  lib/org.conqat.ide.commons.ui.jar,
  lib/swt-grouplayout.jar,
- lib/org.eclipse.systemfocus.kernel.common_0.0.5.20191213.jar,
- lib/org.eclipse.systemfocus.kernel.common.ui_0.0.5.20191213.jar
+ lib/org.eclipse.systemfocus.kernel.common_0.0.5.20191219.jar,
+ lib/org.eclipse.systemfocus.kernel.common.ui_0.0.5.20191219.jar
 Export-Package: aerofx,
  aquafx,
  jfxtras,
diff --git a/org.fortiss.tooling.common.ui/build.properties b/org.fortiss.tooling.common.ui/build.properties
index e4293a8077ba272c17cde3f615f0c17be7389027..047e606ce9d79664f75aab85d5fb16ee0ae09b08 100644
--- a/org.fortiss.tooling.common.ui/build.properties
+++ b/org.fortiss.tooling.common.ui/build.properties
@@ -6,8 +6,8 @@ bin.includes = .,\
                lib/org.conqat.ide.commons.ui.jar,\
                lib/swt-grouplayout.jar,\
                res/,\
-               lib/org.eclipse.systemfocus.kernel.common_0.0.5.20191213.jar,\
-               lib/org.eclipse.systemfocus.kernel.common.ui_0.0.5.20191213.jar
+               lib/org.eclipse.systemfocus.kernel.common_0.0.5.20191219.jar,\
+               lib/org.eclipse.systemfocus.kernel.common.ui_0.0.5.20191219.jar
 jars.compile.order = .
 source.. = src/,\
            res/,\
diff --git a/org.fortiss.tooling.common.ui/lib/org.eclipse.systemfocus.kernel.common.ui_0.0.5.20191213.jar b/org.fortiss.tooling.common.ui/lib/org.eclipse.systemfocus.kernel.common.ui_0.0.5.20191213.jar
deleted file mode 100644
index fb24b39f087a12b919462f58014ae5cc13d42a41..0000000000000000000000000000000000000000
Binary files a/org.fortiss.tooling.common.ui/lib/org.eclipse.systemfocus.kernel.common.ui_0.0.5.20191213.jar and /dev/null differ
diff --git a/org.fortiss.tooling.common.ui/lib/org.eclipse.systemfocus.kernel.common.ui_0.0.5.20191219.jar b/org.fortiss.tooling.common.ui/lib/org.eclipse.systemfocus.kernel.common.ui_0.0.5.20191219.jar
new file mode 100644
index 0000000000000000000000000000000000000000..395895b74e4f88edcd5118c917fd2ab6b413e057
Binary files /dev/null and b/org.fortiss.tooling.common.ui/lib/org.eclipse.systemfocus.kernel.common.ui_0.0.5.20191219.jar differ
diff --git a/org.fortiss.tooling.common.ui/lib/org.eclipse.systemfocus.kernel.common_0.0.5.20191213.jar b/org.fortiss.tooling.common.ui/lib/org.eclipse.systemfocus.kernel.common_0.0.5.20191219.jar
similarity index 80%
rename from org.fortiss.tooling.common.ui/lib/org.eclipse.systemfocus.kernel.common_0.0.5.20191213.jar
rename to org.fortiss.tooling.common.ui/lib/org.eclipse.systemfocus.kernel.common_0.0.5.20191219.jar
index a7d80f27a40d52955285adc3b5a211581b4e93e7..b27db9f8c0e0c56fd798ea2b54927bc768b5ce64 100644
Binary files a/org.fortiss.tooling.common.ui/lib/org.eclipse.systemfocus.kernel.common_0.0.5.20191213.jar and b/org.fortiss.tooling.common.ui/lib/org.eclipse.systemfocus.kernel.common_0.0.5.20191219.jar differ
diff --git a/org.fortiss.tooling.kernel.ui/META-INF/MANIFEST.MF b/org.fortiss.tooling.kernel.ui/META-INF/MANIFEST.MF
index 881846afa276a61c6c3c08ca4e481866234ae095..ca6401da3143db4f507bbbef21b47a85dddd61e1 100644
--- a/org.fortiss.tooling.kernel.ui/META-INF/MANIFEST.MF
+++ b/org.fortiss.tooling.kernel.ui/META-INF/MANIFEST.MF
@@ -4,11 +4,12 @@ Bundle-Name: Tooling Kernel UI
 Bundle-SymbolicName: org.fortiss.tooling.kernel.ui;singleton:=true
 Bundle-Version: 2.16.0.qualifier
 Bundle-Activator: org.fortiss.tooling.kernel.ui.ToolingKernelUIActivator
-Require-Bundle: org.fortiss.tooling.common.ui;bundle-version="2.16.0";visibility:=reexport,
- org.fortiss.tooling.kernel;bundle-version="2.16.0";visibility:=reexport,
+Require-Bundle: org.fortiss.tooling.common.ui;visibility:=reexport,
+ org.fortiss.tooling.kernel;visibility:=reexport,
  org.eclipse.core.resources;visibility:=reexport,
  org.eclipse.emf.databinding;visibility:=reexport,
- org.eclipse.core.databinding.property;visibility:=reexport
+ org.eclipse.core.databinding.property;visibility:=reexport,
+ com.google.guava;visibility:=reexport
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: JavaSE-11
 Bundle-Vendor: fortiss GmbH
diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/.ratings b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/.ratings
index e4afd03ed7a246008939ddd4dfced2250a797efa..0f71fc3dd92acfc4197b5dc1400f09fe10e33967 100644
--- a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/.ratings
+++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/.ratings
@@ -4,7 +4,7 @@ IContextMenuContributor.java 0f09c76662c154cf52ddab61b417e82a42854162 GREEN
 IContextMenuMultiSelectionContributor.java 125b31dd38009bc2095b7e6bc860e946e39f58c4 GREEN
 IEditPartFactory.java 5729715847f553d95a5bad4a9211c7e6f458badd GREEN
 IModelEditor.java 962d7f7758abc88bbc6064c8b4eb32da00abf8e8 GREEN
-IModelEditorBinding.java a3d5c344f61fa6f12ab944a4e933a557d6e7011b GREEN
+IModelEditorBinding.java d6896569cfe7eb0d7f0b8e4a71573c50e8c75329 GREEN
 IModelElementHandler.java 21b4a96251e0267f156b4b8f2b95a97f6e81e646 GREEN
 ITutorialStepUI.java b8aee2b95857484ab6ad9ecd55b5de9f0ea158e5 GREEN
 ITutorialUIProvider.java aa0ff5db4d7ba0953e34edeb99f3e8279567e18f GREEN
diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/IModelEditorBinding.java b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/IModelEditorBinding.java
index a3d5c344f61fa6f12ab944a4e933a557d6e7011b..d6896569cfe7eb0d7f0b8e4a71573c50e8c75329 100644
--- a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/IModelEditorBinding.java
+++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/IModelEditorBinding.java
@@ -16,6 +16,9 @@
 package org.fortiss.tooling.kernel.ui.extension;
 
 import org.eclipse.emf.ecore.EObject;
+import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.controller.IControllerFactory;
+import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.model.IModelFactory;
+import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.visual.IVisualFactory;
 import org.eclipse.ui.IEditorPart;
 import org.fortiss.tooling.kernel.service.base.IEObjectAware;
 import org.fortiss.tooling.kernel.ui.service.IModelEditorBindingService;
@@ -24,12 +27,16 @@ import org.fortiss.tooling.kernel.ui.service.IModelEditorBindingService;
  * Interface for editor bindings. An editor binding a defines a model element
  * editor. Usually, an editor (in the Eclipse interpretation) is a view (in the
  * model-based development interpretation) on the underlying model.
- * 
- * <P>
+ * <p>
+ * This interface also specifies bindings to those MVC factories that are responsible for the
+ * interaction of the editor with the model, its presentation, and behavior.
+ * <p>
  * Each editor provided by some binding becomes part of an Eclipse multi-page editor. Its page
  * carries the name delivered by {@link #getLabel}. The {@link IModelEditorBindingService} sorts the
  * provided editors according to their priority returned by {@link #getPriority} with higher values
  * having lower priority.
+ * <b>NOTE:</b>: The priority reported by {@link #getPriority()} is also used to define the order in
+ * which the factories are traversed.
  * 
  * @see IModelEditorBindingService
  * 
@@ -40,6 +47,15 @@ public interface IModelEditorBinding<T extends EObject> extends IEObjectAware<EO
 	/** Returns the class of the editor registered by this binding. */
 	Class<? extends IEditorPart> getEditorClass(T object);
 
+	/** Returns the {@link IModelFactory} to instantiate for the {@link IEditorPart}. */
+	Class<? extends IModelFactory> getModelFactory();
+
+	/** Returns the {@link IVisualFactory} to instantiate for the {@link IEditorPart}. */
+	Class<? extends IVisualFactory> getVisualFactory();
+
+	/** Returns the {@link IControllerFactory} to instantiate for the {@link IEditorPart}. */
+	Class<? extends IControllerFactory> getControllerFactory();
+
 	/** Returns the label of the editor. */
 	String getLabel(T object);
 
diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/.ratings b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/.ratings
index 976ba3f728d9b735717c8a0d137b2c2c1da9e672..a7f01cec28ced8ee225518f34ad81234c4f6d8a3 100644
--- a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/.ratings
+++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/.ratings
@@ -7,8 +7,8 @@ EReferencePropertySectionBase.java 0548da6778516003257f59d0b4c2b60d458be3b6 GREE
 EditorBase.java 9c09fff92945256bb8680992ae7bb2c78f47b150 GREEN
 FXEditorBase.java 2e520be0bbae7d0aebdff70218a124dbe0896ce2 GREEN
 IListPropertySection.java 8bb00fe7959583e794ff9437b7a77404c9a9e70f GREEN
-LWFXEFEditorBase.java 0b8e6af85d83d0542dcd908974e52c618bc22a08 GREEN
-ModelEditorBindingBase.java 4c5ac569c0b6e7678fc8191096b26dfd09fdcb98 GREEN
+LWFXEFEditorBase.java 2bd06235f20c18dc2e7d433700b2ad74a16664e2 GREEN
+ModelEditorBindingBase.java c258cb0ea28d74440856cd2abf367408fbbc1279 GREEN
 ModelElementHandlerBase.java 384727748f125c9d43f19d9c0eba4ba1be5a7a26 GREEN
 MultiEObjectActionBase.java 9e237d8ea640c4194e4877af4a9cfce88698e543 GREEN
 NamedCommentedModelElementHandlerBase.java 681b98b50b362f01abb7a36f108f4f11b9e51829 GREEN
diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/LWFXEFEditorBase.java b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/LWFXEFEditorBase.java
index 0b8e6af85d83d0542dcd908974e52c618bc22a08..2bd06235f20c18dc2e7d433700b2ad74a16664e2 100644
--- a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/LWFXEFEditorBase.java
+++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/LWFXEFEditorBase.java
@@ -15,8 +15,11 @@
 +--------------------------------------------------------------------------*/
 package org.fortiss.tooling.kernel.ui.extension.base;
 
+import static java.util.stream.Collectors.toList;
+
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
 
 import org.eclipse.emf.ecore.EObject;
 import org.eclipse.jface.viewers.ISelection;
@@ -32,14 +35,21 @@ import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.controller.IContro
 import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.model.IModelFactory;
 import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.IMVCBundle;
 import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.visual.IVisualFactory;
+import org.eclipse.ui.IEditorPart;
 import org.fortiss.tooling.kernel.service.ICommandStackService;
+import org.fortiss.tooling.kernel.ui.extension.IModelEditorBinding;
+import org.fortiss.tooling.kernel.ui.extension.base.factory.DelegatingControllerFactory;
+import org.fortiss.tooling.kernel.ui.extension.base.factory.DelegatingModelFactory;
+import org.fortiss.tooling.kernel.ui.extension.base.factory.DelegatingVisualFactory;
+import org.fortiss.tooling.kernel.ui.service.IModelEditorBindingService;
 
 import javafx.scene.Parent;
 
 /**
- * Base implementation of model element editors which are using LWFXEF DiaViewer.
+ * Base class for JavaFX-based {@link IEditorPart}s that display diagrams of {@link EObject}s.
  * 
- * @author hoelzlf
+ * @author hoelzl
+ * @author diewald
  */
 public abstract class LWFXEFEditorBase<T extends EObject> extends FXEditorBase<T>
 		implements ISelectionProvider {
@@ -48,30 +58,55 @@ public abstract class LWFXEFEditorBase<T extends EObject> extends FXEditorBase<T
 	/** The list of {@link ISelectionChangedListener}s. */
 	private final List<ISelectionChangedListener> selectionListeners = new ArrayList<>();
 
+	/** References the delegating {@link IModelFactory} of this JavaFX {@link IEditorPart}. */
+	private IModelFactory delegatingModelFactory;
+
+	/** References the delegating {@link IModelFactory} of this JavaFX {@link IEditorPart}. */
+	private IVisualFactory delegatingVisualFactory;
+
+	/** References the delegating {@link IModelFactory} of this JavaFX {@link IEditorPart}. */
+	private IControllerFactory delegatingControllerFactory;
+
 	/** {@inheritDoc} */
 	@Override
 	protected final Parent createSceneRoot() {
-		viewer = new DiagramViewer(createModelFactory(), createVisualFactory(),
-				createControllerFactory(), cb -> modelSelected(), chg -> applyModelChange(chg));
+		constructMVCFactories();
+
+		viewer = new DiagramViewer(delegatingModelFactory, delegatingVisualFactory,
+				delegatingControllerFactory, cb -> modelSelected(), chg -> applyModelChange(chg));
 		customizeViewer();
 		getSite().setSelectionProvider(this);
 		return viewer.getVisualNode();
 	}
 
+	/**
+	 * Constructs delegating factories that wrap all factories registered by
+	 * {@link IModelEditorBinding}s for the edited type. Delegating factories are used for extending
+	 * editors of the same type.
+	 */
+	protected void constructMVCFactories() {
+		List<IModelEditorBinding<EObject>> bindings =
+				IModelEditorBindingService.getInstance().getBindings(editedObject);
+		bindings.removeIf(b -> (b.getEditorClass(editedObject) != null) &&
+				(!LWFXEFEditorBase.class.isAssignableFrom(b.getEditorClass(editedObject))));
+
+		List<Class<? extends IModelFactory>> modelFactories = bindings.stream()
+				.map(b -> b.getModelFactory()).filter(Objects::nonNull).collect(toList());
+		List<Class<? extends IVisualFactory>> visualFactories = bindings.stream()
+				.map(b -> b.getVisualFactory()).filter(Objects::nonNull).collect(toList());
+		List<Class<? extends IControllerFactory>> controllerFactories = bindings.stream()
+				.map(b -> b.getControllerFactory()).filter(Objects::nonNull).collect(toList());
+
+		delegatingModelFactory = new DelegatingModelFactory(modelFactories, editedObject);
+		delegatingVisualFactory = new DelegatingVisualFactory(visualFactories);
+		delegatingControllerFactory = new DelegatingControllerFactory(controllerFactories);
+	}
+
 	/** Customize the viewer after it is created. The default implementation changes nothing. */
 	protected void customizeViewer() {
 		// the default does nothing
 	}
 
-	/** Create the {@link IModelFactory}. */
-	protected abstract IModelFactory createModelFactory();
-
-	/** Create the {@link IVisualFactory}. */
-	protected abstract IVisualFactory createVisualFactory();
-
-	/** Create the {@link IControllerFactory}. */
-	protected abstract IControllerFactory createControllerFactory();
-
 	/** Called when a model element is selected in the diagram viewer. */
 	protected void modelSelected() {
 		getSite().getSelectionProvider().setSelection(createSelection());
diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/ModelEditorBindingBase.java b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/ModelEditorBindingBase.java
index 4c5ac569c0b6e7678fc8191096b26dfd09fdcb98..c258cb0ea28d74440856cd2abf367408fbbc1279 100644
--- a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/ModelEditorBindingBase.java
+++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/ModelEditorBindingBase.java
@@ -16,6 +16,9 @@
 package org.fortiss.tooling.kernel.ui.extension.base;
 
 import org.eclipse.emf.ecore.EObject;
+import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.controller.IControllerFactory;
+import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.model.IModelFactory;
+import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.visual.IVisualFactory;
 import org.fortiss.tooling.kernel.service.base.IEObjectAware;
 import org.fortiss.tooling.kernel.ui.extension.IModelEditorBinding;
 import org.fortiss.tooling.kernel.ui.service.IModelEditorBindingService;
@@ -34,6 +37,7 @@ import org.fortiss.tooling.kernel.ui.service.IModelEditorBindingService;
  * @see IModelEditorBindingService
  * 
  * @author hoelzl
+ * @author diewald
  */
 public abstract class ModelEditorBindingBase<T extends EObject>
 		implements IEObjectAware<EObject>, IModelEditorBinding<T> {
@@ -48,6 +52,30 @@ public abstract class ModelEditorBindingBase<T extends EObject>
 		return getEditorClass(null);
 	}
 
+	/** {@inheritDoc} */
+	@Override
+	public Class<? extends IModelFactory> getModelFactory() {
+		throw new UnsupportedOperationException("This method shall only be called from FX" +
+				" editors. Ensure to define the model factory in the editor binding. Remove" +
+				" this method when the ediors are migrated to JavaFX.");
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public Class<? extends IVisualFactory> getVisualFactory() {
+		throw new UnsupportedOperationException("This method shall only be called from FX" +
+				" editors. Ensure to define the visual factory in the editor binding. Remove" +
+				" this method when the ediors are migrated to JavaFX.");
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public Class<? extends IControllerFactory> getControllerFactory() {
+		throw new UnsupportedOperationException("This method shall only be called from FX" +
+				" editors. Ensure to define the controller factory in the editor binding. Remove" +
+				" this method when the ediors are migrated to JavaFX.");
+	}
+
 	/** Returns the label of editor */
 	@Override
 	public String getLabel(T object) {
diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/.ratings b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/.ratings
new file mode 100644
index 0000000000000000000000000000000000000000..75b475f75083ac3976a4740cc7fc19976f96542c
--- /dev/null
+++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/.ratings
@@ -0,0 +1,4 @@
+DelegatingControllerFactory.java ad214d83b5821b39862b7c382c91a13c3dfddbd0 GREEN
+DelegatingFactoryBase.java f421742267610f41bb6196346026d2f239d90ed0 GREEN
+DelegatingModelFactory.java 717b706781879efe9efcb5ce4bf53723e39a3e1b GREEN
+DelegatingVisualFactory.java 7e834acd12ae4d1c2b2b32a5456dc9f2b6d4e466 GREEN
diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/DelegatingControllerFactory.java b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/DelegatingControllerFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..ad214d83b5821b39862b7c382c91a13c3dfddbd0
--- /dev/null
+++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/DelegatingControllerFactory.java
@@ -0,0 +1,111 @@
+/*-------------------------------------------------------------------------+
+| Copyright 2019 fortiss GmbH                                              |
+|                                                                          |
+| Licensed under the Apache License, Version 2.0 (the "License");          |
+| you may not use this file except in compliance with the License.         |
+| You may obtain a copy of the License at                                  |
+|                                                                          |
+|    http://www.apache.org/licenses/LICENSE-2.0                            |
+|                                                                          |
+| Unless required by applicable law or agreed to in writing, software      |
+| distributed under the License is distributed on an "AS IS" BASIS,        |
+| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
+| See the License for the specific language governing permissions and      |
+| limitations under the License.                                           |
++--------------------------------------------------------------------------*/
+package org.fortiss.tooling.kernel.ui.extension.base.factory;
+
+import java.util.List;
+import java.util.Optional;
+
+import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.controller.IController;
+import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.controller.IControllerFactory;
+import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.IContentAnchorageMVCBundle;
+import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.IContentMVCBundle;
+import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.IDiagramAnchorageMVCBundle;
+import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.IDiagramMVCBundle;
+import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.ILinkMVCBundle;
+import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.IMVCBundle;
+
+/**
+ * Delegates the creational calls to concrete {@link IControllerFactory}s. The first non-null
+ * element returned by the factories of the initially given list is returned. If no element is
+ * created (all delegates returned null), this factory throws a {@link RuntimeException}.
+ * 
+ * @author hoelzl
+ * @author diewald
+ */
+public class DelegatingControllerFactory extends DelegatingFactoryBase<IControllerFactory>
+		implements IControllerFactory {
+
+	/** Constructor. */
+	public DelegatingControllerFactory(List<Class<? extends IControllerFactory>> factories) {
+		super(factories, null);
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public IController createContentController(IContentMVCBundle modelBundle) {
+		Optional<IController> controller =
+				getDelegateFactories().stream().map(f -> f.createContentController(modelBundle))
+						.filter(cc -> cc != null).findFirst();
+		if(controller.isPresent()) {
+			return controller.get();
+		}
+		throw createNoControllerException(modelBundle);
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public IController createDiagramAnchorageController(IDiagramAnchorageMVCBundle modelBundle) {
+		Optional<IController> controller = getDelegateFactories().stream()
+				.map(f -> f.createDiagramAnchorageController(modelBundle)).filter(cc -> cc != null)
+				.findFirst();
+		if(controller.isPresent()) {
+			return controller.get();
+		}
+		throw createNoControllerException(modelBundle);
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public IController createContentAnchorageController(IContentAnchorageMVCBundle modelBundle) {
+		Optional<IController> controller = getDelegateFactories().stream()
+				.map(f -> f.createContentAnchorageController(modelBundle)).filter(cc -> cc != null)
+				.findFirst();
+		if(controller.isPresent()) {
+			return controller.get();
+		}
+		throw createNoControllerException(modelBundle);
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public IController createLinkController(ILinkMVCBundle modelBundle) {
+		Optional<IController> controller = getDelegateFactories().stream()
+				.map(f -> f.createLinkController(modelBundle)).filter(cc -> cc != null).findFirst();
+		if(controller.isPresent()) {
+			return controller.get();
+		}
+		throw createNoControllerException(modelBundle);
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public IController createDiagramController(IDiagramMVCBundle diagramBundle) {
+		Optional<IController> controller = getDelegateFactories().stream().map(f -> {
+			return f.createDiagramController(diagramBundle);
+		}).filter(cc -> cc != null).findFirst();
+		if(controller.isPresent()) {
+			return controller.get();
+		}
+		throw createNoControllerException(diagramBundle);
+	}
+
+	/** Throws a runtime exception indicating a missing controller. */
+	private RuntimeException createNoControllerException(IMVCBundle modelBundle) {
+		return new RuntimeException("No controller has been specified for model elements of the" +
+				" type " + modelBundle.getModel().getClass().getSimpleName() + ". Please check" +
+				" the editor bindings and the delegate controllers.");
+	}
+}
diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/DelegatingFactoryBase.java b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/DelegatingFactoryBase.java
new file mode 100644
index 0000000000000000000000000000000000000000..f421742267610f41bb6196346026d2f239d90ed0
--- /dev/null
+++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/DelegatingFactoryBase.java
@@ -0,0 +1,79 @@
+/*-------------------------------------------------------------------------+
+| Copyright 2019 fortiss GmbH                                              |
+|                                                                          |
+| Licensed under the Apache License, Version 2.0 (the "License");          |
+| you may not use this file except in compliance with the License.         |
+| You may obtain a copy of the License at                                  |
+|                                                                          |
+|    http://www.apache.org/licenses/LICENSE-2.0                            |
+|                                                                          |
+| Unless required by applicable law or agreed to in writing, software      |
+| distributed under the License is distributed on an "AS IS" BASIS,        |
+| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
+| See the License for the specific language governing permissions and      |
+| limitations under the License.                                           |
++--------------------------------------------------------------------------*/
+package org.fortiss.tooling.kernel.ui.extension.base.factory;
+
+import static java.util.stream.Collectors.toList;
+import static org.apache.commons.lang3.reflect.ConstructorUtils.getMatchingAccessibleConstructor;
+import static org.fortiss.tooling.kernel.utils.LoggingUtils.error;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+import org.fortiss.tooling.kernel.ui.ToolingKernelUIActivator;
+
+import com.google.common.collect.ImmutableList;
+
+/**
+ * Base class for delegating MVC factories that wrap 1..n factories for editors of a defined type.
+ * 
+ * @author diewald
+ */
+/* package */ abstract class DelegatingFactoryBase<T> {
+
+	/** References the edited Object in case it is needed by some factory. May be {@code null}. */
+	protected final Object editedObject;
+
+	/** References the */
+	private List<T> delegateFactories = new ArrayList<>();
+
+	/** Constructor. */
+	protected DelegatingFactoryBase(List<Class<? extends T>> factories, Object editedObject) {
+		this.editedObject = editedObject;
+
+		delegateFactories = factories.stream().map(fCls -> constructFactory(fCls))
+				.flatMap(Optional::stream).collect(toList());
+	}
+
+	/** Creates an instance of the given {@code delegateFactory}. */
+	protected Optional<? extends T> constructFactory(Class<? extends T> delegateFactory) {
+		Constructor<? extends T> ctor = null;
+		try {
+			ctor = getMatchingAccessibleConstructor(delegateFactory);
+			try {
+				return Optional.of(ctor.newInstance());
+			} catch(InstantiationException | IllegalAccessException | IllegalArgumentException |
+					InvocationTargetException e) {
+				error(ToolingKernelUIActivator.getDefault(), "Failed to instantiate the factory " +
+						delegateFactory.getSimpleName() + ".");
+				return Optional.empty();
+			}
+		} catch(NullPointerException | SecurityException e1) {
+			error(ToolingKernelUIActivator.getDefault(), "The factory " +
+					delegateFactory.getSimpleName() +
+					" is missing a no-arg Constructor. Only such constructors are allowed for" +
+					" these factories.");
+			return Optional.empty();
+		}
+	}
+
+	/** Returns the list of delegate factory instances whose types are given during construction. */
+	protected ImmutableList<T> getDelegateFactories() {
+		return ImmutableList.copyOf(delegateFactories);
+	}
+}
diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/DelegatingModelFactory.java b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/DelegatingModelFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..717b706781879efe9efcb5ce4bf53723e39a3e1b
--- /dev/null
+++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/DelegatingModelFactory.java
@@ -0,0 +1,144 @@
+/*-------------------------------------------------------------------------+
+| Copyright 2019 fortiss GmbH                                              |
+|                                                                          |
+| Licensed under the Apache License, Version 2.0 (the "License");          |
+| you may not use this file except in compliance with the License.         |
+| You may obtain a copy of the License at                                  |
+|                                                                          |
+|    http://www.apache.org/licenses/LICENSE-2.0                            |
+|                                                                          |
+| Unless required by applicable law or agreed to in writing, software      |
+| distributed under the License is distributed on an "AS IS" BASIS,        |
+| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
+| See the License for the specific language governing permissions and      |
+| limitations under the License.                                           |
++--------------------------------------------------------------------------*/
+package org.fortiss.tooling.kernel.ui.extension.base.factory;
+
+import static java.util.stream.Collectors.toList;
+import static org.apache.commons.lang3.reflect.ConstructorUtils.getMatchingAccessibleConstructor;
+import static org.conqat.lib.commons.collections.CollectionUtils.isNullOrEmpty;
+import static org.fortiss.tooling.kernel.utils.EcoreUtils.getInterfaceType;
+import static org.fortiss.tooling.kernel.utils.LoggingUtils.error;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Collection;
+import java.util.List;
+import java.util.Optional;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.model.IModelFactory;
+import org.fortiss.tooling.kernel.ui.ToolingKernelUIActivator;
+
+/**
+ * Delegates the creational and getter calls to concrete {@link IModelFactory}s. The first non-null
+ * element returned by the factories of the initially given list is returned. If no element is
+ * created (all delegates returned null), this factory also returns null.
+ * <p>
+ * Only the root model must be identical for all delegate factories. Hence, the root element of the
+ * first delegate is returned.
+ * 
+ * @author hoelzl
+ */
+public class DelegatingModelFactory extends DelegatingFactoryBase<IModelFactory>
+		implements IModelFactory {
+
+	/** Constructor. */
+	public DelegatingModelFactory(List<Class<? extends IModelFactory>> factories,
+			Object editedObject) {
+		super(factories, editedObject);
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	protected Optional<? extends IModelFactory>
+			constructFactory(Class<? extends IModelFactory> delegateFactory) {
+		Constructor<? extends IModelFactory> ctor = null;
+		try {
+			Class<?> ctorParamType = (editedObject instanceof EObject)
+					? getInterfaceType((EObject)editedObject) : editedObject.getClass();
+			ctor = getMatchingAccessibleConstructor(delegateFactory, ctorParamType);
+			try {
+				return Optional.of(ctor.newInstance(editedObject));
+			} catch(InstantiationException | IllegalAccessException | IllegalArgumentException |
+					InvocationTargetException e) {
+				error(ToolingKernelUIActivator.getDefault(), "Failed to instantiate the factory " +
+						delegateFactory.getSimpleName() + ".");
+				return Optional.empty();
+			}
+		} catch(NullPointerException | SecurityException e1) {
+			error(ToolingKernelUIActivator.getDefault(), "The factory " +
+					delegateFactory.getSimpleName() +
+					" is missing a single argument Constructor accepting the edited model." +
+					" Only such constructors are allowed for " +
+					IModelFactory.class.getSimpleName() + "s.");
+			return Optional.empty();
+		}
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public List<?> getContentAnchorageModels(Object parent) {
+		return getDelegateFactories().stream().map(f -> f.getContentAnchorageModels(parent))
+				.filter(lm -> !isNullOrEmpty(lm)).flatMap(Collection::stream).distinct()
+				.collect(toList());
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public Object getLinkStart(Object link) {
+		return getDelegateFactories().stream().map(f -> f.getLinkStart(link))
+				.filter(cc -> cc != null).findFirst().orElse(null);
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public Object getLinkEnd(Object link) {
+		return getDelegateFactories().stream().map(f -> f.getLinkEnd(link)).filter(cc -> cc != null)
+				.findFirst().orElse(null);
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public Object getParent(Object element) {
+		return getDelegateFactories().stream().map(f -> f.getParent(element))
+				.filter(cc -> cc != null).findFirst().orElse(null);
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public Object getRootModel() {
+		return editedObject;
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public List<?> getContentModels() {
+		return getDelegateFactories().stream().map(f -> f.getContentModels())
+				.filter(lm -> !isNullOrEmpty(lm)).flatMap(Collection::stream).distinct()
+				.collect(toList());
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public List<?> getDiagramAnchorageModels() {
+		return getDelegateFactories().stream().map(f -> f.getDiagramAnchorageModels())
+				.filter(lm -> !isNullOrEmpty(lm)).flatMap(Collection::stream).distinct()
+				.collect(toList());
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public List<?> getLinkModels() {
+		return getDelegateFactories().stream().map(f -> f.getLinkModels())
+				.filter(lm -> !isNullOrEmpty(lm)).flatMap(Collection::stream).distinct()
+				.collect(toList());
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public void update() {
+		// Not yet needed.
+	}
+}
diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/DelegatingVisualFactory.java b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/DelegatingVisualFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..7e834acd12ae4d1c2b2b32a5456dc9f2b6d4e466
--- /dev/null
+++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/DelegatingVisualFactory.java
@@ -0,0 +1,81 @@
+/*-------------------------------------------------------------------------+
+| Copyright 2019 fortiss GmbH                                              |
+|                                                                          |
+| Licensed under the Apache License, Version 2.0 (the "License");          |
+| you may not use this file except in compliance with the License.         |
+| You may obtain a copy of the License at                                  |
+|                                                                          |
+|    http://www.apache.org/licenses/LICENSE-2.0                            |
+|                                                                          |
+| Unless required by applicable law or agreed to in writing, software      |
+| distributed under the License is distributed on an "AS IS" BASIS,        |
+| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
+| See the License for the specific language governing permissions and      |
+| limitations under the License.                                           |
++--------------------------------------------------------------------------*/
+package org.fortiss.tooling.kernel.ui.extension.base.factory;
+
+import java.util.List;
+
+import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.IContentAnchorageMVCBundle;
+import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.IContentMVCBundle;
+import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.IDiagramAnchorageMVCBundle;
+import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.ILinkMVCBundle;
+import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.visual.IContentAnchorageVisual;
+import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.visual.IContentVisual;
+import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.visual.IDiagramAnchorageVisual;
+import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.visual.ILinkVisual;
+import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.visual.IVisualFactory;
+import org.eclipse.ui.IEditorPart;
+import org.fortiss.tooling.kernel.service.ITransformationService;
+import org.fortiss.tooling.kernel.ui.extension.base.LWFXEFEditorBase;
+
+/**
+ * Base class for {@link IVisualFactory}s of extendable {@link LWFXEFEditorBase}
+ * {@link IEditorPart}s.The first non-null element returned by the factories of the initially given
+ * list is returned. If no element is
+ * created (all delegates returned null), this factory also returns null.
+ * <P>
+ * This class uses the {@link ITransformationService} to find a delegate visual factory for the
+ * model elements in question.
+ * 
+ * @author hoelzl
+ */
+public class DelegatingVisualFactory extends DelegatingFactoryBase<IVisualFactory>
+		implements IVisualFactory {
+
+	/** Constructor. */
+	public DelegatingVisualFactory(List<Class<? extends IVisualFactory>> factories) {
+		super(factories, null);
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public IContentVisual createContentVisual(IContentMVCBundle modelBundle) {
+		return getDelegateFactories().stream().map(f -> f.createContentVisual(modelBundle))
+				.filter(cc -> cc != null).findFirst().orElse(null);
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public IDiagramAnchorageVisual
+			createDiagramAnchorageVisual(IDiagramAnchorageMVCBundle modelBundle) {
+		return getDelegateFactories().stream().map(f -> f.createDiagramAnchorageVisual(modelBundle))
+				.filter(cc -> cc != null).findFirst().orElse(null);
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public IContentAnchorageVisual
+			createContentAnchorageVisual(IContentAnchorageMVCBundle modelBundle) {
+		return getDelegateFactories().stream().map(f -> f.createContentAnchorageVisual(modelBundle))
+				.filter(cc -> cc != null).findFirst().orElse(null);
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public ILinkVisual createLinkVisual(ILinkMVCBundle modelBundle) {
+		return getDelegateFactories().stream().map(f -> f.createLinkVisual(modelBundle))
+				.filter(cc -> cc != null).findFirst().orElse(null);
+	}
+}
diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/.ratings b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/.ratings
index 4ea2eb911c9c55e937b880dbeaf7c166dd8ac547..e61bcd66e8b7e1f52185aeeec04e87a887296375 100644
--- a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/.ratings
+++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/.ratings
@@ -5,7 +5,7 @@ ConstraintUIService.java 433e35bb1c9bbc628c6ee070ff45632400becf4a GREEN
 ContextMenuService.java ca3c899293f25b70ce8e5f0d86ca2f9683329d81 GREEN
 EditPartFactoryService.java e9180c0020f1769d9e24ef3c08f9ca5599dbc5c3 GREEN
 MarkerService.java b01b7706034691683df7bbc2e7828c42574b3147 GREEN
-ModelEditorBindingService.java 948fcdc298a74e366351ad8835a145af6cd238be GREEN
+ModelEditorBindingService.java 577f5db41abf240291434dbad6bc6b0fde1eeb2b GREEN
 ModelElementHandlerService.java 07a30545ad687ff0fe13bf7a9348c41fb03e0b2c GREEN
 NavigatorService.java 2b1361eac805996e22e5409dafff9707fbac3376 GREEN
 ToolingKernelUIInternal.java 38903445a9084b7908716a00f41621dfb3126fca GREEN
diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/ModelEditorBindingService.java b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/ModelEditorBindingService.java
index 948fcdc298a74e366351ad8835a145af6cd238be..577f5db41abf240291434dbad6bc6b0fde1eeb2b 100644
--- a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/ModelEditorBindingService.java
+++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/ModelEditorBindingService.java
@@ -16,10 +16,13 @@
 package org.fortiss.tooling.kernel.ui.internal;
 
 import static java.util.Collections.emptyList;
+import static java.util.Collections.sort;
 import static org.fortiss.tooling.kernel.utils.KernelModelElementUtils.getParentElement;
 import static org.fortiss.tooling.kernel.utils.KernelModelElementUtils.isChildElementOf;
 import static org.fortiss.tooling.kernel.utils.LoggingUtils.error;
 
+import java.util.ArrayList;
+import java.util.Comparator;
 import java.util.EventObject;
 import java.util.HashMap;
 import java.util.List;
@@ -96,6 +99,16 @@ public class ModelEditorBindingService extends EObjectAwareServiceBase<IModelEdi
 	@Override
 	public void startService() {
 		IKernelIntrospectionSystemService.getInstance().registerService(this);
+
+		for(List<IModelEditorBinding<EObject>> bindings : handlerMap.values()) {
+			sort(bindings, new Comparator<IModelEditorBinding<EObject>>() {
+				@Override
+				public int compare(IModelEditorBinding<EObject> o1,
+						IModelEditorBinding<EObject> o2) {
+					return o2.getPriority() - o1.getPriority();
+				}
+			});
+		}
 	}
 
 	/** Registers the given editor binding with the service. */
@@ -169,12 +182,18 @@ public class ModelEditorBindingService extends EObjectAwareServiceBase<IModelEdi
 
 	/** {@inheritDoc} */
 	@Override
-	public List<IModelEditorBinding<EObject>> getBindings(EObject element) {
-		List<IModelEditorBinding<EObject>> bindings = getRegisteredHandlers(element.getClass());
+	public List<IModelEditorBinding<EObject>> getBindings(Class<? extends EObject> elementType) {
+		List<IModelEditorBinding<EObject>> bindings = getRegisteredHandlers(elementType);
 		if(bindings == null) {
 			bindings = emptyList();
 		}
-		return bindings;
+		return new ArrayList<>(bindings);
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public List<IModelEditorBinding<EObject>> getBindings(EObject element) {
+		return getBindings(element.getClass());
 	}
 
 	/** {@inheritDoc} */
diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/editor/.ratings b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/editor/.ratings
index 7b672cb407f325d3e708dae32125084d5b8d68e2..04963a065a9a724a7e30606456560f819bf493b7 100644
--- a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/editor/.ratings
+++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/editor/.ratings
@@ -1,5 +1,5 @@
 ActionBarContributor.java 18d9db3744c5381cca8b6823b5f7bc18183a1cfa GREEN
-ExtendableMultiPageEditor.java f8eb6fdc347098fb03e776f23fab61109aa55d6e GREEN
+ExtendableMultiPageEditor.java b18b5eed364eaa1c83cbcb64a89288d1ad263f7d GREEN
 IActionContributingEditor.java 4aa7496d67822de919a8cf0af0ddaafc61bf2919 GREEN
 ModelElementEditorInput.java e269eff5d992d375a646e54d048f1f0efc6144dd GREEN
 TutorialStepUIEditor.java 9eadc96c302b5131ff4cc3715777718fa06ec7e8 GREEN
diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/editor/ExtendableMultiPageEditor.java b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/editor/ExtendableMultiPageEditor.java
index f8eb6fdc347098fb03e776f23fab61109aa55d6e..b18b5eed364eaa1c83cbcb64a89288d1ad263f7d 100644
--- a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/editor/ExtendableMultiPageEditor.java
+++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/editor/ExtendableMultiPageEditor.java
@@ -15,11 +15,10 @@
 +--------------------------------------------------------------------------*/
 package org.fortiss.tooling.kernel.ui.internal.editor;
 
-import static java.util.Collections.sort;
 import static org.conqat.ide.commons.ui.logging.LoggingUtils.error;
 
+import java.lang.reflect.Constructor;
 import java.util.Collection;
-import java.util.Comparator;
 import java.util.EventObject;
 import java.util.List;
 
@@ -185,18 +184,13 @@ public class ExtendableMultiPageEditor extends MultiPageEditorPart
 		int pageIndex = 0;
 		List<IModelEditorBinding<EObject>> bindings =
 				IModelEditorBindingService.getInstance().getBindings(editedObject);
-		sort(bindings, new Comparator<IModelEditorBinding<EObject>>() {
-			@Override
-			public int compare(IModelEditorBinding<EObject> o1, IModelEditorBinding<EObject> o2) {
-				return o2.getPriority() - o1.getPriority();
-			}
-		});
 		for(IModelEditorBinding<EObject> editorBinding : bindings) {
 			try {
 				Class<? extends IEditorPart> editorClass =
 						editorBinding.getEditorClass(editedObject);
 				if(editorClass != null) {
-					IEditorPart editorPart = editorClass.newInstance();
+					Class<? extends EObject> inputType = editedObject.getClass();
+					IEditorPart editorPart = constructEditorPart(editorClass, inputType);
 					addPage(editorPart, getEditorInput());
 					setPageText(pageIndex++, editorBinding.getLabel(editedObject));
 				}
@@ -206,6 +200,23 @@ public class ExtendableMultiPageEditor extends MultiPageEditorPart
 		}
 	}
 
+	/**
+	 * Constructs an {@link IEditorPart} instance of the given {@code editorClass}.
+	 * {@link IEditorPart}s that take the input model element type as a parameter are preferred over
+	 * no-arg constructors.
+	 */
+	protected IEditorPart constructEditorPart(Class<? extends IEditorPart> editorClass,
+			Class<? extends EObject> inputType) throws Exception {
+		try {
+			Constructor<? extends IEditorPart> ctor = editorClass.getConstructor(Class.class);
+			return ctor.newInstance(inputType);
+		} catch(NoSuchMethodException | SecurityException e) {
+			// Fallback for no-arg constructors.
+			Constructor<? extends IEditorPart> ctor = editorClass.getConstructor();
+			return ctor.newInstance();
+		}
+	}
+
 	/** {@inheritDoc} */
 	@Override
 	public void doSave(IProgressMonitor monitor) {
diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/service/.ratings b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/service/.ratings
index e97d02bb76318c4fa509cab879c8029ee5376253..fd22b149f0941e9eed55e12988c6bc503e54c1e8 100644
--- a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/service/.ratings
+++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/service/.ratings
@@ -4,7 +4,7 @@ IConstraintUIService.java 07df6b9553bf04f8c414c976dc630e6a1dd5ec96 GREEN
 IContextMenuService.java cfb6b8237b6cd2b0e461991a9ceb95969f330265 GREEN
 IEditPartFactoryService.java c448bff63fb81f57037c9f1dc5319859c12d0c4d GREEN
 IMarkerService.java d433e838e387dd2fe61b8dea7395ebb7203ae39b GREEN
-IModelEditorBindingService.java e000fb7faf558d1201c5c26e449e0019b4ec24b0 GREEN
+IModelEditorBindingService.java ce2ae1957e2232bb0fac1d1d262103f9adfc5266 GREEN
 IModelElementHandlerService.java c04c2876ccb8b3f8597c8e443f9c7c3db0945430 GREEN
 INavigatorService.java 8d2ffeb6f075d3abea904b84d8a40090d97837fd GREEN
 ITutorialUIService.java 72707c60c3d23d8ffc5c579cb9b022bb614eb094 GREEN
diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/service/IModelEditorBindingService.java b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/service/IModelEditorBindingService.java
index e000fb7faf558d1201c5c26e449e0019b4ec24b0..ce2ae1957e2232bb0fac1d1d262103f9adfc5266 100644
--- a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/service/IModelEditorBindingService.java
+++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/service/IModelEditorBindingService.java
@@ -54,6 +54,9 @@ public interface IModelEditorBindingService {
 	/** Returns the currently active editor. */
 	IModelEditor<EObject> getActiveEditor();
 
+	/** Returns registered editor bindings for the given class. */
+	List<IModelEditorBinding<EObject>> getBindings(Class<? extends EObject> elementType);
+
 	/** Returns registered editor bindings for the given {@link EObject}. */
 	List<IModelEditorBinding<EObject>> getBindings(EObject element);
 
diff --git a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/.ratings b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/.ratings
index 0a98fb5c57e6ec70b3853c8145ec72ebe32eb99e..b2f23c1f28fd6be6f4cd785dfbd17d06d59c5604 100644
--- a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/.ratings
+++ b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/.ratings
@@ -6,7 +6,7 @@ IEclipseResourceStorageLocationProvider.java 0ab7f304d52a9d86f01f66e308e9a7ca420
 IElementCompositor.java 5b0ab1732f71b3f8467e0276c844f0dd549e191f GREEN
 ILibraryElementHandler.java 00ef5b25c63b8570006e6f6748aed0da1f33a5f1 GREEN
 ILogMessageHandler.java 9ab53e836a095ef00fd84ecc0375167edf593b46 GREEN
-IMigrationProvider.java fdb1078dfca10a82a18f79b862d7b8644e80e14e GREEN
+IMigrationProvider.java 241bfd8594dfb86ce0f89dc95b43662f52d9e450 GREEN
 IPrototypeProvider.java d5e3dbae19b5654caf28b81da6b1609d3c12be12 GREEN
 IStorageProvider.java d9b14cdd254d0c956dc5715c1c4d4d955a705dd5 GREEN
 ITransformationProvider.java a4ee2ea08720bb2fce29806062eb01499bb5071e GREEN
diff --git a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/IMigrationProvider.java b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/IMigrationProvider.java
index fdb1078dfca10a82a18f79b862d7b8644e80e14e..241bfd8594dfb86ce0f89dc95b43662f52d9e450 100644
--- a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/IMigrationProvider.java
+++ b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/IMigrationProvider.java
@@ -45,12 +45,12 @@ public interface IMigrationProvider extends IObjectAware<ITopLevelElement> {
 	/**
 	 * Applies the provider to the given element.
 	 * 
-	 * The parameter "unknownFeatures" returns a map indicating the features that are not recognized
+	 * The parameter "unknownFeatures" indicates the features that are not recognized
 	 * in the model. This can be useful to detect features coming from old models and can be then
 	 * translated to the new model by a migrator.
 	 * 
-	 * The migrator should remove from unknownFeatures the features that it dealt with.
-	 * If one forgets to do so, the migrator will run into an infinite loop!
+	 * @return all unknown features that have successfully been migrated.
 	 */
-	void migrate(ITopLevelElement modelElement, Map<EObject, AnyType> unknownFeatures);
+	Map<EObject, AnyType> migrate(ITopLevelElement modelElement,
+			Map<EObject, AnyType> unknownFeatures);
 }
diff --git a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/base/RemoveDeprecatedArtifactsMigrationProviderBase.java b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/base/RemoveDeprecatedArtifactsMigrationProviderBase.java
deleted file mode 100644
index 4a1b676223b7ec53259a26d1a671b11ff2f911e2..0000000000000000000000000000000000000000
--- a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/base/RemoveDeprecatedArtifactsMigrationProviderBase.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*-------------------------------------------------------------------------+
-| Copyright 2018 fortiss GmbH                                              |
-|                                                                          |
-| Licensed under the Apache License, Version 2.0 (the "License");          |
-| you may not use this file except in compliance with the License.         |
-| You may obtain a copy of the License at                                  |
-|                                                                          |
-|    http://www.apache.org/licenses/LICENSE-2.0                            |
-|                                                                          |
-| Unless required by applicable law or agreed to in writing, software      |
-| distributed under the License is distributed on an "AS IS" BASIS,        |
-| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
-| See the License for the specific language governing permissions and      |
-| limitations under the License.                                           |
-+--------------------------------------------------------------------------*/
-package org.fortiss.tooling.kernel.extension.base;
-
-import static org.conqat.lib.commons.reflect.ReflectionUtils.isInstanceOfAny;
-import static org.eclipse.emf.ecore.util.EcoreUtil.delete;
-import static org.fortiss.tooling.common.util.LambdaUtils.asStream;
-
-import java.util.Collection;
-import java.util.Map;
-import java.util.Optional;
-import java.util.stream.Stream;
-
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.xml.type.AnyType;
-import org.fortiss.tooling.kernel.extension.IMigrationProvider;
-import org.fortiss.tooling.kernel.extension.data.ITopLevelElement;
-import org.fortiss.tooling.kernel.model.INamedCommentedElement;
-
-/**
- * Remove artificats related to deprecated use case model.
- * 
- * @author barner
- */
-public abstract class RemoveDeprecatedArtifactsMigrationProviderBase implements IMigrationProvider { // NO_UCD
-	// Migrators are retired after a release, but this base class should be available when needed.
-	// See https://af3-developer.fortiss.org/projects/autofocus3/wiki/Model_Migration
-
-	/** Returns the {@link Collection} of deprecated artifact types to be removed from the model. */
-	protected abstract Collection<Class<? extends EObject>> getDeprecatedArtifacts();
-
-	/**
-	 * Returns the {@link Collection} of deprecated root artifact types (possibly empty subset of
-	 * {@link #getDeprecatedArtifacts()}) for which a comment is added to the migrated model that
-	 * deprecated artifacts have been removed.
-	 */
-	protected abstract Collection<Class<? extends EObject>> getDeprecatedRootArtifacts();
-
-	/** Returns the {@link Stream} of deprecated model elements to be removed. */
-	private Stream<EObject> getDeprecatedModelElements(ITopLevelElement modelElement) {
-		Stream<EObject> root = asStream(modelElement.getRootModelElement().eAllContents());
-		Collection<Class<? extends EObject>> deprArtifacts = getDeprecatedArtifacts();
-		return root.filter(
-				e -> isInstanceOfAny(e, deprArtifacts.toArray(new Class[deprArtifacts.size()])));
-	}
-
-	/** {@inheritDoc} */
-
-	@Override
-	public boolean needMigration(ITopLevelElement modelElement,
-			Map<EObject, AnyType> unknownFeatures) {
-
-		return getDeprecatedModelElements(modelElement).findAny().isPresent();
-	}
-
-	/** {@inheritDoc} */
-	@Override
-	public void migrate(ITopLevelElement modelElement, Map<EObject, AnyType> unknownFeatures) {
-		EObject object;
-		do {
-			object = null;
-			Stream<EObject> deprecatedModelElements = getDeprecatedModelElements(modelElement);
-			Optional<EObject> anyObject = deprecatedModelElements.findAny();
-			if(anyObject.isPresent()) {
-				object = anyObject.get();
-				if(object.eContainer() instanceof INamedCommentedElement) {
-					INamedCommentedElement parent = (INamedCommentedElement)object.eContainer();
-					if(parent.getComment() == null || parent.getComment().isEmpty()) {
-						for(Class<? extends EObject> rootType : getDeprecatedRootArtifacts()) {
-							if(rootType.isAssignableFrom(object.getClass())) {
-								parent.setComment(rootType.getSimpleName() +
-										" models are no longer supported. This sub-model has been removed automatically!");
-								break;
-							}
-						}
-					}
-				}
-				delete(object);
-			}
-		} while(object != null);
-	}
-}
diff --git a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/.ratings b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/.ratings
index e6e117aec42749c55a27ff79b3607f3b914272f7..2f69b2046501b5917850e19477bc500f81ea116c 100644
--- a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/.ratings
+++ b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/.ratings
@@ -7,7 +7,7 @@ ElementCompositorService.java 98c5d27e09881e60aa4f87c1ac0c7787cdec9f7c GREEN
 LibraryPrototypeProvider.java b77eddbdca78f561ffb1233e98817be361c690ae GREEN
 LibraryService.java d22671ba820466062852c15873698adf28960d94 GREEN
 LoggingService.java da784259f7b456b54bf75c41ec268f64919ce78d GREEN
-MigrationService.java 632c13563a3d69681e2a608023fcdadbe5340c4b GREEN
+MigrationService.java 2f800eac9793aa736089a802bbfc2c4c1c09770d GREEN
 PersistencyService.java 103eef642c038ef63fa49b743d803aaa3fea2724 GREEN
 PrototypeService.java 18c3db05ab11f189a9711bf241c3c7f35c954a9e GREEN
 ToolingKernelInternal.java d624a5f6b237ce993e150e2b8d1b4390e3fc8f7a GREEN
diff --git a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/MigrationService.java b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/MigrationService.java
index 632c13563a3d69681e2a608023fcdadbe5340c4b..2f800eac9793aa736089a802bbfc2c4c1c09770d 100644
--- a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/MigrationService.java
+++ b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/MigrationService.java
@@ -16,18 +16,21 @@
 package org.fortiss.tooling.kernel.internal;
 
 import static java.util.Collections.emptyList;
+import static java.util.stream.Collectors.joining;
+import static java.util.stream.Collectors.toSet;
 import static org.fortiss.tooling.kernel.utils.EcoreUtils.getFirstChildWithType;
 import static org.fortiss.tooling.kernel.utils.LoggingUtils.error;
+import static org.fortiss.tooling.kernel.utils.LoggingUtils.warning;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.stream.Stream;
 
 import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.emf.common.util.BasicEList;
 import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.util.FeatureMap;
 import org.eclipse.emf.ecore.xml.type.AnyType;
 import org.fortiss.tooling.kernel.ToolingKernelActivator;
 import org.fortiss.tooling.kernel.extension.IMigrationProvider;
@@ -97,19 +100,6 @@ public class MigrationService extends ObjectAwareServiceBase<IMigrationProvider>
 		return false;
 	}
 
-	/** Extracts the list of feature names from a map of features. */
-	private List<String> featuresToStrings(Map<EObject, AnyType> features) {
-		List<String> res = new BasicEList<String>();
-		for(AnyType featuresPerKey : features.values()) {
-			FeatureMap actualFeatures = featuresPerKey.getMixed();
-			actualFeatures.addAll(featuresPerKey.getAnyAttribute());
-			for(FeatureMap.Entry feature : actualFeatures) {
-				res.add(feature.getEStructuralFeature().getName());
-			}
-		}
-		return res;
-	}
-
 	/** {@inheritDoc} */
 	@Override
 	public void migrate(final ITopLevelElement input, final Map<EObject, AnyType> unknownFeatures) {
@@ -117,17 +107,12 @@ public class MigrationService extends ObjectAwareServiceBase<IMigrationProvider>
 
 			@Override
 			public void run() {
+				Map<EObject, AnyType> migratedFeatures = new HashMap<EObject, AnyType>();
 				for(IMigrationProvider provider : getProviders(input)) {
 					if(provider.needMigration(input, unknownFeatures)) {
-						provider.migrate(input, unknownFeatures);
+						migratedFeatures.putAll(provider.migrate(input, unknownFeatures));
 					}
 				}
-				if(!unknownFeatures.isEmpty()) {
-					error(ToolingKernelActivator.getDefault(),
-							input.getSaveableName() + " contains one or more unknown feature(s): " +
-									featuresToStrings(unknownFeatures));
-				}
-
 				for(IMigrationProvider provider : getProviders(input)) {
 					if(provider.needMigration(input, unknownFeatures)) {
 						error(ToolingKernelActivator.getDefault(),
@@ -136,6 +121,19 @@ public class MigrationService extends ObjectAwareServiceBase<IMigrationProvider>
 										"already performed. Please fix the migrator (or model).");
 					}
 				}
+				unknownFeatures.entrySet().removeAll(migratedFeatures.entrySet());
+				if(!unknownFeatures.isEmpty()) {
+					Stream<AnyType> anyTypes = unknownFeatures.values().stream()
+							.map(v -> v.getMixed()).flatMap(f -> f.stream()).map(e -> e.getValue())
+							.filter(AnyType.class::isInstance).map(AnyType.class::cast);
+					String removedTypes = anyTypes.map(a -> a.eClass().getName()).collect(toSet())
+							.stream().collect(joining(", "));
+					warning(ToolingKernelActivator.getDefault(), input.getSaveableName() +
+							" contains one or more feature(s) of the following unkown types that will be deleted: " +
+							removedTypes + ".");
+
+					unknownFeatures.clear();
+				}
 			}
 		});
 
diff --git a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/storage/eclipse/.ratings b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/storage/eclipse/.ratings
index 4a4edee0b9b29c4f7e79c5026854886346e3d02a..605b741d853bf1e95bbf06c68ab9a477dea3beb5 100644
--- a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/storage/eclipse/.ratings
+++ b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/storage/eclipse/.ratings
@@ -1,5 +1,5 @@
 AutoUndoCommandStack.java fc326adf66c6cea2354884cdc240da5f2f82689a GREEN
 EMFTransactionalCommand.java ba4b5bead9768b6ce6c955b9238cd96cb722533c GREEN
 EclipseResourceStorageService.java e29e32272286921c5e43963253902b3ba54490c7 GREEN
-ModelContext.java 55de5f19c5d625f935fb8136ff72d80b3a54ff19 GREEN
+ModelContext.java db1735834c85e7b508266f56463d011f2b72af0e GREEN
 NonDirtyingEMFTransactionalCommand.java d288ebe35d22442c603496b0c917fb99a8febeea GREEN
diff --git a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/storage/eclipse/ModelContext.java b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/storage/eclipse/ModelContext.java
index 55de5f19c5d625f935fb8136ff72d80b3a54ff19..db1735834c85e7b508266f56463d011f2b72af0e 100644
--- a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/storage/eclipse/ModelContext.java
+++ b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/storage/eclipse/ModelContext.java
@@ -330,7 +330,9 @@ class ModelContext implements ITopLevelElement, CommandStackListener {
 
 		// Step 3..n: Save resources not managed by kernel
 		for(Resource currentResource : rset.getResources()) {
-			if(currentResource != resource && !editingDomain.isReadOnly(currentResource)) {
+			if(currentResource != resource && !editingDomain.isReadOnly(currentResource) &&
+					!currentResource.getContents().isEmpty()) {
+				// do not save resources which are not contained (by a FileProject)
 				try {
 					currentResource.save(saveOptions);
 				} catch(IOException e) {
diff --git a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/utils/.ratings b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/utils/.ratings
index d85861e2edafbeb32da7cbcff68cc64ad45f8ba9..a14d336f35b4b272093a2fc62dcf8c95d8cadab7 100644
--- a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/utils/.ratings
+++ b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/utils/.ratings
@@ -10,6 +10,6 @@ JavaUtils.java 65cdadfb9137a240ad59992eacf53a15b7f20804 GREEN
 KernelModelElementUtils.java fded09befe7e543fc04ea5184ffc1c8a309d7a66 GREEN
 LoggingUtils.java 0e0aa5d466d80ea29cfc7e91178b23a5cdd4ddf7 GREEN
 PrototypesUtils.java ec75bed75cfc5103f1f38e3a29df86f729428775 GREEN
-ResourceUtils.java 698c7db34acb4f1a258a1953e6afcca9823763a8 GREEN
+ResourceUtils.java e31eda3fdbedd2e44c85d471f717b14f92a3c663 GREEN
 TransformationUtils.java 552d3a9d56d34450be781af828efe0b8aa5d359e GREEN
 UniqueIDUtils.java 665955b1790c1bd1c2087e23114da920bfec2265 GREEN
diff --git a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/utils/ResourceUtils.java b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/utils/ResourceUtils.java
index 698c7db34acb4f1a258a1953e6afcca9823763a8..e31eda3fdbedd2e44c85d471f717b14f92a3c663 100644
--- a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/utils/ResourceUtils.java
+++ b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/utils/ResourceUtils.java
@@ -51,6 +51,11 @@ import org.eclipse.emf.ecore.resource.ResourceSet;
 import org.eclipse.emf.ecore.resource.impl.ResourceFactoryImpl;
 import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
 import org.eclipse.emf.ecore.xmi.PackageNotFoundException;
+import org.eclipse.emf.ecore.xmi.XMLHelper;
+import org.eclipse.emf.ecore.xmi.XMLLoad;
+import org.eclipse.emf.ecore.xmi.XMLResource;
+import org.eclipse.emf.ecore.xmi.impl.SAXXMIHandler;
+import org.eclipse.emf.ecore.xmi.impl.XMILoadImpl;
 import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl;
 import org.eclipse.emf.ecore.xmi.impl.XMLResourceFactoryImpl;
 import org.eclipse.emf.ecore.xml.type.AnyType;
@@ -58,6 +63,7 @@ import org.fortiss.tooling.kernel.ToolingKernelActivator;
 import org.fortiss.tooling.kernel.extension.data.ITopLevelElement;
 import org.fortiss.tooling.kernel.model.IIdLabeled;
 import org.fortiss.tooling.kernel.service.IPersistencyService;
+import org.xml.sax.helpers.DefaultHandler;
 
 /**
  * Utility class for dealing with EMF {@link Resource}s.
@@ -77,12 +83,79 @@ public final class ResourceUtils {
 	 */
 	public static class KernelResourceFactory extends ResourceFactoryImpl {
 
+		/**
+		 * XMIHandler that cleans up dangling references when loading models with unknown types
+		 * instead of throwing an exception.
+		 */
+		private final class DanglingReferencesCleanupXMIHandler extends SAXXMIHandler {
+			/** Constructor. */
+			private DanglingReferencesCleanupXMIHandler(XMLResource xmiResource, XMLHelper helper,
+					Map<?, ?> options) {
+				super(xmiResource, helper, options);
+			}
+
+			/** {@inheritDoc} */
+			@Override
+			protected void handleForwardReferences(boolean isEndDocument) {
+				List<SingleReference> toRemoveFwdSingleRefs = new ArrayList<>();
+				for(SingleReference ref : forwardSingleReferences) {
+					EObject obj;
+					try {
+						obj = xmlResource.getEObject((String)ref.getValue());
+					} catch(RuntimeException exception) {
+						obj = null;
+					}
+					if(obj == null || obj instanceof AnyType) {
+						warnRefWithUnknownType((AnyType)obj, ref.getLineNumber(),
+								ref.getColumnNumber());
+						toRemoveFwdSingleRefs.add(ref);
+					}
+				}
+				forwardSingleReferences.removeAll(toRemoveFwdSingleRefs);
+
+				List<ManyReference> toRemoveFwdManyRefs = new ArrayList<>();
+				for(ManyReference ref : forwardManyReferences) {
+					Object[] values = ref.getValues();
+
+					for(String id : (String[])values) {
+
+						EObject obj;
+						try {
+							obj = xmlResource.getEObject(id);
+						} catch(RuntimeException exception) {
+							obj = null;
+						}
+						if(obj == null || obj instanceof AnyType) {
+							warnRefWithUnknownType((AnyType)obj, ref.getLineNumber(),
+									ref.getColumnNumber());
+							toRemoveFwdManyRefs.add(ref);
+							break;
+						}
+					}
+				}
+				forwardManyReferences.removeAll(toRemoveFwdManyRefs);
+
+				super.handleForwardReferences(isEndDocument);
+			}
+
+			/** Issues a warning for a given {@link AnyType}d object. */
+			private void warnRefWithUnknownType(AnyType obj, int line, int col) {
+				String message = "Removing reference to element with unknown type" +
+						(obj != null ? " \"" + obj.eClass().getName() + "\"" : "") + " in line " +
+						line + ", column " + col + ".";
+
+				// Static inline not possible: name clash with XMLHandler::warning()
+				LoggingUtils.warning(ToolingKernelActivator.getDefault(), message);
+			}
+		}
+
 		/**
 		 * {@link XMIResourceImpl} used to persist models managed by the tooling kernel.
 		 * 
 		 * @author barner
 		 */
 		private final class KernelXMIResource extends XMIResourceImpl {
+
 			/** Constructs a new {@link KernelXMIResource}. */
 			private KernelXMIResource(URI uri) {
 				super(uri);
@@ -99,7 +172,7 @@ public final class ResourceUtils {
 			public String getID(EObject eObject) {
 				String id = super.getID(eObject);
 				if(id == null && eObject instanceof IIdLabeled) {
-					id = new Integer(((IIdLabeled)eObject).getId()).toString();
+					id = String.valueOf(((IIdLabeled)eObject).getId());
 					setID(eObject, id);
 				}
 				return id;
@@ -140,6 +213,18 @@ public final class ResourceUtils {
 				}
 				return eObjectToExtensionMap;
 			}
+
+			/** {@inheritDoc} */
+			@Override
+			protected XMLLoad createXMLLoad() {
+				return new XMILoadImpl(createXMLHelper()) {
+					/** {@inheritDoc} */
+					@Override
+					protected DefaultHandler makeDefaultHandler() {
+						return new DanglingReferencesCleanupXMIHandler(resource, helper, options);
+					}
+				};
+			}
 		}
 
 		/** {@inheritDoc} */
@@ -196,13 +281,13 @@ public final class ResourceUtils {
 
 	/**
 	 * <p>
-	 * Determines the {@link ITopLevelElement} which shares the same {@link ResourceSet} as the a
-	 * {@link Resource} with the specified {@link URI}. If no such {@link Resource} has been loaded,
-	 * {@code null} is returned.
+	 * Determines the {@link ITopLevelElement} which shares the same {@link ResourceSet} as the
+	 * a {@link Resource} with the specified {@link URI}. If no such {@link Resource} has been
+	 * loaded, {@code null} is returned.
 	 * </p>
 	 * <p>
-	 * This is useful to determine to which model managed by the Kernel a given (external) model is
-	 * linked.
+	 * This is useful to determine to which model managed by the Kernel a given (external) model
+	 * is linked.
 	 * </p>
 	 * 
 	 * @param uri
@@ -226,8 +311,8 @@ public final class ResourceUtils {
 	}
 
 	/**
-	 * Obtains a model of a given type from a {@code resourceSet}, or {@code null} if it could not
-	 * be found.
+	 * Obtains a model of a given type from a {@code resourceSet}, or {@code null} if it could
+	 * not be found.
 	 * 
 	 * @param resourceSet
 	 *            {@link ResourceSet} from which model of given type should be determined
@@ -251,25 +336,30 @@ public final class ResourceUtils {
 	}
 
 	/**
-	 * Obtains a model of a given type from a {@code resourceSet}, and creates the model if it does
-	 * not exist yet (and adds it to the given {@code resourceSet}). Returns {@code null} if the
-	 * model could not be created.
+	 * Obtains a model of a given type from a {@code resourceSet}, and creates the model if it
+	 * does not exist yet (and adds it to the given {@code resourceSet}). Returns {@code null} if
+	 * the model could not be created.
 	 * 
 	 * @param resourceSet
 	 *            {@link ResourceSet} from which model of given type should be determined
 	 * @param clazz
 	 *            Type of model to be returned.
 	 * @param factory
-	 *            {@link EFactory} to create root model element in case the model does not exist in
+	 *            {@link EFactory} to create root model element in case the model does not exist
+	 *            in
 	 *            the {@code resourceSet} yet.
 	 * @param fileExtension
-	 *            File extension to be used in case a new resource has to be created and added to
-	 *            the given given {@code resourceSet}. In case this parameter is {@code null}, this
+	 *            File extension to be used in case a new resource has to be created and added
+	 *            to
+	 *            the given given {@code resourceSet}. In case this parameter is {@code null},
+	 *            this
 	 *            method effectively behaves like {@link #getModel(ResourceSet, Class)}.
 	 * @param referenceClazz
-	 *            Type of root model element whose {@link Resource} {@link URI} should be used to
+	 *            Type of root model element whose {@link Resource} {@link URI} should be used
+	 *            to
 	 *            derive the base name in case a new {@link Resource} has to be created. In case
-	 *            this parameter is {@code null}, the {@link URI} of the first {@link Resource} in
+	 *            this parameter is {@code null}, the {@link URI} of the first {@link Resource}
+	 *            in
 	 *            the given {@link ResourceSet} is used.
 	 * 
 	 * @return Model of a given type, or {@code null} if it could not be created.
@@ -368,12 +458,14 @@ public final class ResourceUtils {
 	 *            {@link Resource} for which {@link URI}s of directly or indirectly referencing
 	 *            resources should be determined.
 	 * @param includeSelf
-	 *            Flag if the {@link URI} of the given {@code resource} should be contained in the
+	 *            Flag if the {@link URI} of the given {@code resource} should be contained in
+	 *            the
 	 *            result.
 	 * @param progressMonitor
 	 *            {@link IProgressMonitor} (may be {@code null}). Loading all resources in a
 	 *            directory may be a long-running operation.
-	 * @return {@link URI}s of directly or indirectly referencing resources, possibly including the
+	 * @return {@link URI}s of directly or indirectly referencing resources, possibly including
+	 *         the
 	 *         {@link URI} of the given {@code resource} itself (see {@code includeSelf}).
 	 */
 	public static Collection<URI> getReferencingResourceURIs(Resource resource, boolean includeSelf,