diff --git a/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/extension/base/.ratings b/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/extension/base/.ratings
index fae2680ff2e964a0a728896270c4b2ffa749b8b4..fec43d694d3e66c5bcfce8ae3f98d59eb5ce29e7 100644
--- a/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/extension/base/.ratings
+++ b/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/extension/base/.ratings
@@ -1,4 +1,3 @@
-
 ConstraintUIBases.java c59835240d43f3bdfb5b5acae69b2941f6b75214 GREEN
 ContextMenuSubMenuContributorBase.java 9539350f9f72b7cdd9537fea9cb3b42be719ef7d GREEN
 EObjectActionBase.java 67c307ac15d7f45ad970ab1df42f4729fee09518 GREEN
diff --git a/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/extension/base/ContextMenuSubMenuContributorBase.java b/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/extension/base/ContextMenuSubMenuContributorBase.java
new file mode 100644
index 0000000000000000000000000000000000000000..420a3fd6ec2424b8df98a853535a39881b58648d
--- /dev/null
+++ b/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/extension/base/ContextMenuSubMenuContributorBase.java
@@ -0,0 +1,323 @@
+/*-------------------------------------------------------------------------+
+| Copyright 2012 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;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IContributionItem;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.fortiss.tooling.kernel.ui.extension.IContextMenuContributor;
+import org.fortiss.tooling.kernel.ui.extension.base.EObjectActionBase.EObjectActionFactory;
+import org.fortiss.tooling.kernel.ui.extension.data.ContextMenuContextProvider;
+import org.fortiss.tooling.kernel.ui.service.IContextMenuService;
+
+/**
+ * Base class for context menu contributors creating a sub-menu {@link IMenuManager} with actions
+ * provided by actions factories {@link EObjectActionFactory} returned by
+ * {@link #getActionFactories()}.
+ * <p>
+ * The menu can be additionally structured using {@link #getMenuStructureHintItems()}: currently
+ * menu separators and one-level sub-menus supported.
+ * <p>
+ * The class implements interface methods {@link #getMenuIcon()} and {@link #getMenuId()} returning
+ * {@code null} by default. Classes providing an own icon or id should override them.
+ * <p>
+ * A usage example can be found in org.fortiss.af3.time.ui plug-in.
+ * 
+ * @param <T>
+ *            Indicates the type of selection elements.
+ * 
+ * @author trachtenherz
+ */
+public abstract class ContextMenuSubMenuContributorBase<T extends EObject> implements
+		IContextMenuContributor {
+
+	/** {@inheritDoc} */
+	@SuppressWarnings("unchecked")
+	@Override
+	public final List<IContributionItem> getContributedItems(EObject selection,
+			ContextMenuContextProvider contextProvider) {
+		if(acceptSelection(selection, contextProvider)) {
+			List<IContributionItem> contributionItems = new ArrayList<IContributionItem>();
+			contributionItems.add(createMenu(createActionsForElement((T)selection)));
+			return contributionItems;
+		}
+		return Collections.emptyList();
+	}
+
+	/** Creates action instances for the given selection. */
+	protected Collection<Action> createActionsForElement(T selection) {
+		ArrayList<Action> list = new ArrayList<Action>();
+		for(EObjectActionFactory<? super T> factory : getActionFactories()) {
+			list.add(factory.createAction(selection));
+		}
+		return list;
+	}
+
+	/**
+	 * Creates a sub-menu {@link IMenuManager} containing specified actions.
+	 */
+	protected IMenuManager createMenu(Collection<Action> actions) {
+		IMenuManager menu = new MenuManager(getMenuName(), getMenuIcon(), getMenuId());
+		IMenuManager subMenu = null;
+		// Points to the currently used menu, which is either {@code menu} or {@code subMenu}
+		IMenuManager currentMenu = menu;
+		// Prepare menu structure hint items
+		MenuStructureHintItem[] hintItems;
+		if(getMenuStructureHintItems() != null) {
+			hintItems = Arrays.copyOf(getMenuStructureHintItems(), actions.size());
+		} else {
+			hintItems = new MenuStructureHint[actions.size()];
+			Arrays.fill(hintItems, null);
+		}
+		/*
+		 * Now the hint items array contains all elements from getMenuStructureHintItems(). It also
+		 * has at least as many elements as the actions collection. If getMenuStructureHintItems()
+		 * has less elements (or is null), than all other elements of the hint items array are null.
+		 */
+		int i = 0;
+		for(Action a : actions) {
+			if(hintItems[i] != null &&
+					(hintItems[i].getHint() == MenuStructureHint.SUBMENU_START_BEFORE || hintItems[i]
+							.getHint() == MenuStructureHint.SUBMENU_START_BEFORE_SEPARATOR_BEFORE)) {
+				if(subMenu != null) {
+					// If there is a previously opened sub-menu then finish processing it because we
+					// use one-level sub-menus.
+					menu.add(subMenu);
+				}
+				if(hintItems[i].getHint() == MenuStructureHint.SUBMENU_START_BEFORE_SEPARATOR_BEFORE) {
+					menu.add(new Separator());
+				}
+				final String subMenuLabel;
+				if(hintItems[i] instanceof MenuStructureHintSubMenuStart) {
+					subMenuLabel = ((MenuStructureHintSubMenuStart)hintItems[i]).getSubMenuLabel();
+				} else {
+					subMenuLabel = MenuStructureHintSubMenuStart.DEFAULT_SUB_MENU_LABEL;
+				}
+				// Open new sub-menu
+				currentMenu = subMenu = new MenuManager(subMenuLabel);
+			}
+
+			if(hintItems[i] != null && hintItems[i].getHint() == MenuStructureHint.SEPARATOR_BEFORE) {
+				currentMenu.add(new Separator());
+			}
+
+			// Add the action to menu
+			currentMenu.add(a);
+
+			if(hintItems[i] != null &&
+					hintItems[i].getHint() == MenuStructureHint.SUBMENU_END_AFTER) {
+				if(subMenu != null) {
+					menu.add(subMenu);
+					subMenu = null;
+					// Return to top-level menu
+					currentMenu = menu;
+				}
+			}
+
+			if(hintItems[i] != null && hintItems[i].getHint() == MenuStructureHint.SEPARATOR_AFTER) {
+				currentMenu.add(new Separator());
+			}
+
+			++i;
+		}
+		return menu;
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public String getMenuSectionID() {
+		return IContextMenuService.BOTTOM_MOST_MENU_SECTION_ID;
+	}
+
+	/**
+	 * Returns {@code true} if the selected element is acceptable. This method
+	 * must also ensure that {@code selection} is an instance of {@code T}
+	 */
+	protected abstract boolean acceptSelection(EObject selection,
+			ContextMenuContextProvider contextProvider);
+
+	/** The name of the sub-menu */
+	protected abstract String getMenuName();
+
+	/** Returns the action factories for the actions to be shown in the menu */
+	protected abstract Collection<EObjectActionFactory<? super T>> getActionFactories();
+
+	/** Interface for menu structure hints. */
+	public static interface MenuStructureHintItem {
+		/** Returns the hint represented by this item. */
+		MenuStructureHint getHint();
+
+		/**
+		 * Returns hints represented by this item. If it represents one hint, than a one-element
+		 * array is returned containing the result of {@link #getHint()}.
+		 */
+		MenuStructureHint[] getHints();
+	}
+
+	/**
+	 * Constants for menu structure hints.
+	 * 
+	 * @see ContextMenuSubMenuContributorBase#getMenuStructureHintItems()
+	 */
+	public static enum MenuStructureHint implements MenuStructureHintItem {
+		/** Insert a separator before current menu item. */
+		SEPARATOR_BEFORE,
+		/** Insert a separator after current menu item. */
+		SEPARATOR_AFTER,
+		/**
+		 * Begin sub-menu before current item.
+		 * <p>
+		 * NOTE: Only one-level sub-menus are supported, so if there was a sub-menu previously
+		 * started, then starting another will automatically end the previous one.
+		 */
+		SUBMENU_START_BEFORE,
+		/** End sub-menu after current item. */
+		SUBMENU_END_AFTER,
+		/**
+		 * Insert separator and begin sub-menu before current.
+		 * 
+		 * @see #SEPARATOR_BEFORE
+		 * @see #SUBMENU_START_BEFORE
+		 */
+		SUBMENU_START_BEFORE_SEPARATOR_BEFORE;
+
+		/** {@inheritDoc} */
+		@Override
+		public MenuStructureHint getHint() {
+			return this;
+		}
+
+		/** {@inheritDoc} */
+		@Override
+		public MenuStructureHint[] getHints() {
+			return new MenuStructureHint[] {getHint()};
+		}
+	}
+
+	/**
+	 * {@link MenuStructureHintItem} wrapping a {@link MenuStructureHint#SUBMENU_START_BEFORE} hint
+	 * and providing additional information for the sub-menu.
+	 */
+	public static class MenuStructureHintSubMenuStart implements MenuStructureHintItem {
+		/** Default sub-menu item label. */
+		public static final String DEFAULT_SUB_MENU_LABEL = "Sub menu";
+		/** @see #getSubMenuLabel() */
+		private String subMenuLabel;
+
+		/**
+		 * @see #getHint()
+		 */
+		private MenuStructureHint menuStructureHint;
+
+		/**
+		 * Creates a {@link MenuStructureHintSubMenuStart} with default sub-menu label text.
+		 * 
+		 * @see #DEFAULT_SUB_MENU_LABEL
+		 */
+		public MenuStructureHintSubMenuStart() {
+			this(DEFAULT_SUB_MENU_LABEL);
+		}
+
+		/**
+		 * Creates a {@link MenuStructureHintSubMenuStart} with given sub-menu label text.
+		 */
+		public MenuStructureHintSubMenuStart(String subMenuLabel) {
+			this(subMenuLabel, false);
+		}
+
+		/**
+		 * Creates a {@link MenuStructureHintSubMenuStart} with given sub-menu label text.
+		 * If {@code separatorBefore} is true than {@link #getHint()} will later return
+		 * {@link MenuStructureHint#SUBMENU_START_BEFORE_SEPARATOR_BEFORE} otherwise
+		 * {@link MenuStructureHint#SUBMENU_START_BEFORE}.
+		 */
+		public MenuStructureHintSubMenuStart(String subMenuLabel, boolean separatorBefore) {
+			this.subMenuLabel = subMenuLabel;
+			if(separatorBefore) {
+				menuStructureHint = MenuStructureHint.SUBMENU_START_BEFORE_SEPARATOR_BEFORE;
+			} else {
+				menuStructureHint = MenuStructureHint.SUBMENU_START_BEFORE;
+			}
+		}
+
+		/** Returns the sub-menu label text. */
+		public String getSubMenuLabel() {
+			return subMenuLabel;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 * 
+		 * @return {@link MenuStructureHint#SUBMENU_START_BEFORE} or
+		 *         {@link MenuStructureHint#SUBMENU_START_BEFORE_SEPARATOR_BEFORE}, depending on the
+		 *         initialization parameters used for the constructor (see
+		 *         {@link #MenuStructureHintSubMenuStart(String, boolean)}.
+		 */
+		@Override
+		public MenuStructureHint getHint() {
+			return this.menuStructureHint;
+		}
+
+		/** {@inheritDoc} */
+		@Override
+		public MenuStructureHint[] getHints() {
+			return new MenuStructureHint[] {getHint()};
+		}
+	}
+
+	/**
+	 * Returns additional informations about the structure of the menu to be used in
+	 * {@link #createMenu(Collection)}. Each array element at position {@code i} corresponds to the
+	 * menu action at position @{@code i} in {@link #getActionFactories()}.
+	 * <p>
+	 * A {@code null} element means that there is no additional information for the corresponding
+	 * action. If the array itself is {@code null} then this is equivalent to an array filled with
+	 * {@code null} elements: in this case all actions are linearly shown in the menu.
+	 * <p>
+	 * If the array is smaller than the number of menu actions returned by
+	 * {@link #getActionFactories()} then missing structure hints are assumed {@code null} (which is
+	 * equivalent to padding the array with {@code null} till the length of
+	 * {@link #getActionFactories()}).
+	 * 
+	 * @see MenuStructureHintItem
+	 * @see MenuStructureHint
+	 * @see #getActionFactories()
+	 * @see #createMenu(Collection)
+	 */
+	protected MenuStructureHintItem[] getMenuStructureHintItems() {
+		return null;
+	}
+
+	/** The image for the sub-menu */
+	protected ImageDescriptor getMenuIcon() {
+		return null;
+	}
+
+	/** The Id for the sub-menu */
+	protected String getMenuId() {
+		return null;
+	}
+}
diff --git a/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/extension/base/EObjectActionBase.java b/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/extension/base/EObjectActionBase.java
index 0f784ea462b8a75b2f63829963847ac7ef1e5f67..4ef9f8be59e64d4838acc9e268d418ba5d94fa1a 100644
--- a/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/extension/base/EObjectActionBase.java
+++ b/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/extension/base/EObjectActionBase.java
@@ -35,6 +35,12 @@ import org.fortiss.tooling.kernel.ui.service.ITutorialUIService;
  */
 public abstract class EObjectActionBase<T extends EObject> extends Action {
 
+	/** Factory interface for action instances. */
+	public static interface EObjectActionFactory<T extends EObject> {
+		/** Creates and returns an action instance for the given target. */
+		EObjectActionBase<T> createAction(T target);
+	}
+
 	/** Stores the target elements. */
 	private EList<T> targets;