Bug 518290: [Tooling] Regression related to the creation of internal transitions

Set the UML-RT client-context ID in the assistant models.
Ensure that the UML-RT pseudostates are presented in the pop-up
assistants in an RT state machine, not the plain UML types.
Let regions also show relevant pop-up assistants.

https://bugs.eclipse.org/bugs/show_bug.cgi?id=518290

Change-Id: I058e1c5129018cf9eaaafb3ae02c6d1da6449934
diff --git a/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/assistants/uml-rt.assistants b/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/assistants/uml-rt.assistants
index 010e476..fac3b3a 100644
--- a/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/assistants/uml-rt.assistants
+++ b/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/assistants/uml-rt.assistants
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="ASCII"?>
-<assistant:ModelingAssistantProvider xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:assistant="http://www.eclipse.org/Papyrus/2014/diagram/assistant" xmlns:filters="http://www.eclipse.org/Papyrus/2014/common/filters" xmlns:umlfilters="http://www.eclipse.org/Papyrus/2014/uml/filters" name="UMLRealTime">
+<assistant:ModelingAssistantProvider xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:assistant="http://www.eclipse.org/Papyrus/2014/diagram/assistant" xmlns:filters="http://www.eclipse.org/Papyrus/2014/common/filters" xmlns:umlfilters="http://www.eclipse.org/Papyrus/2014/uml/filters" name="UMLRealTime" clientContextID="org.eclipse.papyrusrt.umlrt.architecture">
   <ownedFilter xsi:type="assistant:ElementTypeFilter" name="UML::Activity" elementTypeID="org.eclipse.papyrus.uml.Activity"/>
   <ownedFilter xsi:type="assistant:ElementTypeFilter" name="UML::AssociationClass" elementTypeID="org.eclipse.papyrus.uml.AssociationClass"/>
   <ownedFilter xsi:type="assistant:ElementTypeFilter" name="UML::Behavior" elementTypeID="org.eclipse.papyrus.uml.Behavior"/>
diff --git a/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.statemachine/assistants/uml-rt.statemachine.assistants b/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.statemachine/assistants/uml-rt.statemachine.assistants
index 2ac4539..7779a95 100644
--- a/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.statemachine/assistants/uml-rt.statemachine.assistants
+++ b/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.statemachine/assistants/uml-rt.statemachine.assistants
@@ -1,20 +1,33 @@
 <?xml version="1.0" encoding="ASCII"?>
-<assistant:ModelingAssistantProvider xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:assistant="http://www.eclipse.org/Papyrus/2014/diagram/assistant" xmlns:filters="http://www.eclipse.org/Papyrus/2014/common/filters" xmlns:umlfilters="http://www.eclipse.org/Papyrus/2014/uml/filters" name="UMLRealTime StateMachine">
+<assistant:ModelingAssistantProvider xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:assistant="http://www.eclipse.org/Papyrus/2014/diagram/assistant" xmlns:filters="http://www.eclipse.org/Papyrus/2014/common/filters" xmlns:umlfilters="http://www.eclipse.org/Papyrus/2014/uml/filters" name="UMLRealTime StateMachine" clientContextID="org.eclipse.papyrusrt.umlrt.architecture">
   <ownedFilter xsi:type="filters:CompoundFilter" name="pertains to Profile UMLRealTime" filter="//@ownedFilter.0/@ownedFilter.0" operator="or">
     <ownedFilter xsi:type="umlfilters:ProfileApplied" name="UMLRealTime is applied in context" profileQualifiedName="UMLRealTime" profileURI="pathmap://UML_RT_PROFILE/uml-rt.profile.uml#_1h74oEeVEeO0lv5O1DTHOQ"/>
   </ownedFilter>
   <ownedFilter xsi:type="assistant:ElementTypeFilter" name="RTState_Shape" elementTypeID="org.eclipse.papyrusrt.umlrt.tooling.diagram.statemachine.State_Shape"/>
-  <ownedFilter xsi:type="assistant:ElementTypeFilter" name="UML_Region_Shape" elementTypeID="org.eclipse.papyrus.umldi.Region_Shape"/>
+  <ownedFilter xsi:type="assistant:ElementTypeFilter" name="RTRegion" elementTypeID="org.eclipse.papyrusrt.umlrt.core.RTRegion"/>
   <ownedFilter xsi:type="assistant:ElementTypeFilter" name="RTState" elementTypeID="org.eclipse.papyrusrt.umlrt.core.RTState"/>
-  <ownedFilter xsi:type="assistant:ElementTypeFilter" name="InternalTransition Compartment" elementTypeID="org.eclipse.papyrusrt.umlrt.tooling.diagram.statemachine.InternalTransition_Label"/>
+  <ownedFilter xsi:type="assistant:ElementTypeFilter" name="InternalTransition Label" elementTypeID="org.eclipse.papyrusrt.umlrt.tooling.diagram.statemachine.InternalTransition_Label"/>
   <ownedFilter xsi:type="assistant:ElementTypeFilter" name="RTState_Shape_TN" elementTypeID="org.eclipse.papyrusrt.umlrt.tooling.diagram.statemachine.State_Shape_TN"/>
   <popupAssistant elementTypeID="org.eclipse.papyrusrt.umlrt.core.TransitionInternal" filter="//@popupAssistant.0/@ownedFilter">
     <ownedFilter xsi:type="filters:CompoundFilter" name="TransitionInternalAnd" filter="//@ownedFilter.0 //@popupAssistant.0/@ownedFilter/@ownedFilter.0">
       <ownedFilter xsi:type="filters:CompoundFilter" name="TransitionInternalOr" filter="//@ownedFilter.1 //@ownedFilter.2 //@ownedFilter.3 //@ownedFilter.5" operator="or"/>
     </ownedFilter>
   </popupAssistant>
-  <elementTypeID>org.eclipse.papyrus.umldi.State_Shape</elementTypeID>
+  <popupAssistant elementTypeID="org.eclipse.papyrusrt.umlrt.core.RTPseudoState_EntryPoint" filter="//@popupAssistant.1/@ownedFilter">
+    <ownedFilter xsi:type="filters:CompoundFilter" filter="//@ownedFilter.3 //@ownedFilter.2" operator="or"/>
+  </popupAssistant>
+  <popupAssistant elementTypeID="org.eclipse.papyrusrt.umlrt.core.RTPseudoState_ExitPoint" filter="//@popupAssistant.2/@ownedFilter">
+    <ownedFilter xsi:type="filters:CompoundFilter" filter="//@ownedFilter.3 //@ownedFilter.2" operator="or"/>
+  </popupAssistant>
+  <popupAssistant elementTypeID="org.eclipse.papyrusrt.umlrt.core.RTState" filter="//@ownedFilter.2"/>
+  <popupAssistant elementTypeID="org.eclipse.papyrusrt.umlrt.core.RTPseudoState_Choice" filter="//@ownedFilter.2"/>
+  <popupAssistant elementTypeID="org.eclipse.papyrusrt.umlrt.core.RTPseudoState_Junction" filter="//@ownedFilter.2"/>
+  <popupAssistant elementTypeID="org.eclipse.papyrusrt.umlrt.core.RTPseudoState_DeepHistory" filter="//@ownedFilter.2"/>
   <elementTypeID>org.eclipse.papyrusrt.umlrt.tooling.diagram.statemachine.RTPseudoState_ChoiceShape</elementTypeID>
   <elementTypeID>org.eclipse.papyrusrt.umlrt.tooling.diagram.statemachine.State_Shape</elementTypeID>
-  <elementTypeID>org.eclipse.papyrus.umldi.Region_Shape</elementTypeID>
+  <elementTypeID>org.eclipse.papyrusrt.umlrt.tooling.diagram.statemachine.RTPseudoState_DeepHistoryShape</elementTypeID>
+  <elementTypeID>org.eclipse.papyrusrt.umlrt.tooling.diagram.statemachine.RTPseudoState_EntryPointShape</elementTypeID>
+  <elementTypeID>org.eclipse.papyrusrt.umlrt.tooling.diagram.statemachine.RTPseudoState_ExitPointShape</elementTypeID>
+  <elementTypeID>org.eclipse.papyrusrt.umlrt.tooling.diagram.statemachine.RTPseudoState_JunctionShape</elementTypeID>
+  <elementTypeID>org.eclipse.papyrusrt.umlrt.tooling.diagram.statemachine.InternalTransition_Label</elementTypeID>
 </assistant:ModelingAssistantProvider>
diff --git a/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.statemachine/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/statemachine/internal/editparts/RTRegionEditPart.java b/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.statemachine/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/statemachine/internal/editparts/RTRegionEditPart.java
index 164baad..79c2c9c 100644
--- a/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.statemachine/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/statemachine/internal/editparts/RTRegionEditPart.java
+++ b/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.statemachine/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/statemachine/internal/editparts/RTRegionEditPart.java
@@ -13,6 +13,7 @@
 
 package org.eclipse.papyrusrt.umlrt.tooling.diagram.statemachine.internal.editparts;
 
+import static org.eclipse.papyrusrt.umlrt.core.types.ElementTypeUtils.isTypeCompatible;
 import static org.eclipse.papyrusrt.umlrt.tooling.diagram.common.internal.editpolicies.AbstractInheritanceEditPolicy.INHERITANCE_ROLE;
 
 import java.util.Optional;
@@ -23,10 +24,18 @@
 import org.eclipse.emf.common.notify.Notifier;
 import org.eclipse.emf.common.notify.impl.AdapterImpl;
 import org.eclipse.emf.ecore.EObject;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.Request;
 import org.eclipse.gmf.runtime.diagram.ui.editpolicies.EditPolicyRoles;
+import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewAndElementRequest;
+import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewAndElementRequest.ViewAndElementDescriptor;
+import org.eclipse.gmf.runtime.emf.type.core.IElementType;
 import org.eclipse.gmf.runtime.notation.View;
 import org.eclipse.papyrus.infra.tools.util.TypeUtils;
 import org.eclipse.papyrus.uml.diagram.statemachine.custom.edit.part.CustomRegionEditPart;
+import org.eclipse.papyrus.uml.diagram.statemachine.edit.parts.RegionCompartmentEditPart;
+import org.eclipse.papyrus.uml.service.types.element.UMLElementTypes;
+import org.eclipse.papyrusrt.umlrt.core.types.UMLRTElementTypesEnumerator;
 import org.eclipse.papyrusrt.umlrt.core.utils.Either;
 import org.eclipse.papyrusrt.umlrt.tooling.diagram.common.internal.editpolicies.InheritanceEditPolicy;
 import org.eclipse.papyrusrt.umlrt.tooling.diagram.common.internal.editpolicies.RTSemanticEditPolicy;
@@ -180,4 +189,33 @@
 		EditPartInheritanceUtils.handleNotificationEvent(this, notification,
 				super::handleNotificationEvent);
 	}
+
+	@Override
+	public EditPart getTargetEditPart(Request request) {
+		EditPart result;
+
+		if (request instanceof CreateViewAndElementRequest) {
+			Optional<IElementType> elementType = Optional.of(request)
+					.map(CreateViewAndElementRequest.class::cast)
+					.map(CreateViewAndElementRequest::getViewAndElementDescriptor)
+					.map(ViewAndElementDescriptor::getElementAdapter)
+					.map(a -> a.getAdapter(IElementType.class));
+
+			result = elementType.<EditPart> map(type ->
+			// Create connection points and internal transitions in our containing state
+			(isTypeCompatible(type, UMLRTElementTypesEnumerator.RT_PSEUDO_STATE_ENTRY_POINT)
+					|| isTypeCompatible(type, UMLRTElementTypesEnumerator.RT_PSEUDO_STATE_EXIT_POINT)
+					|| isTypeCompatible(type, UMLRTElementTypesEnumerator.TRANSITION_INTERNAL))
+							? TypeUtils.as(getParent().getParent(), RTStateEditPartTN.class)
+							// Create other pseudostates and actual states in our compartment
+							: (isTypeCompatible(type, UMLElementTypes.STATE) || isTypeCompatible(type, UMLElementTypes.PSEUDOSTATE))
+									? getChildBySemanticHint(RegionCompartmentEditPart.VISUAL_ID)
+									: null)
+					.orElseGet(() -> super.getTargetEditPart(request));
+		} else {
+			result = super.getTargetEditPart(request);
+		}
+
+		return result;
+	}
 }
diff --git a/tests/junit/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.statemachine.tests/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/statemachine/editor/tests/AbstractStateMachineDiagramTest.java b/tests/junit/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.statemachine.tests/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/statemachine/editor/tests/AbstractStateMachineDiagramTest.java
new file mode 100644
index 0000000..b5aaa3f
--- /dev/null
+++ b/tests/junit/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.statemachine.tests/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/statemachine/editor/tests/AbstractStateMachineDiagramTest.java
@@ -0,0 +1,130 @@
+/*****************************************************************************
+ * Copyright (c) 2017 Christian W. Damus and others.
+ * 
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Christian W. Damus - Initial API and implementation
+ *   
+ *****************************************************************************/
+
+package org.eclipse.papyrusrt.umlrt.tooling.diagram.statemachine.editor.tests;
+
+import static com.google.common.base.Predicates.not;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import java.util.Iterator;
+
+import org.eclipse.emf.common.util.TreeIterator;
+import org.eclipse.emf.ecore.ENamedElement;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
+import org.eclipse.emf.edit.provider.IItemLabelProvider;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.LabelEditPart;
+import org.eclipse.papyrus.infra.emf.utils.TreeIterators;
+import org.eclipse.papyrus.infra.gmfdiag.common.utils.DiagramEditPartsUtil;
+import org.eclipse.papyrus.junit.framework.classification.tests.AbstractPapyrusTest;
+import org.eclipse.papyrus.junit.utils.rules.AbstractHouseKeeperRule.CleanUp;
+import org.eclipse.papyrus.junit.utils.rules.HouseKeeper;
+import org.eclipse.papyrusrt.junit.rules.ElementTypesRule;
+import org.eclipse.papyrusrt.junit.rules.PapyrusRTEditorFixture.DiagramNaming;
+import org.eclipse.papyrusrt.junit.rules.UIThreadRule;
+import org.eclipse.papyrusrt.junit.rules.UMLRTViewpointRule;
+import org.eclipse.papyrusrt.umlrt.tooling.diagram.statemachine.canonical.tests.StateMachineDiagramNameStrategy;
+import org.eclipse.papyrusrt.umlrt.uml.util.UMLRTExtensionUtil;
+import org.eclipse.uml2.uml.Element;
+import org.eclipse.uml2.uml.NamedElement;
+import org.eclipse.uml2.uml.util.UMLUtil;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.rules.TestRule;
+
+/**
+ * Test cases for modeling assistants in the RT state machine diagram.
+ */
+@DiagramNaming(StateMachineDiagramNameStrategy.class)
+public abstract class AbstractStateMachineDiagramTest extends AbstractPapyrusTest {
+
+	@ClassRule
+	public static final TestRule uiThread = new UIThreadRule();
+
+	@ClassRule
+	public static final TestRule viewpoint = new UMLRTViewpointRule();
+
+	@ClassRule
+	public static final TestRule elementTypesRule = new ElementTypesRule();
+
+	@Rule
+	public final HouseKeeper housekeeper = new HouseKeeper();
+
+	@CleanUp
+	private ComposedAdapterFactory adapterFactory;
+
+	public AbstractStateMachineDiagramTest() {
+		super();
+	}
+
+	protected IGraphicalEditPart requireEditPart(EObject element) {
+		IGraphicalEditPart result = getEditPart(element, getDiagramEditPart());
+		assertThat("No edit part for " + label(element), result, notNullValue());
+		return result;
+	}
+
+	protected abstract DiagramEditPart getDiagramEditPart();
+
+	protected IGraphicalEditPart getEditPart(EObject element, IGraphicalEditPart scope) {
+		IGraphicalEditPart result = null;
+
+		com.google.common.base.Predicate<EditPart> isLabel = LabelEditPart.class::isInstance;
+		TreeIterator<IGraphicalEditPart> nonLabels = TreeIterators.filter(allContents(scope, true), not(isLabel));
+
+		for (Iterator<IGraphicalEditPart> iter = nonLabels; iter.hasNext();) {
+			IGraphicalEditPart next = iter.next();
+			EObject semantic = next.resolveSemanticElement();
+
+			// We don't want to get the label edit-parts by this means (we search for them as
+			// a specific child of a shape edit-part). We especially don't want applied-stereotype labels
+			if (!(next instanceof LabelEditPart) && ((semantic == element) || redefines(semantic, element))) {
+				result = next;
+				break;
+			}
+		}
+
+		return result;
+	}
+
+	protected TreeIterator<IGraphicalEditPart> allContents(EditPart root, boolean includeRoot) {
+		return TreeIterators.filter(DiagramEditPartsUtil.getAllContents(root, includeRoot), IGraphicalEditPart.class);
+	}
+
+	protected boolean redefines(EObject element, EObject redefined) {
+		return (element instanceof Element) && (redefined instanceof Element)
+				&& UMLRTExtensionUtil.redefines((Element) element, (Element) redefined);
+	}
+
+	@Before
+	public void createAdapterFactory() {
+		adapterFactory = new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE);
+	}
+
+	protected String label(EObject object) {
+		String result;
+
+		if (object instanceof ENamedElement) {
+			result = ((UMLUtil.getQualifiedName((ENamedElement) object, NamedElement.SEPARATOR)));
+		} else {
+			IItemLabelProvider labels = (IItemLabelProvider) adapterFactory.adapt(object, IItemLabelProvider.class);
+			result = (labels == null) ? String.valueOf(object) : labels.getText(object);
+		}
+
+		return result;
+	}
+}
diff --git a/tests/junit/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.statemachine.tests/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/statemachine/editor/tests/ModelingAssistantsTest.java b/tests/junit/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.statemachine.tests/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/statemachine/editor/tests/ModelingAssistantsTest.java
new file mode 100644
index 0000000..270f2a4
--- /dev/null
+++ b/tests/junit/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.statemachine.tests/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/statemachine/editor/tests/ModelingAssistantsTest.java
@@ -0,0 +1,192 @@
+/*****************************************************************************
+ * Copyright (c) 2017 Christian W. Damus and others.
+ * 
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Christian W. Damus - Initial API and implementation
+ *   
+ *****************************************************************************/
+
+package org.eclipse.papyrusrt.umlrt.tooling.diagram.statemachine.editor.tests;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+
+import javax.inject.Named;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.tools.AbstractPopupBarTool;
+import org.eclipse.gmf.runtime.diagram.ui.tools.PopupBarTool;
+import org.eclipse.gmf.runtime.emf.type.core.ElementTypeRegistry;
+import org.eclipse.gmf.runtime.emf.type.core.IElementType;
+import org.eclipse.gmf.runtime.emf.ui.services.modelingassistant.ModelingAssistantService;
+import org.eclipse.papyrus.junit.utils.rules.ActiveDiagram;
+import org.eclipse.papyrus.junit.utils.rules.AnnotationRule;
+import org.eclipse.papyrus.junit.utils.rules.PapyrusEditorFixture;
+import org.eclipse.papyrus.junit.utils.rules.PluginResource;
+import org.eclipse.papyrus.uml.service.types.element.UMLDIElementTypes;
+import org.eclipse.papyrusrt.junit.rules.FixtureElementRule;
+import org.eclipse.papyrusrt.junit.rules.PapyrusRTEditorFixture;
+import org.eclipse.uml2.uml.Region;
+import org.eclipse.uml2.uml.State;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+
+/**
+ * Test cases for modeling assistants in the RT state machine diagram.
+ */
+@PluginResource("resource/statemachine/model.di")
+@ActiveDiagram("Capsule1::StateMachine")
+public class ModelingAssistantsTest extends AbstractStateMachineDiagramTest {
+
+	@ClassRule
+	public static final PapyrusEditorFixture editor = new PapyrusRTEditorFixture();
+
+	@Rule
+	public final AnnotationRule<String> diagramName = AnnotationRule.create(ActiveDiagram.class);
+
+	@Rule
+	public final FixtureElementRule elementsRule = new FixtureElementRule("test");
+
+	@Named("Capsule1::StateMachine::Region::State1")
+	State state;
+
+	@Named("Capsule2::StateMachine::Region::State1")
+	State compositeState;
+
+	@Named("Capsule2::StateMachine::Region::State1::Region1")
+	Region compositeStateRegion;
+
+	@Test
+	public void popupEntryPointOnState() {
+		assertPopupAssistant(requireEditPart(state), "RTPseudoState_EntryPointShape", true);
+	}
+
+	@Test
+	public void popupExitPointOnState() {
+		assertPopupAssistant(requireEditPart(state), "RTPseudoState_ExitPointShape", true);
+	}
+
+	@Test
+	public void noPopupUMLEntryPointOnState() {
+		assertPopupAssistant(requireEditPart(state), UMLDIElementTypes.PSEUDOSTATE_ENTRY_POINT_SHAPE, false);
+	}
+
+	@Test
+	public void noPopupUMLExitPointOnState() {
+		assertPopupAssistant(requireEditPart(state), UMLDIElementTypes.PSEUDOSTATE_EXIT_POINT_SHAPE, false);
+	}
+
+	@Test
+	public void popupInternalTransitionOnState() {
+		assertPopupAssistant(requireEditPart(state), "InternalTransition_Label", true);
+	}
+
+	@Test
+	@ActiveDiagram("Capsule2::State1")
+	public void popupEntryPointOnCompositeState() {
+		assertPopupAssistant(requireEditPart(compositeState), "RTPseudoState_EntryPointShape", true);
+	}
+
+	@Test
+	@ActiveDiagram("Capsule2::State1")
+	public void popupExitPointOnCompositeState() {
+		assertPopupAssistant(requireEditPart(compositeState), "RTPseudoState_ExitPointShape", true);
+	}
+
+	@Test
+	@ActiveDiagram("Capsule2::State1")
+	public void popupInternalTransitionOnCompositeState() {
+		assertPopupAssistant(requireEditPart(compositeState), "InternalTransition_Label", true);
+	}
+
+	@Test
+	@ActiveDiagram("Capsule2::State1")
+	public void popupEntryPointOnCompositeStateRegion() {
+		assertPopupAssistant(requireEditPart(compositeStateRegion), "RTPseudoState_EntryPointShape", true);
+	}
+
+	@Test
+	@ActiveDiagram("Capsule2::State1")
+	public void popupExitPointOnCompositeStateRegion() {
+		assertPopupAssistant(requireEditPart(compositeStateRegion), "RTPseudoState_ExitPointShape", true);
+	}
+
+	@Test
+	@ActiveDiagram("Capsule2::State1")
+	public void popupInternalTransitionOnCompositeStateRegion() {
+		assertPopupAssistant(requireEditPart(compositeStateRegion), "InternalTransition_Label", true);
+	}
+
+	@Test
+	@ActiveDiagram("Capsule2::State1")
+	public void popupStateOnCompositeStateRegion() {
+		assertPopupAssistant(requireEditPart(compositeStateRegion), "State_Shape", true);
+	}
+
+	@Test
+	@ActiveDiagram("Capsule2::State1")
+	public void popupChoiceOnCompositeStateRegion() {
+		assertPopupAssistant(requireEditPart(compositeStateRegion), "RTPseudoState_ChoiceShape", true);
+	}
+
+	@Test
+	@ActiveDiagram("Capsule2::State1")
+	public void popupJunctionOnCompositeStateRegion() {
+		assertPopupAssistant(requireEditPart(compositeStateRegion), "RTPseudoState_JunctionShape", true);
+	}
+
+	@Test
+	@ActiveDiagram("Capsule2::State1")
+	public void popupHistoryOnCompositeStateRegion() {
+		assertPopupAssistant(requireEditPart(compositeStateRegion), "RTPseudoState_DeepHistoryShape", true);
+	}
+
+	//
+	// Test framework
+	//
+
+	@Before
+	public void activateDiagram() {
+		editor.activateDiagram(diagramName.get());
+
+		if (!Objects.equals(editor.getActiveDiagramEditor().getPartName(), diagramName.get())) {
+			// Try opening it, then
+			editor.openDiagram(diagramName.get());
+		}
+	}
+
+	void assertPopupAssistant(EditPart editPart, String elementType, boolean expected) {
+		assertPopupAssistant(editPart,
+				ElementTypeRegistry.getInstance().getType("org.eclipse.papyrusrt.umlrt.tooling.diagram.statemachine." + elementType),
+				expected);
+	}
+
+	void assertPopupAssistant(EditPart editPart, IElementType elementType, boolean expected) {
+		Optional<PopupBarTool> found = ((List<?>) ModelingAssistantService.getInstance().getTypesForPopupBar(editPart))
+				.stream().map(IElementType.class::cast)
+				.filter(elementType::equals)
+				.map(type -> new PopupBarTool(editPart, type))
+				.filter(AbstractPopupBarTool::isCommandEnabled)
+				.findAny();
+
+		assertThat((expected ? "Element type not found: " : "Unexpected element type: ") + elementType.getDisplayName(),
+				found.isPresent(), is(expected));
+	}
+
+	@Override
+	protected DiagramEditPart getDiagramEditPart() {
+		return editor.getActiveDiagramEditor().getDiagramEditPart();
+	}
+}
diff --git a/tests/junit/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.statemachine.tests/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/statemachine/editpolicies/tests/StateMachineCreationTest.java b/tests/junit/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.statemachine.tests/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/statemachine/editpolicies/tests/StateMachineCreationTest.java
index 5ce6c38..1bed76d 100644
--- a/tests/junit/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.statemachine.tests/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/statemachine/editpolicies/tests/StateMachineCreationTest.java
+++ b/tests/junit/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.statemachine.tests/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/statemachine/editpolicies/tests/StateMachineCreationTest.java
@@ -8,7 +8,7 @@
  *
  * Contributors:
  *   CEA LIST - Initial API and implementation
- *   Christian W. Damus - bug 510323
+ *   Christian W. Damus - bug 510323, 518290
  *   
  *****************************************************************************/
 
@@ -150,29 +150,16 @@
 
 	}
 
+	/**
+	 * Test that the creation of a plain UML state in an UML-RT region is not permitted by the
+	 * edit-helpers.
+	 */
 	@Test
-	public void verifyUMLStateCreationOnRegion() {
+	public void verifyNoUMLStateCreationOnRegion() {
 		IGraphicalEditPart regionCompartmentEditPart = getEditPart(capsule1_stateMachine_region).getChildBySemanticHint(RegionCompartmentEditPart.VISUAL_ID);
 		assertThat(regionCompartmentEditPart, notNullValue());
-		List<Vertex> initialChildren = new ArrayList<>(capsule1_stateMachine_region.getSubvertices());
 		Command command = getNodeCreationCommand(regionCompartmentEditPart, capsule1_stateMachine_region, ElementTypeRegistry.getInstance().getType("org.eclipse.papyrus.umldi.State_Shape"));
-		assertThat(command, isExecutable());
-
-		editor.getEditingDomain().getCommandStack().execute(GEFtoEMFCommandWrapper.wrap(command));
-		List<Vertex> newElements = new ArrayList<>(capsule1_stateMachine_region.getSubvertices()).stream().filter(v -> !initialChildren.contains(v)).collect(Collectors.toList());
-		assertThat("There is not one and only one state added: " + newElements, newElements.size(), equalTo(1));
-		assertThat(newElements.get(0), instanceOf(State.class));
-		State newState = (State) newElements.get(0);
-
-		editor.getEditingDomain().getCommandStack().undo();
-		List<Vertex> afterUndo = new ArrayList<>(capsule1_stateMachine_region.getSubvertices()).stream().filter(v -> !initialChildren.contains(v)).collect(Collectors.toList());
-		assertThat(afterUndo.size(), equalTo(0));
-
-		editor.getEditingDomain().getCommandStack().execute(GEFtoEMFCommandWrapper.wrap(command));
-		List<Vertex> afterRedo = new ArrayList<>(capsule1_stateMachine_region.getSubvertices()).stream().filter(v -> !initialChildren.contains(v)).collect(Collectors.toList());
-		assertThat(afterRedo.size(), equalTo(1));
-		assertThat(afterRedo.get(0), instanceOf(State.class));
-
+		assertThat(command, not(isExecutable()));
 	}
 
 	@Test