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
index 4811e9c2991d2e451beef74b3519eb1eeb70d8b0..d08365c17e7fd83d7f60daf914600403d89b164a 100644
--- 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
@@ -1,4 +1,4 @@
-ContextMenuUtil.java 7be87ce47b775d90c533078e22d4d445d9864caf GREEN
+ContextMenuUtil.java a25d01f125fbd84fd199b6d3061eb0aa0a653715 YELLOW
 EObjectDiagramController.java 66b14c1c77953cad7caecae1e04f455958943f28 GREEN
 EObjectModelChangeProvider.java f4b60cebb088a5c81ca92a41614e1a5d40030502 GREEN
 EObjectRectangularResizableContentControllerBase.java 787a540213f29e8daaecd9afe98af8b3f4088db7 GREEN
diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/ContextMenuUtil.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/ContextMenuUtil.java
index 7be87ce47b775d90c533078e22d4d445d9864caf..a25d01f125fbd84fd199b6d3061eb0aa0a653715 100644
--- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/ContextMenuUtil.java
+++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/ContextMenuUtil.java
@@ -39,7 +39,7 @@ import javafx.scene.control.MenuItem;
  * 
  * @author hoelzl
  */
-final class ContextMenuUtil {
+public final class ContextMenuUtil {
 	/** Creates the menu populated with composable prototypes. */
 	public static List<MenuItem> createPrototypeMenu(EObject target,
 			IElementCompositionContext context) {
diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/.ratings b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/.ratings
index 3102da926a65d77d07f05fa103bc6bde9e85ebd5..68513a0273c51460d3b4397800e06aeddf8f5f34 100644
--- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/.ratings
+++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/.ratings
@@ -1,7 +1,7 @@
 DynamicTreeContentProviderBase.java e801da995a1b6e5a1b757247c1638bafb6073e6d YELLOW
-DynamicTreeItem.java 15adce9e9a7fedf51f2369abf80e79ef659f066f YELLOW
+DynamicTreeItem.java 75dc5534b119ffdb3c10a65810c2a0f330b7955e YELLOW
 DynamicTreeTableUIProviderBase.java 7bfc1395283d3dc10026aff5e2e65df88d25f3a7 GREEN
-DynamicTreeTableViewer.java 80df0fbe814da719b3fa6dc1644ea3333cffee93 YELLOW
+DynamicTreeTableViewer.java 43757359b3071192ae79710bcbc0e9577bb6f62d YELLOW
 DynamicTreeUIProviderBase.java 56fe4df4577b35f1e5e6e4c4be189b706c852d52 GREEN
 DynamicTreeViewer.java da5e24ae57777a482d8e12c8262513d8143bfa93 GREEN
 DynamicTreeViewerBase.java 47124c847de322a0ae26eb7a114f85ce4bd02d7e GREEN
diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeItem.java b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeItem.java
index 15adce9e9a7fedf51f2369abf80e79ef659f066f..75dc5534b119ffdb3c10a65810c2a0f330b7955e 100644
--- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeItem.java
+++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeItem.java
@@ -22,7 +22,7 @@ import javafx.scene.control.TreeItem;
 
 /**
  * {@link TreeItem} with support for dynamic children using the
- * {@link DynamicTreeItem#update(String)} method.
+ * {@link DynamicTreeItem#update()} method.
  */
 public class DynamicTreeItem<T> extends TreeItem<T> {
 	/** The viewer. */
diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeTableViewer.java b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeTableViewer.java
index 80df0fbe814da719b3fa6dc1644ea3333cffee93..43757359b3071192ae79710bcbc0e9577bb6f62d 100644
--- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeTableViewer.java
+++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeTableViewer.java
@@ -76,6 +76,7 @@ public final class DynamicTreeTableViewer<T> extends DynamicTreeViewerBase<T> {
 		// wild cast works: see constructor
 		DynamicTreeItem<T> rootItem = (DynamicTreeItem<T>)view.getRoot();
 		rootItem.update();
+		view.refresh();
 	}
 
 	/** Expands items up to the given level. */
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 8fb040ffbf08c91fe3c8dea473975346c23c28b3..74035b2eb5a81834780c43e9371c9ac3c72b010c 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
@@ -7,6 +7,7 @@ HierarchicalNameComparator.java 6face1b673126701a0721af48ead2f9766c17d46 GREEN
 IdentifierUtils.java fff43dc4e84cdd89c3ece4f5d9d89aec4b0749c2 GREEN
 JavaUtils.java 65cdadfb9137a240ad59992eacf53a15b7f20804 GREEN
 KernelModelElementUtils.java fded09befe7e543fc04ea5184ffc1c8a309d7a66 GREEN
+KernelServiceBasedModelListenerBase.java 8d916509ae75f7118ce72564ee715c46556fb709 YELLOW
 LoggingUtils.java 0e0aa5d466d80ea29cfc7e91178b23a5cdd4ddf7 GREEN
 PrototypesUtils.java ec75bed75cfc5103f1f38e3a29df86f729428775 GREEN
 ResourceUtils.java 7f4941a83115dfbed75eb58b79c0a372fe1cbb94 GREEN
diff --git a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/utils/KernelServiceBasedModelListenerBase.java b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/utils/KernelServiceBasedModelListenerBase.java
new file mode 100644
index 0000000000000000000000000000000000000000..8d916509ae75f7118ce72564ee715c46556fb709
--- /dev/null
+++ b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/utils/KernelServiceBasedModelListenerBase.java
@@ -0,0 +1,116 @@
+/*-------------------------------------------------------------------------+
+| 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.utils;
+
+import java.util.ArrayList;
+import java.util.EventObject;
+import java.util.List;
+
+import org.eclipse.emf.common.command.CommandStackListener;
+import org.eclipse.emf.common.notify.Adapter;
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.util.EContentAdapter;
+import org.fortiss.tooling.kernel.extension.data.ITopLevelElement;
+import org.fortiss.tooling.kernel.service.ICommandStackService;
+import org.fortiss.tooling.kernel.service.IPersistencyService;
+
+/**
+ * Base class for listeners using EMF {@link Adapter}s and {@link ICommandStackService}.
+ * <P>
+ * Sub-classes should override {@link #updateComplete(List)} in order to be notified when an
+ * update cycle has completed (one or more EMF notifications followed by a command stack
+ * change).
+ * <P>
+ * Sub-classes may also provide their custom EMF {@link Adapter}, but must call
+ * {@link #addNotification(Notification)} whenever a relevant EMF notification occurs.
+ * 
+ * @author hoelzl
+ */
+public abstract class KernelServiceBasedModelListenerBase<T extends EObject>
+		implements CommandStackListener {
+	/** The persistency service reference. */
+	private static final IPersistencyService persistencyService = IPersistencyService.getInstance();
+	/** The command stack service. */
+	private static final ICommandStackService commandStackService =
+			ICommandStackService.getInstance();
+	/** List of relevant {@link Notification}s recorded during a change transaction. */
+	private final List<Notification> notifications = new ArrayList<>();
+
+	/** The model element. */
+	private final T modelElement;
+	/** The EMF notification listener. */
+	private Adapter emfAdapter = new EContentAdapter() {
+		/** {@inheritDoc} */
+		@Override
+		public void notifyChanged(Notification notification) {
+			super.notifyChanged(notification);
+			addNotification(notification);
+		}
+	};
+
+	/** Constructor. */
+	public KernelServiceBasedModelListenerBase(T modelElement, Adapter emfAdapter) {
+		this.modelElement = modelElement;
+		this.emfAdapter = emfAdapter;
+	}
+
+	/** Constructor. */
+	public KernelServiceBasedModelListenerBase(T modelElement) {
+		this.modelElement = modelElement;
+	}
+
+	/**
+	 * Called when the update cycle is completed.
+	 * 
+	 * @param notifications
+	 *            the list of notifications of the completed cycle
+	 */
+	public void updateComplete(List<Notification> notifications) {
+		// default does nothing.
+	}
+
+	/** Adds the given {@link Notification} to list of notifications. */
+	protected final void addNotification(Notification event) {
+		notifications.add(event);
+	}
+
+	/** Registers the listener with the model and the command stack service. */
+	public final void register() {
+		notifications.clear();
+		ITopLevelElement root = persistencyService.getTopLevelElementFor(modelElement);
+		commandStackService.addCommandStackListener(root, this);
+		modelElement.eAdapters().add(emfAdapter);
+	}
+
+	/** Unregisters the listener from the model and the command stack service. */
+	public final void unregister() {
+		modelElement.eAdapters().remove(emfAdapter);
+		ITopLevelElement root = persistencyService.getTopLevelElementFor(modelElement);
+		commandStackService.removeCommandStackListener(root, this);
+		notifications.clear();
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public void commandStackChanged(EventObject event) {
+		if(notifications.isEmpty()) {
+			return;
+		}
+		updateComplete(notifications);
+		notifications.clear();
+	}
+}