diff --git a/features/org.eclipse.papyrus.uml.domain.services.feature/feature.xml b/features/org.eclipse.papyrus.uml.domain.services.feature/feature.xml
index b10d316bc194b60c344f31f536b5a1b15c348a42..f63bfc1b3d6668e8988241565d21df21283438c9 100644
--- a/features/org.eclipse.papyrus.uml.domain.services.feature/feature.xml
+++ b/features/org.eclipse.papyrus.uml.domain.services.feature/feature.xml
@@ -2,7 +2,7 @@
 <feature
       id="org.eclipse.papyrus.uml.domain.services.feature"
       label="%featureName"
-      version="0.23.0.qualifier"
+      version="0.24.0"
       provider-name="%providerName"
       license-feature="org.eclipse.license"
       license-feature-version="2.0.2">
diff --git a/features/org.eclipse.papyrus.uml.domain.services.feature/pom.xml b/features/org.eclipse.papyrus.uml.domain.services.feature/pom.xml
index 97eddaaf1a9d4441e3123b05b2df9dfa63b84f45..50e9c71028fc8dbb0522ffd685f493684fd61841 100644
--- a/features/org.eclipse.papyrus.uml.domain.services.feature/pom.xml
+++ b/features/org.eclipse.papyrus.uml.domain.services.feature/pom.xml
@@ -6,7 +6,7 @@
 	<parent>
 		<groupId>org.eclipse.papyrus.domainservices</groupId>
 		<artifactId>parent</artifactId>
-		<version>0.23.0-SNAPSHOT</version>
+		<version>0.24.0</version>
 		<relativePath>../../parent</relativePath>
 	</parent>
 	<artifactId>org.eclipse.papyrus.uml.domain.services.feature</artifactId>
diff --git a/parent/pom.xml b/parent/pom.xml
index ebc6a72339fbebb990779817a562af7a86d750dd..e17a6ae46159644c4984daa2efa09b8c8d8327ac 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -5,7 +5,7 @@
 	<modelVersion>4.0.0</modelVersion>
 	<groupId>org.eclipse.papyrus.domainservices</groupId>
 	<artifactId>parent</artifactId>
-	<version>0.23.0-SNAPSHOT</version>
+	<version>0.24.0</version>
 	<packaging>pom</packaging>
 	<name>Papyrus-UML-services</name>
 
diff --git a/plugins/org.eclipse.papyrus.uml.domain.services.test/META-INF/MANIFEST.MF b/plugins/org.eclipse.papyrus.uml.domain.services.test/META-INF/MANIFEST.MF
index 4948923abe77cc93af4545f36d62bb169cb44d36..96b4996d717854c50388cb7d6d27cdabce074991 100644
--- a/plugins/org.eclipse.papyrus.uml.domain.services.test/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.papyrus.uml.domain.services.test/META-INF/MANIFEST.MF
@@ -2,10 +2,10 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: UML Domain service Tests
 Bundle-SymbolicName: org.eclipse.papyrus.uml.domain.services.test
-Bundle-Version: 0.23.0.qualifier
+Bundle-Version: 0.24.0
 Fragment-Host: org.eclipse.papyrus.uml.domain.services;bundle-version="0.1.0"
 Automatic-Module-Name: org.eclipse.papyrus.uml.domain.services.test
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Require-Bundle: org.eclipse.uml2.uml.resources;bundle-version="5.5.0",
- org.junit.jupiter.api,
- org.junit.jupiter.params
+ junit-jupiter-api,
+ junit-jupiter-params
diff --git a/plugins/org.eclipse.papyrus.uml.domain.services.test/pom.xml b/plugins/org.eclipse.papyrus.uml.domain.services.test/pom.xml
index 0b969848d52ce155163ef113ff7a3ead973731e7..e3aa0628227587220dd179306d57e4f65b93d923 100644
--- a/plugins/org.eclipse.papyrus.uml.domain.services.test/pom.xml
+++ b/plugins/org.eclipse.papyrus.uml.domain.services.test/pom.xml
@@ -7,7 +7,7 @@
 	<parent>
 		<groupId>org.eclipse.papyrus.domainservices</groupId>
 	    <artifactId>parent</artifactId>
-		<version>0.23.0-SNAPSHOT</version>
+		<version>0.24.0</version>
 		<relativePath>../../parent</relativePath>
 	</parent>
 
diff --git a/plugins/org.eclipse.papyrus.uml.domain.services.test/src/org/eclipse/papyrus/uml/domain/services/destroy/DiagramElementDeletorTest.java b/plugins/org.eclipse.papyrus.uml.domain.services.test/src/org/eclipse/papyrus/uml/domain/services/destroy/DiagramElementDeletorTest.java
index da61be00f85a8229230bf19b894097d6c13e63a0..4aa5cc62c2544dcfb58a44c3a23a87ea266c968e 100644
--- a/plugins/org.eclipse.papyrus.uml.domain.services.test/src/org/eclipse/papyrus/uml/domain/services/destroy/DiagramElementDeletorTest.java
+++ b/plugins/org.eclipse.papyrus.uml.domain.services.test/src/org/eclipse/papyrus/uml/domain/services/destroy/DiagramElementDeletorTest.java
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (c) 2022, 2023 CEA LIST, Obeo.
+ * Copyright (c) 2022, 2024 CEA LIST, Obeo.
  *
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -489,41 +489,6 @@ public class DiagramElementDeletorTest extends AbstractUMLTest {
         assertTrue(interaction.getMessages().isEmpty());
     }
 
-    @Test
-    public void deleteMessageWithSharedStartAndFinishEventsInInteraction() {
-        Interaction interaction = create(Interaction.class);
-        Message message = createIn(Message.class, interaction);
-        MessageOccurrenceSpecification sendEvent = createIn(MessageOccurrenceSpecification.class, interaction);
-        message.setSendEvent(sendEvent);
-        MessageOccurrenceSpecification receiveEvent = createIn(MessageOccurrenceSpecification.class, interaction);
-        message.setReceiveEvent(receiveEvent);
-
-        Message message2 = createIn(Message.class, interaction);
-        message2.setSendEvent(sendEvent);
-        message2.setReceiveEvent(receiveEvent);
-
-        assertFalse(interaction.getFragments().isEmpty());
-        assertFalse(interaction.getMessages().isEmpty());
-        DestroyerStatus messageDestroyStatus = ElementDestroyer.buildDefault(getCrossRef(), getEditableChecker())
-                .destroy(message);
-        assertEquals(State.DONE, messageDestroyStatus.getState());
-        assertTrue(interaction.getFragments().contains(sendEvent));
-        assertTrue(interaction.getFragments().contains(receiveEvent));
-        assertTrue(interaction.getMessages().contains(message2));
-        // Only message is deleted because its send/receive events are shared with
-        // message 2.
-        assertFalse(interaction.getMessages().contains(message));
-
-        DestroyerStatus message2DestroyStatus = ElementDestroyer.buildDefault(getCrossRef(), getEditableChecker())
-                .destroy(message2);
-        // Message 2 and its send/receive events are deleted since they aren't shared
-        // anymore.
-        assertEquals(State.DONE, message2DestroyStatus.getState());
-        assertTrue(interaction.getFragments().isEmpty());
-        assertTrue(interaction.getMessages().isEmpty());
-
-    }
-
     @Test
     public void deleteMessageWithoutStartAndFinishEventsInInteraction() {
         Interaction interaction = create(Interaction.class);
diff --git a/plugins/org.eclipse.papyrus.uml.domain.services.test/src/org/eclipse/papyrus/uml/domain/services/drop/SequenceInternalSourceToRepresentationDropBehaviorProviderTest.java b/plugins/org.eclipse.papyrus.uml.domain.services.test/src/org/eclipse/papyrus/uml/domain/services/drop/SequenceInternalSourceToRepresentationDropBehaviorProviderTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..01589890beedcfdbeef1d17945204814a385dc0c
--- /dev/null
+++ b/plugins/org.eclipse.papyrus.uml.domain.services.test/src/org/eclipse/papyrus/uml/domain/services/drop/SequenceInternalSourceToRepresentationDropBehaviorProviderTest.java
@@ -0,0 +1,107 @@
+/*****************************************************************************
+ * Copyright (c) 2024 CEA LIST.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *  Obeo - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.domain.services.drop;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.eclipse.papyrus.uml.domain.services.drop.diagrams.SequenceInternalSourceToRepresentationDropBehaviorProvider;
+import org.eclipse.papyrus.uml.domain.services.status.State;
+import org.eclipse.papyrus.uml.domain.services.status.Status;
+import org.eclipse.papyrus.uml.domain.services.utils.AbstractUMLTest;
+import org.eclipse.uml2.uml.Comment;
+import org.eclipse.uml2.uml.Constraint;
+import org.eclipse.uml2.uml.Interaction;
+import org.eclipse.uml2.uml.InteractionOperand;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Test class for
+ * {@link SequenceInternalSourceToRepresentationDropBehaviorProvider}.
+ * 
+ * @author <a href="mailto:glenn.plouhinec@obeo.fr">Glenn Plouhinec</a>
+ */
+public class SequenceInternalSourceToRepresentationDropBehaviorProviderTest extends AbstractUMLTest {
+
+    private SequenceInternalSourceToRepresentationDropBehaviorProvider sequenceInternalSourceToRepresentationDropBehaviorProvider;
+
+    @BeforeEach
+    @Override
+    public void setUp() {
+        super.setUp();
+        this.sequenceInternalSourceToRepresentationDropBehaviorProvider = new SequenceInternalSourceToRepresentationDropBehaviorProvider();
+    }
+
+    @Test
+    public void testCommentDropFromInteractionToInteractionOperand() {
+        Interaction interaction = this.create(Interaction.class);
+        Comment commentToDrop = this.create(Comment.class);
+        interaction.getOwnedComments().add(commentToDrop);
+        InteractionOperand interactionOperand = create(InteractionOperand.class);
+
+        Status status = this.sequenceInternalSourceToRepresentationDropBehaviorProvider.drop(commentToDrop, interaction,
+                interactionOperand, this.getCrossRef(), this.getEditableChecker());
+
+        assertEquals(State.DONE, status.getState());
+        assertTrue(interactionOperand.getOwnedComments().contains(commentToDrop));
+        assertFalse(interaction.getOwnedComments().contains(commentToDrop));
+    }
+
+    @Test
+    public void testCommentDropFromInteractionOperandToInteraction() {
+        InteractionOperand interactionOperand = create(InteractionOperand.class);
+        Comment commentToDrop = this.create(Comment.class);
+        interactionOperand.getOwnedComments().add(commentToDrop);
+        Interaction interaction = this.create(Interaction.class);
+
+        Status status = this.sequenceInternalSourceToRepresentationDropBehaviorProvider.drop(commentToDrop,
+                interactionOperand, interaction, this.getCrossRef(), this.getEditableChecker());
+
+        assertEquals(State.DONE, status.getState());
+        assertTrue(interaction.getOwnedComments().contains(commentToDrop));
+        assertFalse(interactionOperand.getOwnedComments().contains(commentToDrop));
+    }
+
+    @Test
+    public void testConstraintDropFromInteractionToInteractionOperand() {
+        Interaction interaction = this.create(Interaction.class);
+        Constraint constraintToDrop = this.create(Constraint.class);
+        interaction.getOwnedRules().add(constraintToDrop);
+        InteractionOperand interactionOperand = create(InteractionOperand.class);
+
+        Status status = this.sequenceInternalSourceToRepresentationDropBehaviorProvider.drop(constraintToDrop,
+                interaction, interactionOperand, this.getCrossRef(), this.getEditableChecker());
+
+        assertEquals(State.DONE, status.getState());
+        assertTrue(interactionOperand.getOwnedRules().contains(constraintToDrop));
+        assertFalse(interaction.getOwnedRules().contains(constraintToDrop));
+    }
+
+    @Test
+    public void testConstraintDropFromInteractionOperandToInteraction() {
+        InteractionOperand interactionOperand = create(InteractionOperand.class);
+        Constraint constraintToDrop = this.create(Constraint.class);
+        interactionOperand.getOwnedRules().add(constraintToDrop);
+        Interaction interaction = this.create(Interaction.class);
+
+        Status status = this.sequenceInternalSourceToRepresentationDropBehaviorProvider.drop(constraintToDrop,
+                interactionOperand, interaction, this.getCrossRef(), this.getEditableChecker());
+
+        assertEquals(State.DONE, status.getState());
+        assertTrue(interaction.getOwnedRules().contains(constraintToDrop));
+        assertFalse(interactionOperand.getOwnedRules().contains(constraintToDrop));
+    }
+}
diff --git a/plugins/org.eclipse.papyrus.uml.domain.services.test/src/org/eclipse/papyrus/uml/domain/services/drop/SequenceInternalSourceToRepresentationDropCheckerTest.java b/plugins/org.eclipse.papyrus.uml.domain.services.test/src/org/eclipse/papyrus/uml/domain/services/drop/SequenceInternalSourceToRepresentationDropCheckerTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..532b89aa8e0498523c3120a3c2c37268175ebc2b
--- /dev/null
+++ b/plugins/org.eclipse.papyrus.uml.domain.services.test/src/org/eclipse/papyrus/uml/domain/services/drop/SequenceInternalSourceToRepresentationDropCheckerTest.java
@@ -0,0 +1,126 @@
+/*****************************************************************************
+ * Copyright (c) 2024 CEA LIST.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *  Obeo - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.domain.services.drop;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.eclipse.papyrus.uml.domain.services.drop.diagrams.SequenceInternalSourceToRepresentationDropChecker;
+import org.eclipse.papyrus.uml.domain.services.status.CheckStatus;
+import org.eclipse.papyrus.uml.domain.services.utils.AbstractUMLTest;
+import org.eclipse.uml2.uml.CombinedFragment;
+import org.eclipse.uml2.uml.Comment;
+import org.eclipse.uml2.uml.Constraint;
+import org.eclipse.uml2.uml.Interaction;
+import org.eclipse.uml2.uml.InteractionOperand;
+import org.eclipse.uml2.uml.InteractionUse;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Test class for {@link SequenceInternalSourceToRepresentationDropChecker}.
+ * 
+ * @author <a href="mailto:glenn.plouhinec@obeo.fr">Glenn Plouhinec</a>
+ */
+public class SequenceInternalSourceToRepresentationDropCheckerTest extends AbstractUMLTest {
+
+    private SequenceInternalSourceToRepresentationDropChecker sequenceInternalSourceToRepresentationDropChecker;
+
+    @Override
+    @BeforeEach
+    public void setUp() {
+        super.setUp();
+        this.sequenceInternalSourceToRepresentationDropChecker = new SequenceInternalSourceToRepresentationDropChecker();
+    }
+
+    @Test
+    public void testCommentDropOnInteraction() {
+        Comment commentToDrop = this.create(Comment.class);
+        Interaction targetInteraction = this.create(Interaction.class);
+
+        CheckStatus canDragAndDropStatus = this.sequenceInternalSourceToRepresentationDropChecker
+                .canDragAndDrop(commentToDrop, targetInteraction);
+        assertTrue(canDragAndDropStatus.isValid());
+    }
+
+    @Test
+    public void testCommentDropOnInteractionOperand() {
+        Comment commentToDrop = this.create(Comment.class);
+        InteractionOperand targetInteractionOperand = this.create(InteractionOperand.class);
+
+        CheckStatus canDragAndDropStatus = this.sequenceInternalSourceToRepresentationDropChecker
+                .canDragAndDrop(commentToDrop, targetInteractionOperand);
+        assertTrue(canDragAndDropStatus.isValid());
+    }
+
+    @Test
+    public void testCommentDropOnCombinedFragment() {
+        Comment commentToDrop = this.create(Comment.class);
+        CombinedFragment targetCombinedFragment = this.create(CombinedFragment.class);
+
+        CheckStatus canDragAndDropStatus = this.sequenceInternalSourceToRepresentationDropChecker
+                .canDragAndDrop(commentToDrop, targetCombinedFragment);
+        assertFalse(canDragAndDropStatus.isValid());
+    }
+
+    @Test
+    public void testCommentDropOnInteractionUse() {
+        Comment commentToDrop = this.create(Comment.class);
+        InteractionUse targetInteractionUse = this.create(InteractionUse.class);
+
+        CheckStatus canDragAndDropStatus = this.sequenceInternalSourceToRepresentationDropChecker
+                .canDragAndDrop(commentToDrop, targetInteractionUse);
+        assertFalse(canDragAndDropStatus.isValid());
+    }
+
+    @Test
+    public void testConstraintDropOnInteraction() {
+        Constraint constraintToDrop = this.create(Constraint.class);
+        Interaction targetInteraction = this.create(Interaction.class);
+
+        CheckStatus canDragAndDropStatus = this.sequenceInternalSourceToRepresentationDropChecker
+                .canDragAndDrop(constraintToDrop, targetInteraction);
+        assertTrue(canDragAndDropStatus.isValid());
+    }
+
+    @Test
+    public void testConstraintDropOnInteractionOperand() {
+        Constraint constraintToDrop = this.create(Constraint.class);
+        InteractionOperand targetInteractionOperand = this.create(InteractionOperand.class);
+
+        CheckStatus canDragAndDropStatus = this.sequenceInternalSourceToRepresentationDropChecker
+                .canDragAndDrop(constraintToDrop, targetInteractionOperand);
+        assertTrue(canDragAndDropStatus.isValid());
+    }
+
+    @Test
+    public void testConstraintDropOnCombinedFragment() {
+        Constraint constraintToDrop = this.create(Constraint.class);
+        CombinedFragment targetCombinedFragment = this.create(CombinedFragment.class);
+
+        CheckStatus canDragAndDropStatus = this.sequenceInternalSourceToRepresentationDropChecker
+                .canDragAndDrop(constraintToDrop, targetCombinedFragment);
+        assertFalse(canDragAndDropStatus.isValid());
+    }
+
+    @Test
+    public void testConstraintDropOnInteractionUse() {
+        Constraint constraintToDrop = this.create(Constraint.class);
+        InteractionUse targetInteractionUse = this.create(InteractionUse.class);
+
+        CheckStatus canDragAndDropStatus = this.sequenceInternalSourceToRepresentationDropChecker
+                .canDragAndDrop(constraintToDrop, targetInteractionUse);
+        assertFalse(canDragAndDropStatus.isValid());
+    }
+}
diff --git a/plugins/org.eclipse.papyrus.uml.domain.services.test/src/org/eclipse/papyrus/uml/domain/services/labels/ElementLabelProviderTest.java b/plugins/org.eclipse.papyrus.uml.domain.services.test/src/org/eclipse/papyrus/uml/domain/services/labels/ElementLabelProviderTest.java
index 06beacf63081e7eb036a527351126b6e45571675..e968ca1cd6bd4bb6d48410a8233b00bcff2ddf69 100644
--- a/plugins/org.eclipse.papyrus.uml.domain.services.test/src/org/eclipse/papyrus/uml/domain/services/labels/ElementLabelProviderTest.java
+++ b/plugins/org.eclipse.papyrus.uml.domain.services.test/src/org/eclipse/papyrus/uml/domain/services/labels/ElementLabelProviderTest.java
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (c) 2022, 2023 CEA LIST, Obeo.
+ * Copyright (c) 2022, 2024 CEA LIST, Obeo.
  *
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -16,7 +16,6 @@ package org.eclipse.papyrus.uml.domain.services.labels;
 import static org.eclipse.papyrus.uml.domain.services.EMFUtils.allContainedObjectOfType;
 import static org.eclipse.papyrus.uml.domain.services.labels.UMLCharacters.CLOSE_ANGLE_BRACKET;
 import static org.eclipse.papyrus.uml.domain.services.labels.UMLCharacters.CLOSE_BRACKET;
-import static org.eclipse.papyrus.uml.domain.services.labels.UMLCharacters.D_DOTS;
 import static org.eclipse.papyrus.uml.domain.services.labels.UMLCharacters.EMPTY;
 import static org.eclipse.papyrus.uml.domain.services.labels.UMLCharacters.EOL;
 import static org.eclipse.papyrus.uml.domain.services.labels.UMLCharacters.EQL;
@@ -29,6 +28,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.fail;
 
 import java.io.IOException;
+import java.text.MessageFormat;
 import java.util.List;
 import java.util.Map;
 import java.util.function.Function;
@@ -56,6 +56,7 @@ import org.eclipse.uml2.uml.Constraint;
 import org.eclipse.uml2.uml.ControlFlow;
 import org.eclipse.uml2.uml.Dependency;
 import org.eclipse.uml2.uml.Duration;
+import org.eclipse.uml2.uml.Element;
 import org.eclipse.uml2.uml.ExpansionKind;
 import org.eclipse.uml2.uml.ExpansionRegion;
 import org.eclipse.uml2.uml.Expression;
@@ -148,6 +149,10 @@ public class ElementLabelProviderTest extends AbstractUMLTest {
     private static final String SINGLE_EXECUTION = "singleExecution";
     private static final String A_PREFIX = "aPrefix";
 
+    private static String guillemets(String value) {
+        return ST_LEFT + value + ST_RIGHT;
+    }
+
     /**
      * Basic test case for {@link Usage} label. Prefix \u00ABuse\u00BB should
      * appear.
@@ -157,9 +162,9 @@ public class ElementLabelProviderTest extends AbstractUMLTest {
         Usage usage = this.create(Usage.class);
 
         ElementLabelProvider elementLabelProvider = this.buildLabelProviderNoPrefix();
-        assertEquals(ST_LEFT + "use" + ST_RIGHT, elementLabelProvider.getLabel(usage));
+        assertEquals(guillemets("use"), elementLabelProvider.getLabel(usage));
         usage.setName("u1");
-        assertEquals(ST_LEFT + "use" + ST_RIGHT + EOL + "u1", elementLabelProvider.getLabel(usage));
+        assertEquals(guillemets("use") + EOL + "u1", elementLabelProvider.getLabel(usage));
     }
 
     private ElementLabelProvider buildLabelProviderNoPrefix() {
@@ -184,6 +189,41 @@ public class ElementLabelProviderTest extends AbstractUMLTest {
                 .build();
     }
 
+    private Lifeline createTypedLifeline() {
+        Lifeline result = this.create(Lifeline.class);
+        result.setName(LIFELINE);
+        Class clazz = this.create(Class.class);
+        clazz.setName(CLASS1);
+        Property property = this.create(Property.class);
+        property.setName(PROPERTY);
+        property.setType(clazz);
+        result.setRepresents(property);
+        return result;
+    }
+
+    private Expression createExpression() {
+        Expression expression = this.create(Expression.class);
+        expression.setName(EXPRESSION);
+        LiteralString literalString = this.create(LiteralString.class);
+        literalString.setName(LITERAL_STRING);
+        literalString.setValue(LITERAL_STRING_VALUE);
+        expression.getOperands().add(literalString);
+        return expression;
+    }
+
+    private void assertLifeline(String name, String selection, String type, Element lifeline) {
+        assertLabel(MessageFormat.format("{0}[{1}] : {2}", name, selection, type), lifeline);
+    }
+
+    private void assertLifeline(String name, String type, Element lifeline) {
+        assertLabel(MessageFormat.format("{0} : {1}", name, type), lifeline);
+    }
+
+    private void assertLabel(String label, Element element) {
+        ElementLabelProvider elementLabelProvider = buildLabelProviderNoPrefix();
+        assertEquals(label, elementLabelProvider.getLabel(element));
+    }
+
     /**
      * Basic test case for {@link Abstraction} label. Prefix \u00ABabstraction\u00BB
      * should appear.
@@ -193,9 +233,9 @@ public class ElementLabelProviderTest extends AbstractUMLTest {
         Abstraction abstraction = this.create(Abstraction.class);
 
         ElementLabelProvider elementLabelProvider = this.buildLabelProviderNoPrefix();
-        assertEquals(ST_LEFT + "abstraction" + ST_RIGHT, elementLabelProvider.getLabel(abstraction));
+        assertEquals(guillemets("abstraction"), elementLabelProvider.getLabel(abstraction));
         abstraction.setName("ab1");
-        assertEquals(ST_LEFT + "abstraction" + ST_RIGHT + EOL + "ab1", elementLabelProvider.getLabel(abstraction));
+        assertEquals(guillemets("abstraction") + EOL + "ab1", elementLabelProvider.getLabel(abstraction));
     }
 
     @Test
@@ -304,9 +344,9 @@ public class ElementLabelProviderTest extends AbstractUMLTest {
         Substitution substitution = this.create(Substitution.class);
 
         ElementLabelProvider elementLabelProvider = this.buildLabelProviderNoPrefix();
-        assertEquals(ST_LEFT + "substitute" + ST_RIGHT, elementLabelProvider.getLabel(substitution));
+        assertEquals(guillemets("substitute"), elementLabelProvider.getLabel(substitution));
         substitution.setName("s1");
-        assertEquals(ST_LEFT + "substitute" + ST_RIGHT + EOL + "s1", elementLabelProvider.getLabel(substitution));
+        assertEquals(guillemets("substitute") + EOL + "s1", elementLabelProvider.getLabel(substitution));
     }
 
     /**
@@ -318,9 +358,9 @@ public class ElementLabelProviderTest extends AbstractUMLTest {
         Manifestation manifestation = this.create(Manifestation.class);
 
         ElementLabelProvider elementLabelProvider = this.buildLabelProviderNoPrefix();
-        assertEquals(ST_LEFT + "manifest" + ST_RIGHT, elementLabelProvider.getLabel(manifestation));
+        assertEquals(guillemets("manifest"), elementLabelProvider.getLabel(manifestation));
         manifestation.setName("m1");
-        assertEquals(ST_LEFT + "manifest" + ST_RIGHT + EOL + "m1", elementLabelProvider.getLabel(manifestation));
+        assertEquals(guillemets("manifest") + EOL + "m1", elementLabelProvider.getLabel(manifestation));
     }
 
     /**
@@ -349,14 +389,14 @@ public class ElementLabelProviderTest extends AbstractUMLTest {
 
         ElementLabelProvider labelProvider = ElementLabelProvider.buildDefault();
         String label0 = labelProvider.getLabel(classOneStereotype);
-        assertEquals(ST_LEFT + "Utility" + ST_RIGHT + EOL + classOneStereotypeName, label0);
+        assertEquals(guillemets("Utility") + EOL + classOneStereotypeName, label0);
 
         String classTwoStereotypeName = "ClassTwoStereotypes";
         Class classTwoStereotype = allContainedObjectOfType(umlResource, Class.class)
                 .filter(c -> classTwoStereotypeName.equals(c.getName())).findFirst().orElseThrow();
 
         String label2 = labelProvider.getLabel(classTwoStereotype);
-        assertEquals(ST_LEFT + "Auxiliary, Focus" + ST_RIGHT + EOL + classTwoStereotypeName, label2);
+        assertEquals(guillemets("Auxiliary, Focus") + EOL + classTwoStereotypeName, label2);
     }
 
     /**
@@ -367,19 +407,19 @@ public class ElementLabelProviderTest extends AbstractUMLTest {
         PackageImport element = this.create(PackageImport.class);
 
         ElementLabelProvider elementLabelProvider = this.buildLabelProviderNoPrefix();
-        assertEquals(ST_LEFT + "import" + ST_RIGHT, elementLabelProvider.getLabel(element));
+        assertEquals(guillemets("import"), elementLabelProvider.getLabel(element));
 
         // Label is not related to source or target.
         element.setImportedPackage(this.createNamedElement(Package.class, "Any"));
-        assertEquals(ST_LEFT + "import" + ST_RIGHT, elementLabelProvider.getLabel(element));
+        assertEquals(guillemets("import"), elementLabelProvider.getLabel(element));
 
         element.setVisibility(VisibilityKind.PRIVATE_LITERAL);
         String accessKeyword = "access";
-        assertEquals(ST_LEFT + accessKeyword + ST_RIGHT, elementLabelProvider.getLabel(element));
+        assertEquals(guillemets(accessKeyword), elementLabelProvider.getLabel(element));
         element.setVisibility(VisibilityKind.PACKAGE_LITERAL);
-        assertEquals(ST_LEFT + accessKeyword + ST_RIGHT, elementLabelProvider.getLabel(element));
+        assertEquals(guillemets(accessKeyword), elementLabelProvider.getLabel(element));
         element.setVisibility(VisibilityKind.PROTECTED_LITERAL);
-        assertEquals(ST_LEFT + accessKeyword + ST_RIGHT, elementLabelProvider.getLabel(element));
+        assertEquals(guillemets(accessKeyword), elementLabelProvider.getLabel(element));
     }
 
     /**
@@ -390,12 +430,12 @@ public class ElementLabelProviderTest extends AbstractUMLTest {
         PackageMerge element = this.create(PackageMerge.class);
 
         ElementLabelProvider elementLabelProvider = this.buildLabelProviderNoPrefix();
-        assertEquals(ST_LEFT + "merge" + ST_RIGHT, elementLabelProvider.getLabel(element));
+        assertEquals(guillemets("merge"), elementLabelProvider.getLabel(element));
 
         // Label is not related to source or target.
         element.setMergedPackage(this.createNamedElement(org.eclipse.uml2.uml.Package.class, "M1"));
         element.setReceivingPackage(this.createNamedElement(org.eclipse.uml2.uml.Package.class, "M2"));
-        assertEquals(ST_LEFT + "merge" + ST_RIGHT, elementLabelProvider.getLabel(element));
+        assertEquals(guillemets("merge"), elementLabelProvider.getLabel(element));
     }
 
     @Test
@@ -456,9 +496,9 @@ public class ElementLabelProviderTest extends AbstractUMLTest {
         Collaboration collaboration = this.create(Collaboration.class);
 
         ElementLabelProvider elementLabelProvider = this.buildLabelProviderNoPrefix();
-        assertEquals(ST_LEFT + "collaboration" + ST_RIGHT, elementLabelProvider.getLabel(collaboration));
+        assertEquals(guillemets("collaboration"), elementLabelProvider.getLabel(collaboration));
         collaboration.setName(C1_NAME);
-        assertEquals(ST_LEFT + "collaboration" + ST_RIGHT + EOL + C1_NAME,
+        assertEquals(guillemets("collaboration") + EOL + C1_NAME,
                 elementLabelProvider.getLabel(collaboration));
     }
 
@@ -471,9 +511,9 @@ public class ElementLabelProviderTest extends AbstractUMLTest {
         Activity activity = this.create(Activity.class);
 
         ElementLabelProvider elementLabelProvider = this.buildLabelProviderNoPrefix();
-        assertEquals(ST_LEFT + ACTIVITY + ST_RIGHT, elementLabelProvider.getLabel(activity));
+        assertEquals(guillemets(ACTIVITY), elementLabelProvider.getLabel(activity));
         activity.setName("a1");
-        assertEquals(ST_LEFT + ACTIVITY + ST_RIGHT + EOL + "a1", elementLabelProvider.getLabel(activity));
+        assertEquals(guillemets(ACTIVITY) + EOL + "a1", elementLabelProvider.getLabel(activity));
     }
 
     /**
@@ -503,9 +543,9 @@ public class ElementLabelProviderTest extends AbstractUMLTest {
         FunctionBehavior functionBehavior = this.create(FunctionBehavior.class);
 
         ElementLabelProvider elementLabelProvider = this.buildLabelProviderNoPrefix();
-        assertEquals(ST_LEFT + "functionBehavior" + ST_RIGHT, elementLabelProvider.getLabel(functionBehavior));
+        assertEquals(guillemets("functionBehavior"), elementLabelProvider.getLabel(functionBehavior));
         functionBehavior.setName("fb1");
-        assertEquals(ST_LEFT + "functionBehavior" + ST_RIGHT + EOL + "fb1",
+        assertEquals(guillemets("functionBehavior") + EOL + "fb1",
                 elementLabelProvider.getLabel(functionBehavior));
     }
 
@@ -514,9 +554,9 @@ public class ElementLabelProviderTest extends AbstractUMLTest {
         OpaqueBehavior opaqueBehavior = this.create(OpaqueBehavior.class);
 
         ElementLabelProvider elementLabelProvider = this.buildLabelProviderNoPrefix();
-        assertEquals(ST_LEFT + "opaqueBehavior" + ST_RIGHT, elementLabelProvider.getLabel(opaqueBehavior));
+        assertEquals(guillemets("opaqueBehavior"), elementLabelProvider.getLabel(opaqueBehavior));
         opaqueBehavior.setName("ob1");
-        assertEquals(ST_LEFT + "opaqueBehavior" + ST_RIGHT + EOL + "ob1",
+        assertEquals(guillemets("opaqueBehavior") + EOL + "ob1",
                 elementLabelProvider.getLabel(opaqueBehavior));
     }
 
@@ -525,9 +565,9 @@ public class ElementLabelProviderTest extends AbstractUMLTest {
         Interaction interaction = this.create(Interaction.class);
 
         ElementLabelProvider elementLabelProvider = this.buildLabelProviderNoPrefix();
-        assertEquals(ST_LEFT + "interaction" + ST_RIGHT, elementLabelProvider.getLabel(interaction));
+        assertEquals(guillemets("interaction"), elementLabelProvider.getLabel(interaction));
         interaction.setName("i1");
-        assertEquals(ST_LEFT + "interaction" + ST_RIGHT + EOL + "i1", elementLabelProvider.getLabel(interaction));
+        assertEquals(guillemets("interaction") + EOL + "i1", elementLabelProvider.getLabel(interaction));
     }
 
     @Test
@@ -535,9 +575,9 @@ public class ElementLabelProviderTest extends AbstractUMLTest {
         StateMachine stateMachine = this.create(StateMachine.class);
 
         ElementLabelProvider elementLabelProvider = this.buildLabelProviderNoPrefix();
-        assertEquals(ST_LEFT + "stateMachine" + ST_RIGHT, elementLabelProvider.getLabel(stateMachine));
+        assertEquals(guillemets("stateMachine"), elementLabelProvider.getLabel(stateMachine));
         stateMachine.setName("sm1");
-        assertEquals(ST_LEFT + "stateMachine" + ST_RIGHT + EOL + "sm1", elementLabelProvider.getLabel(stateMachine));
+        assertEquals(guillemets("stateMachine") + EOL + "sm1", elementLabelProvider.getLabel(stateMachine));
     }
 
     @Test
@@ -545,9 +585,9 @@ public class ElementLabelProviderTest extends AbstractUMLTest {
         ProtocolStateMachine protocolStateMachine = this.create(ProtocolStateMachine.class);
 
         ElementLabelProvider elementLabelProvider = this.buildLabelProviderNoPrefix();
-        assertEquals(ST_LEFT + "protocol" + ST_RIGHT, elementLabelProvider.getLabel(protocolStateMachine));
+        assertEquals(guillemets("protocol"), elementLabelProvider.getLabel(protocolStateMachine));
         protocolStateMachine.setName("psm1");
-        assertEquals(ST_LEFT + "protocol" + ST_RIGHT + EOL + "psm1",
+        assertEquals(guillemets("protocol") + EOL + "psm1",
                 elementLabelProvider.getLabel(protocolStateMachine));
     }
 
@@ -556,9 +596,9 @@ public class ElementLabelProviderTest extends AbstractUMLTest {
         InformationFlow informationFlow = this.create(InformationFlow.class);
 
         ElementLabelProvider elementLabelProvider = this.buildLabelProviderNoPrefix();
-        assertEquals(ST_LEFT + FLOW + ST_RIGHT, elementLabelProvider.getLabel(informationFlow));
+        assertEquals(guillemets(FLOW), elementLabelProvider.getLabel(informationFlow));
         informationFlow.setName(IF1);
-        assertEquals(ST_LEFT + FLOW + ST_RIGHT + EOL + IF1, elementLabelProvider.getLabel(informationFlow));
+        assertEquals(guillemets(FLOW) + EOL + IF1, elementLabelProvider.getLabel(informationFlow));
 
         // Test that conveyeds Elements name are displayed
         Class class1 = this.create(Class.class);
@@ -566,7 +606,7 @@ public class ElementLabelProviderTest extends AbstractUMLTest {
         Class class2 = this.create(Class.class);
         class2.setName(CLASS2);
         informationFlow.getConveyeds().addAll(List.of(class1, class2));
-        assertEquals(ST_LEFT + FLOW + ST_RIGHT + EOL + CLASS1 + ", " + CLASS2 + EOL + IF1,
+        assertEquals(guillemets(FLOW) + EOL + CLASS1 + ", " + CLASS2 + EOL + IF1,
                 elementLabelProvider.getLabel(informationFlow));
 
         // Test that conveyeds Elements name are displayed, even if the InformationFlow
@@ -574,7 +614,7 @@ public class ElementLabelProviderTest extends AbstractUMLTest {
 
         InformationFlow informationFlow2 = this.create(InformationFlow.class);
         informationFlow2.getConveyeds().addAll(List.of(class1, class2));
-        assertEquals(ST_LEFT + FLOW + ST_RIGHT + UMLCharacters.EOL + "Class1, Class2",
+        assertEquals(guillemets(FLOW) + UMLCharacters.EOL + "Class1, Class2",
                 elementLabelProvider.getLabel(informationFlow2));
     }
 
@@ -583,9 +623,9 @@ public class ElementLabelProviderTest extends AbstractUMLTest {
         Component element = this.create(Component.class);
 
         ElementLabelProvider elementLabelProvider = this.buildLabelProviderNoPrefix();
-        assertEquals(ST_LEFT + "component" + ST_RIGHT, elementLabelProvider.getLabel(element));
+        assertEquals(guillemets("component"), elementLabelProvider.getLabel(element));
         element.setName("comp");
-        assertEquals(ST_LEFT + "component" + ST_RIGHT + EOL + "comp", elementLabelProvider.getLabel(element));
+        assertEquals(guillemets("component") + EOL + "comp", elementLabelProvider.getLabel(element));
     }
 
     /**
@@ -605,9 +645,9 @@ public class ElementLabelProviderTest extends AbstractUMLTest {
         Include element = this.create(Include.class);
 
         ElementLabelProvider elementLabelProvider = this.buildLabelProviderNoPrefix();
-        assertEquals(ST_LEFT + "include" + ST_RIGHT, elementLabelProvider.getLabel(element));
+        assertEquals(guillemets("include"), elementLabelProvider.getLabel(element));
         element.setName("incl");
-        assertEquals(ST_LEFT + "include" + ST_RIGHT + EOL + "incl", elementLabelProvider.getLabel(element));
+        assertEquals(guillemets("include") + EOL + "incl", elementLabelProvider.getLabel(element));
     }
 
     @Test
@@ -615,9 +655,9 @@ public class ElementLabelProviderTest extends AbstractUMLTest {
         Interface element = this.create(Interface.class);
 
         ElementLabelProvider elementLabelProvider = this.buildLabelProviderNoPrefix();
-        assertEquals(ST_LEFT + "interface" + ST_RIGHT, elementLabelProvider.getLabel(element));
+        assertEquals(guillemets("interface"), elementLabelProvider.getLabel(element));
         element.setName("inter");
-        assertEquals(ST_LEFT + "interface" + ST_RIGHT + EOL + "inter", elementLabelProvider.getLabel(element));
+        assertEquals(guillemets("interface") + EOL + "inter", elementLabelProvider.getLabel(element));
     }
 
     @Test
@@ -800,9 +840,9 @@ public class ElementLabelProviderTest extends AbstractUMLTest {
         ExpansionRegion expansionRegion = this.create(ExpansionRegion.class);
         ExpansionKind mode = expansionRegion.getMode();
         ElementLabelProvider elementLabelProvider = this.buildLabelProviderNoPrefix();
-        assertEquals(ST_LEFT + mode.getName() + ST_RIGHT, elementLabelProvider.getLabel(expansionRegion));
+        assertEquals(guillemets(mode.getName()), elementLabelProvider.getLabel(expansionRegion));
         expansionRegion.setMode(ExpansionKind.PARALLEL_LITERAL);
-        assertEquals(ST_LEFT + ExpansionKind.PARALLEL_LITERAL.getName() + ST_RIGHT,
+        assertEquals(guillemets(ExpansionKind.PARALLEL_LITERAL.getName()),
                 elementLabelProvider.getLabel(expansionRegion));
     }
 
@@ -832,189 +872,132 @@ public class ElementLabelProviderTest extends AbstractUMLTest {
     public void testStructuredActivityNodeLabel() {
         StructuredActivityNode structuredActivityNode = this.create(StructuredActivityNode.class);
         ElementLabelProvider elementLabelProvider = this.buildLabelProviderNoPrefix();
-        assertEquals(ST_LEFT + STRUCTURED + ST_RIGHT, elementLabelProvider.getLabel(structuredActivityNode));
+        assertEquals(guillemets(STRUCTURED), elementLabelProvider.getLabel(structuredActivityNode));
     }
 
     @Test
     public void testLoopNodeLabel() {
         LoopNode loopNode = this.create(LoopNode.class);
         ElementLabelProvider elementLabelProvider = this.buildLabelProviderNoPrefix();
-        assertEquals(ST_LEFT + LOOP_NODE + ST_RIGHT, elementLabelProvider.getLabel(loopNode));
+        assertEquals(guillemets(LOOP_NODE), elementLabelProvider.getLabel(loopNode));
     }
 
     @Test
     public void testSequenceNodeLabel() {
         SequenceNode sequenceNode = this.create(SequenceNode.class);
         ElementLabelProvider elementLabelProvider = this.buildLabelProviderNoPrefix();
-        assertEquals(ST_LEFT + SEQUENCE + ST_RIGHT, elementLabelProvider.getLabel(sequenceNode));
+        assertEquals(guillemets(SEQUENCE), elementLabelProvider.getLabel(sequenceNode));
     }
 
     @Test
     public void testConditionalNodeLabel() {
         ConditionalNode conditionalNode = this.create(ConditionalNode.class);
         ElementLabelProvider elementLabelProvider = this.buildLabelProviderNoPrefix();
-        assertEquals(ST_LEFT + CONDITIONAL + ST_RIGHT, elementLabelProvider.getLabel(conditionalNode));
+        assertEquals(guillemets(CONDITIONAL), elementLabelProvider.getLabel(conditionalNode));
     }
 
     @Test
     public void testLifelineWithNameNoRepresents() {
         Lifeline lifeline = this.create(Lifeline.class);
         lifeline.setName(LIFELINE);
-        ElementLabelProvider elementLabelProvider = this.buildLabelProviderNoPrefix();
-        assertEquals(LIFELINE, elementLabelProvider.getLabel(lifeline));
+        assertLabel(LIFELINE, lifeline);
     }
 
     @Test
     public void testLifelineWithNoNameNoRepresents() {
         Lifeline lifeline = this.create(Lifeline.class);
-        ElementLabelProvider elementLabelProvider = this.buildLabelProviderNoPrefix();
-        assertEquals(EMPTY, elementLabelProvider.getLabel(lifeline));
+        assertLabel(EMPTY, lifeline);
     }
 
     @Test
     public void testLifelineWithNameAndRepresentsNoSelector() {
-        Lifeline lifeline = this.create(Lifeline.class);
-        lifeline.setName(LIFELINE);
-        Class clazz = this.create(Class.class);
-        clazz.setName(CLASS1);
-        Property property = this.create(Property.class);
-        property.setName(PROPERTY);
-        property.setType(clazz);
-        lifeline.setRepresents(property);
-        ElementLabelProvider elementLabelProvider = this.buildLabelProviderNoPrefix();
-        assertEquals(PROPERTY + SPACE + D_DOTS + SPACE + CLASS1, elementLabelProvider.getLabel(lifeline));
+        assertLifeline(PROPERTY, CLASS1, createTypedLifeline());
     }
 
     @Test
     public void testLifelineWithNameAndRepresentsAndLiteralStringSelector() {
-        Lifeline lifeline = this.create(Lifeline.class);
-        lifeline.setName(LIFELINE);
-        Class clazz = this.create(Class.class);
-        clazz.setName(CLASS1);
-        Property property = this.create(Property.class);
-        property.setName(PROPERTY);
-        property.setType(clazz);
-        lifeline.setRepresents(property);
+        Lifeline lifeline = createTypedLifeline();
         LiteralString literalString = this.create(LiteralString.class);
         literalString.setName(LITERAL_STRING);
         literalString.setValue(LITERAL_STRING_VALUE);
         lifeline.setSelector(literalString);
-        ElementLabelProvider elementLabelProvider = this.buildLabelProviderNoPrefix();
-        assertEquals(PROPERTY + OPEN_ANGLE_BRACKET + literalString.getValue() + CLOSE_ANGLE_BRACKET + SPACE + D_DOTS
-                + SPACE + CLASS1, elementLabelProvider.getLabel(lifeline));
+
+        assertLifeline(PROPERTY, LITERAL_STRING_VALUE, CLASS1, lifeline);
     }
 
+
     @Test
     public void testLifelineWithNameAndRepresentsAndExpressionSelector() {
-        Lifeline lifeline = this.create(Lifeline.class);
-        lifeline.setName(LIFELINE);
-        Class clazz = this.create(Class.class);
-        clazz.setName(CLASS1);
-        Property property = this.create(Property.class);
-        property.setName(PROPERTY);
-        property.setType(clazz);
-        lifeline.setRepresents(property);
-        Expression expression = this.create(Expression.class);
-        expression.setName(EXPRESSION);
-        LiteralString literalString = this.create(LiteralString.class);
-        literalString.setName(LITERAL_STRING);
-        literalString.setValue(LITERAL_STRING_VALUE);
-        expression.getOperands().add(literalString);
-        lifeline.setSelector(expression);
-        ElementLabelProvider elementLabelProvider = this.buildLabelProviderNoPrefix();
-        assertEquals(PROPERTY + SPACE + D_DOTS + SPACE + CLASS1, elementLabelProvider.getLabel(lifeline));
+        Lifeline lifeline = createTypedLifeline();
+        lifeline.setSelector(createExpression());
+
+        assertLifeline(PROPERTY, "(" + LITERAL_STRING_VALUE + ")", CLASS1, lifeline);
     }
 
     @Test
     public void testLifelineWithNameNoRepresentsAndExpressionSelector() {
         Lifeline lifeline = this.create(Lifeline.class);
         lifeline.setName(LIFELINE);
-        Expression expression = this.create(Expression.class);
-        expression.setName(EXPRESSION);
-        LiteralString literalString = this.create(LiteralString.class);
-        literalString.setName(LITERAL_STRING);
-        literalString.setValue(LITERAL_STRING_VALUE);
-        expression.getOperands().add(literalString);
-        lifeline.setSelector(expression);
-        ElementLabelProvider elementLabelProvider = this.buildLabelProviderNoPrefix();
-        assertEquals("", elementLabelProvider.getLabel(lifeline));
+        lifeline.setSelector(createExpression());
+
+        assertLabel(LIFELINE, lifeline);
     }
 
     @Test
     public void testLifelineWithNameAndRepresentsAndOpaqueExpressionSelector() {
-        Lifeline lifeline = this.create(Lifeline.class);
-        lifeline.setName(LIFELINE);
-        Class clazz = this.create(Class.class);
-        clazz.setName(CLASS1);
-        Property property = this.create(Property.class);
-        property.setName(PROPERTY);
-        property.setType(clazz);
-        lifeline.setRepresents(property);
+        Lifeline lifeline = createTypedLifeline();
+
         OpaqueExpression expression = this.create(OpaqueExpression.class);
         expression.setName(EXPRESSION);
         expression.getLanguages().add("JAVA");
         expression.getBodies().add("1 + 1");
         lifeline.setSelector(expression);
-        ElementLabelProvider elementLabelProvider = this.buildLabelProviderNoPrefix();
-        assertEquals(PROPERTY + SPACE + D_DOTS + SPACE + CLASS1, elementLabelProvider.getLabel(lifeline));
+
+        assertLifeline(PROPERTY, "1 + 1", CLASS1, lifeline);
     }
 
     @Test
     public void testLifelineWithNameAndRepresentsAndTimingExpression() {
-        Lifeline lifeline = this.create(Lifeline.class);
-        lifeline.setName(LIFELINE);
-        Class clazz = this.create(Class.class);
-        clazz.setName(CLASS1);
-        Property property = this.create(Property.class);
-        property.setName(PROPERTY);
-        property.setType(clazz);
-        lifeline.setRepresents(property);
+        Lifeline lifeline = createTypedLifeline();
+
         TimeExpression expression = this.create(TimeExpression.class);
         expression.setName(EXPRESSION);
         TimeObservation timeObservation = this.create(TimeObservation.class);
         timeObservation.setName("MyTimeObservation");
         expression.getObservations().add(timeObservation);
         lifeline.setSelector(expression);
-        ElementLabelProvider elementLabelProvider = this.buildLabelProviderNoPrefix();
-        assertEquals(PROPERTY + SPACE + D_DOTS + SPACE + CLASS1, elementLabelProvider.getLabel(lifeline));
+
+        assertLifeline(PROPERTY, "MyTimeObservation", CLASS1, lifeline);
     }
 
-    @Test
-    public void testLifelineWithNameAndRepresentsAndInterval() {
-        Lifeline lifeline = this.create(Lifeline.class);
-        lifeline.setName(LIFELINE);
-        Class clazz = this.create(Class.class);
-        clazz.setName(CLASS1);
-        Property property = this.create(Property.class);
-        property.setName(PROPERTY);
-        property.setType(clazz);
-        lifeline.setRepresents(property);
+    private Interval createInterval() {
         Interval interval = this.create(Interval.class);
         interval.setName(EXPRESSION);
         LiteralInteger intervalMin = this.create(LiteralInteger.class);
         intervalMin.setValue(0);
-        interval.setMin(interval);
+        interval.setMin(intervalMin);
         LiteralInteger intervalMax = this.create(LiteralInteger.class);
         intervalMax.setValue(10);
-        lifeline.setSelector(interval);
-        ElementLabelProvider elementLabelProvider = this.buildLabelProviderNoPrefix();
-        assertEquals(PROPERTY + SPACE + D_DOTS + SPACE + CLASS1, elementLabelProvider.getLabel(lifeline));
+        interval.setMax(intervalMax);
+        return interval;
+    }
+
+    @Test
+    public void testLifelineWithNameAndRepresentsAndInterval() {
+        Lifeline lifeline = createTypedLifeline();
+        lifeline.setSelector(createInterval());
+
+        assertLifeline(PROPERTY, "0..10", CLASS1, lifeline);
     }
 
     @Test
     public void testLifelineWithNameNoRepresentsAndInterval() {
         Lifeline lifeline = this.create(Lifeline.class);
         lifeline.setName(LIFELINE);
-        Interval interval = this.create(Interval.class);
-        interval.setName(EXPRESSION);
-        LiteralInteger intervalMin = this.create(LiteralInteger.class);
-        intervalMin.setValue(0);
-        interval.setMin(interval);
-        LiteralInteger intervalMax = this.create(LiteralInteger.class);
-        intervalMax.setValue(10);
-        lifeline.setSelector(interval);
-        ElementLabelProvider elementLabelProvider = this.buildLabelProviderNoPrefix();
-        assertEquals(LIFELINE, elementLabelProvider.getLabel(lifeline));
+        lifeline.setSelector(createInterval());
+
+        // No property to select from
+        assertLabel(LIFELINE, lifeline);
     }
 
     @Test
@@ -1024,6 +1007,7 @@ public class ElementLabelProviderTest extends AbstractUMLTest {
         Property property = this.create(Property.class);
         property.setName(PROPERTY);
         lifeline.setRepresents(property);
+
         ElementLabelProvider elementLabelProvider = this.buildLabelProviderNoPrefix();
         assertEquals(PROPERTY, elementLabelProvider.getLabel(lifeline));
     }
diff --git a/plugins/org.eclipse.papyrus.uml.domain.services/META-INF/MANIFEST.MF b/plugins/org.eclipse.papyrus.uml.domain.services/META-INF/MANIFEST.MF
index 5a322a2b161de1e24130f5d266119bed127beb35..1e6b9400c5b8ee4b1d827d3a620399eb8cf7c7c4 100644
--- a/plugins/org.eclipse.papyrus.uml.domain.services/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.papyrus.uml.domain.services/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.papyrus.uml.domain.services
-Bundle-Version: 0.23.0.qualifier
+Bundle-Version: 0.24.0
 Bundle-Localization: plugin
 Automatic-Module-Name: org.eclipse.papyrus.uml.domain.services
 Bundle-RequiredExecutionEnvironment: JavaSE-17
diff --git a/plugins/org.eclipse.papyrus.uml.domain.services/pom.xml b/plugins/org.eclipse.papyrus.uml.domain.services/pom.xml
index 5aea327540693b55022a0253f66bde151c593f89..cb9f1dbb4179d0d6d0a39339ac23dddfdfca13fa 100644
--- a/plugins/org.eclipse.papyrus.uml.domain.services/pom.xml
+++ b/plugins/org.eclipse.papyrus.uml.domain.services/pom.xml
@@ -7,7 +7,7 @@
 	<parent>
 		<groupId>org.eclipse.papyrus.domainservices</groupId>
 	    <artifactId>parent</artifactId>
-		<version>0.23.0-SNAPSHOT</version>
+		<version>0.24.0</version>
 		<relativePath>../../parent</relativePath>
 	</parent>
 	
diff --git a/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/UMLHelper.java b/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/UMLHelper.java
index 381aa66cb6c74f77cae15c53b6c60ea8ddec1ff6..1673305b6790fba74fd51ef32d7498285aaae068 100644
--- a/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/UMLHelper.java
+++ b/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/UMLHelper.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2022, 2023 CEA, Obeo.
+ * Copyright (c) 2022, 2024 CEA List, Obeo.
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v2.0
  * which accompanies this distribution, and is available at
@@ -12,8 +12,16 @@
  *******************************************************************************/
 package org.eclipse.papyrus.uml.domain.services;
 
+import java.util.function.BiFunction;
+
+import org.eclipse.emf.common.util.EList;
 import org.eclipse.emf.ecore.EClass;
 import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.uml2.uml.Component;
+import org.eclipse.uml2.uml.Element;
+import org.eclipse.uml2.uml.Namespace;
+import org.eclipse.uml2.uml.Package;
+import org.eclipse.uml2.uml.PackageableElement;
 import org.eclipse.uml2.uml.UMLPackage;
 
 /**
@@ -50,4 +58,65 @@ public final class UMLHelper {
         return eClass;
     }
 
+    /**
+     * Returns the closest container of {@link PackageableElement} in containment.
+     * <p>
+     * Result can be {@link Package} or {@link Component}.
+     * </p>
+     *
+     * @param element
+     *                object to get container from
+     * @return {@link Package} or {@link Component} or null.
+     */
+    public static Namespace getPackagedContainer(Element element) {
+        Namespace result = null;
+        if (element instanceof Package pkg) {
+            result = pkg;
+        } else if (element instanceof Component cmp) {
+            result = cmp;
+        } else if (element != null) {
+            result = getPackagedContainer(element.getOwner());
+        }
+        return result;
+    }
+
+    /**
+     * Returns the closest {@link PackageableElement} containment list.
+     * <p>
+     * Result can be 'packagedElement' of {@link Package} or {@link Component}.
+     * </p>
+     *
+     * @param element
+     *                object to get container from
+     * @return containment list or null.
+     */
+    public static EList<PackageableElement> getPackagedContainment(Element element) {
+        Namespace container = getPackagedContainer(element);
+        EList<PackageableElement> result = null;
+        if (container instanceof Package pkg) {
+            result = pkg.getPackagedElements();
+        } else if (container instanceof Component cmp) {
+            result = cmp.getPackagedElements();
+        }
+        return result;
+    }
+
+    /**
+     * Returns a factory to create new {@link PackageableElement} in.
+     *
+     * @param element
+     *                object to get container factory from
+     * @return factory of PackageableElement
+     */
+    public static BiFunction<String, EClass, PackageableElement> getPackagedCreator(Element element) {
+        Namespace container = getPackagedContainer(element);
+        BiFunction<String, EClass, PackageableElement> result = null;
+        if (container instanceof Package pkg) {
+            result = (name, type) -> pkg.createPackagedElement(name, type);
+        } else if (container instanceof Component cmp) {
+            result = (name, type) -> cmp.createPackagedElement(name, type);
+        }
+        return result;
+    }
+
 }
diff --git a/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/create/ElementConfigurer.java b/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/create/ElementConfigurer.java
index 6c0f66d97a4986b55800bb1982c2c5fb8b7769a7..3b49cf2ee4ef1ad80e65178c2250ac390b14a0f0 100644
--- a/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/create/ElementConfigurer.java
+++ b/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/create/ElementConfigurer.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2022, 2023 CEA LIST, Obeo.
+ * Copyright (c) 2022, 2024 CEA LIST, Obeo.
  *
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -13,7 +13,14 @@
  *******************************************************************************/
 package org.eclipse.papyrus.uml.domain.services.create;
 
+import java.util.List;
+import java.util.function.BiFunction;
+import java.util.function.Consumer;
+
+import org.eclipse.emf.ecore.EClass;
 import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.papyrus.uml.domain.services.UMLHelper;
 import org.eclipse.papyrus.uml.domain.services.labels.ElementDefaultNameProvider;
 import org.eclipse.uml2.uml.AcceptCallAction;
 import org.eclipse.uml2.uml.Action;
@@ -34,20 +41,20 @@ import org.eclipse.uml2.uml.DestroyLinkAction;
 import org.eclipse.uml2.uml.DestroyObjectAction;
 import org.eclipse.uml2.uml.Duration;
 import org.eclipse.uml2.uml.DurationConstraint;
-import org.eclipse.uml2.uml.DurationInterval;
 import org.eclipse.uml2.uml.Element;
 import org.eclipse.uml2.uml.ExecutionOccurrenceSpecification;
+import org.eclipse.uml2.uml.ExecutionSpecification;
 import org.eclipse.uml2.uml.ExtensionEnd;
 import org.eclipse.uml2.uml.InputPin;
-import org.eclipse.uml2.uml.Interaction;
+import org.eclipse.uml2.uml.InteractionFragment;
 import org.eclipse.uml2.uml.InteractionOperand;
 import org.eclipse.uml2.uml.Interval;
 import org.eclipse.uml2.uml.IntervalConstraint;
-import org.eclipse.uml2.uml.LiteralInteger;
-import org.eclipse.uml2.uml.Model;
+import org.eclipse.uml2.uml.Lifeline;
 import org.eclipse.uml2.uml.NamedElement;
 import org.eclipse.uml2.uml.OpaqueExpression;
 import org.eclipse.uml2.uml.OutputPin;
+import org.eclipse.uml2.uml.PackageableElement;
 import org.eclipse.uml2.uml.Pin;
 import org.eclipse.uml2.uml.Port;
 import org.eclipse.uml2.uml.Property;
@@ -66,11 +73,11 @@ import org.eclipse.uml2.uml.StartObjectBehaviorAction;
 import org.eclipse.uml2.uml.TestIdentityAction;
 import org.eclipse.uml2.uml.TimeConstraint;
 import org.eclipse.uml2.uml.TimeExpression;
-import org.eclipse.uml2.uml.TimeInterval;
 import org.eclipse.uml2.uml.UMLFactory;
 import org.eclipse.uml2.uml.UMLPackage;
 import org.eclipse.uml2.uml.UnmarshallAction;
 import org.eclipse.uml2.uml.UseCase;
+import org.eclipse.uml2.uml.ValueSpecification;
 import org.eclipse.uml2.uml.ValueSpecificationAction;
 import org.eclipse.uml2.uml.util.UMLSwitch;
 
@@ -248,26 +255,18 @@ public class ElementConfigurer implements IElementConfigurer {
          */
         @Override
         public Void caseDurationConstraint(DurationConstraint durationConstraint) {
+            addParentToConstrained(durationConstraint);
+            fillInterval(durationConstraint, UMLPackage.eINSTANCE.getDurationInterval(),
+                    UMLPackage.eINSTANCE.getDuration(),
+                    terminal -> ((Duration) terminal).setExpr(UMLFactory.eINSTANCE.createLiteralInteger()));
+            return super.caseDurationConstraint(durationConstraint);
+        }
+
+        private void addParentToConstrained(Constraint constraint) {
             if (this.parent instanceof Element) {
-                durationConstraint.getConstrainedElements().clear();
-                durationConstraint.getConstrainedElements().add((Element) this.parent);
+                constraint.getConstrainedElements().clear();
+                constraint.getConstrainedElements().add((Element) this.parent);
             }
-            DurationInterval durationInterval = UMLFactory.eINSTANCE.createDurationInterval();
-            Model minMaxContainer = durationConstraint.getModel();
-            if (minMaxContainer != null) {
-                Duration durationMin = (Duration) minMaxContainer.createPackagedElement("d1",
-                        UMLPackage.eINSTANCE.getDuration());
-                Duration durationMax = (Duration) minMaxContainer.createPackagedElement("d2",
-                        UMLPackage.eINSTANCE.getDuration());
-                LiteralInteger integerMin = UMLFactory.eINSTANCE.createLiteralInteger();
-                LiteralInteger integerMax = UMLFactory.eINSTANCE.createLiteralInteger();
-                durationMin.setExpr(integerMin);
-                durationMax.setExpr(integerMax);
-                durationInterval.setMin(durationMin);
-                durationInterval.setMax(durationMax);
-            }
-            durationConstraint.setSpecification(durationInterval);
-            return super.caseDurationConstraint(durationConstraint);
         }
 
         /**
@@ -284,22 +283,33 @@ public class ElementConfigurer implements IElementConfigurer {
          */
         @Override
         public Void caseIntervalConstraint(IntervalConstraint intervalConstraint) {
-            // Avoid overriding existing specification (specification is already set for
-            // TimeConstraint, DurationConstraint)
-            if (intervalConstraint.getSpecification() == null) {
-                Interval interval = UMLFactory.eINSTANCE.createInterval();
-                Model minMaxContainer = intervalConstraint.getModel();
-                if (minMaxContainer != null) {
-                    LiteralInteger literalIntegerMin = (LiteralInteger) minMaxContainer.createPackagedElement("i1",
-                            UMLPackage.eINSTANCE.getLiteralInteger());
-                    LiteralInteger literalIntegerMax = (LiteralInteger) minMaxContainer.createPackagedElement("i2",
-                            UMLPackage.eINSTANCE.getLiteralInteger());
-                    interval.setMin(literalIntegerMin);
-                    interval.setMax(literalIntegerMax);
+            fillInterval(intervalConstraint, UMLPackage.eINSTANCE.getInterval(),
+                    UMLPackage.eINSTANCE.getLiteralInteger(), null);
+            return super.caseIntervalConstraint(intervalConstraint);
+        }
+
+        private ValueSpecification fillInterval(IntervalConstraint container, EClass intervalType,
+                EClass terminalType, Consumer<ValueSpecification> terminalInit) {
+            caseNamedElement(container);
+            ValueSpecification existing = container.getSpecification();
+            BiFunction<String, EClass, PackageableElement> creator = UMLHelper.getPackagedCreator(container);
+            if (existing != null) { // exists or impossible to create.
+                return existing;
+            }
+
+            Interval result = (Interval) UMLFactory.eINSTANCE.create(intervalType);
+            container.setSpecification(result); // containment
+
+            if (creator != null) {
+                result.setMin((ValueSpecification) creator.apply("Min" + container.getName(), terminalType));
+                result.setMax((ValueSpecification) creator.apply("Max" + container.getName(), terminalType));
+                if (terminalInit != null) {
+                    terminalInit.accept(result.getMin());
+                    terminalInit.accept(result.getMax());
                 }
-                intervalConstraint.setSpecification(interval);
             }
-            return super.caseIntervalConstraint(intervalConstraint);
+
+            return result;
         }
 
         @Override
@@ -451,25 +461,10 @@ public class ElementConfigurer implements IElementConfigurer {
          */
         @Override
         public Void caseTimeConstraint(TimeConstraint timeConstraint) {
-            if (this.parent instanceof Element) {
-                timeConstraint.getConstrainedElements().clear();
-                timeConstraint.getConstrainedElements().add((Element) this.parent);
-            }
-            TimeInterval timeInterval = UMLFactory.eINSTANCE.createTimeInterval();
-            Model minMaxContainer = timeConstraint.getModel();
-            if (minMaxContainer != null) {
-                TimeExpression timeExpressionMin = (TimeExpression) minMaxContainer.createPackagedElement("t1",
-                        UMLPackage.eINSTANCE.getTimeExpression());
-                TimeExpression timeExpressionMax = (TimeExpression) minMaxContainer.createPackagedElement("t2",
-                        UMLPackage.eINSTANCE.getTimeExpression());
-                LiteralInteger literalIntegerMin = UMLFactory.eINSTANCE.createLiteralInteger();
-                LiteralInteger literalIntegerMax = UMLFactory.eINSTANCE.createLiteralInteger();
-                timeExpressionMin.setExpr(literalIntegerMin);
-                timeExpressionMax.setExpr(literalIntegerMax);
-                timeInterval.setMin(timeExpressionMin);
-                timeInterval.setMax(timeExpressionMax);
-            }
-            timeConstraint.setSpecification(timeInterval);
+            addParentToConstrained(timeConstraint);
+            fillInterval(timeConstraint, UMLPackage.eINSTANCE.getTimeInterval(),
+                    UMLPackage.eINSTANCE.getTimeExpression(),
+                    terminal -> ((TimeExpression) terminal).setExpr(UMLFactory.eINSTANCE.createLiteralInteger()));
             return super.caseTimeConstraint(timeConstraint);
         }
 
@@ -497,28 +492,42 @@ public class ElementConfigurer implements IElementConfigurer {
          */
         @Override
         public Void caseActionExecutionSpecification(ActionExecutionSpecification actionExecutionSpecification) {
-            if (actionExecutionSpecification.getOwner() instanceof Interaction) {
-                /*
-                 * Need to get the name of the ExecutionSpecification first, otherwise we can't
-                 * set the ExecutionOccurrenceSpecification names.
-                 */
-                String executionName = new ElementDefaultNameProvider().getDefaultName(actionExecutionSpecification,
-                        this.parent);
-                Interaction interaction = (Interaction) actionExecutionSpecification.getOwner();
-                ExecutionOccurrenceSpecification start = UMLFactory.eINSTANCE.createExecutionOccurrenceSpecification();
-                interaction.getFragments().add(start);
-                start.setName(executionName + "Start");
-                start.setExecution(actionExecutionSpecification);
-                actionExecutionSpecification.setStart(start);
-                ExecutionOccurrenceSpecification finish = UMLFactory.eINSTANCE.createExecutionOccurrenceSpecification();
-                interaction.getFragments().add(finish);
-                finish.setName(executionName + "Finish");
-                finish.setExecution(actionExecutionSpecification);
-                actionExecutionSpecification.setFinish(finish);
-            }
+            /*
+             * Need to get the name of the ExecutionSpecification first, otherwise we can't set the
+             * ExecutionOccurrenceSpecification names.
+             */
+            caseNamedElement(actionExecutionSpecification);
+            addExecutionEvent(actionExecutionSpecification, UMLPackage.eINSTANCE.getExecutionSpecification_Start());
+            addExecutionEvent(actionExecutionSpecification, UMLPackage.eINSTANCE.getExecutionSpecification_Finish());
+
             return super.caseExecutionSpecification(actionExecutionSpecification);
         }
 
+        private static void addExecutionEvent(ExecutionSpecification execution, EReference eventReference) {
+            List<InteractionFragment> containment;
+            if (execution.getEnclosingOperand() != null) {
+                containment = execution.getEnclosingOperand().getFragments();
+            } else if (execution.getEnclosingInteraction() != null) {
+                containment = execution.getEnclosingInteraction().getFragments();
+            } else { // no container
+                return;
+            }
+            ExecutionOccurrenceSpecification end = UMLFactory.eINSTANCE.createExecutionOccurrenceSpecification();
+            containment.add(end);
+            String suffix = "Start";
+            if (eventReference == UMLPackage.eINSTANCE.getExecutionSpecification_Finish()) {
+                suffix = "Finish";
+            }
+            end.setName(execution.getName() + suffix);
+            end.setExecution(execution);
+            execution.eSet(eventReference, end);
+
+            List<Lifeline> covereds = execution.getCovereds();
+            if (!covereds.isEmpty()) {
+                end.getCovereds().add(covereds.get(0));
+            }
+        }
+
         /**
          * UML spec indicates that an ExtensionEnd should have its Aggregation set to
          * "Composite".
diff --git a/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/destroy/ElementDependencyCollector.java b/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/destroy/ElementDependencyCollector.java
index 43d052bb28db922ed30976c2498c4217ecaaf0f7..f47eb1ff21bdee2249465c7bf3bc7286e581d5b2 100644
--- a/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/destroy/ElementDependencyCollector.java
+++ b/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/destroy/ElementDependencyCollector.java
@@ -1,7 +1,7 @@
 /*****************************************************************************
- * Copyright (c) 2022, 2023 CEA LIST, Obeo.
+ * Copyright (c) 2022, 2024 CEA LIST.
  *
- * All rights reserved. This program and the accompanying materials
+ * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
  * which accompanies this distribution, and is available at
  * https://www.eclipse.org/legal/epl-2.0/
@@ -13,29 +13,22 @@
  *****************************************************************************/
 package org.eclipse.papyrus.uml.domain.services.destroy;
 
-import static java.util.stream.Collectors.toList;
-
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Optional;
 import java.util.Set;
-import java.util.stream.Stream;
 
 import org.eclipse.emf.common.util.EList;
 import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.EPackage;
 import org.eclipse.emf.ecore.EReference;
-import org.eclipse.emf.ecore.EStructuralFeature.Setting;
 import org.eclipse.emf.ecore.util.ECrossReferenceAdapter;
 import org.eclipse.papyrus.uml.domain.services.internal.helpers.CollaborationHelper;
-import org.eclipse.papyrus.uml.domain.services.internal.helpers.DurationConstraintHelper;
-import org.eclipse.papyrus.uml.domain.services.internal.helpers.DurationObservationHelper;
 import org.eclipse.papyrus.uml.domain.services.internal.helpers.OccurrenceSpecificationHelper;
-import org.eclipse.papyrus.uml.domain.services.internal.helpers.TimeConstraintHelper;
-import org.eclipse.papyrus.uml.domain.services.internal.helpers.TimeObservationHelper;
 import org.eclipse.papyrus.uml.domain.services.internal.helpers.UMLService;
+import org.eclipse.papyrus.uml.domain.services.internal.helpers.UMLTemporalHelper;
 import org.eclipse.uml2.uml.ActivityNode;
 import org.eclipse.uml2.uml.Association;
 import org.eclipse.uml2.uml.Classifier;
@@ -43,13 +36,13 @@ import org.eclipse.uml2.uml.Collaboration;
 import org.eclipse.uml2.uml.CombinedFragment;
 import org.eclipse.uml2.uml.Connector;
 import org.eclipse.uml2.uml.ConnectorEnd;
-import org.eclipse.uml2.uml.DestructionOccurrenceSpecification;
 import org.eclipse.uml2.uml.DirectedRelationship;
 import org.eclipse.uml2.uml.Element;
 import org.eclipse.uml2.uml.ExecutionSpecification;
-import org.eclipse.uml2.uml.Interaction;
 import org.eclipse.uml2.uml.InteractionFragment;
 import org.eclipse.uml2.uml.InteractionOperand;
+import org.eclipse.uml2.uml.Interval;
+import org.eclipse.uml2.uml.IntervalConstraint;
 import org.eclipse.uml2.uml.Lifeline;
 import org.eclipse.uml2.uml.Message;
 import org.eclipse.uml2.uml.MessageEnd;
@@ -59,10 +52,9 @@ import org.eclipse.uml2.uml.OccurrenceSpecification;
 import org.eclipse.uml2.uml.Package;
 import org.eclipse.uml2.uml.PartDecomposition;
 import org.eclipse.uml2.uml.Property;
-import org.eclipse.uml2.uml.TimeConstraint;
-import org.eclipse.uml2.uml.TimeObservation;
 import org.eclipse.uml2.uml.UMLPackage;
 import org.eclipse.uml2.uml.UseCase;
+import org.eclipse.uml2.uml.ValueSpecification;
 import org.eclipse.uml2.uml.Vertex;
 import org.eclipse.uml2.uml.util.UMLSwitch;
 
@@ -81,7 +73,7 @@ public class ElementDependencyCollector implements IDestroyerDependencyCollector
 
     /**
      * Constructor.
-     * 
+     *
      * @param theCrossReferenceAdapter
      *                                 an adapter used to get inverse references
      */
@@ -99,34 +91,39 @@ public class ElementDependencyCollector implements IDestroyerDependencyCollector
 
     static class DestroyDependencyCollectorSwitch extends UMLSwitch<Void> {
 
-        /**
-         * Adapter used to get inverse references.
-         */
+        /** Adapter used to get inverse references. */
         private final ECrossReferenceAdapter crossReferenceAdapter;
-        /**
-         * Set of dependences to remove.
-         */
+
+        /** Set of dependences to remove. */
         private final Set<EObject> dependentsToRemove = new HashSet<>();
 
         /**
+         * Default constructor.
+         *
          * @param crossReferenceAdapter
+         *                              cross reference adapter
          */
         DestroyDependencyCollectorSwitch(ECrossReferenceAdapter crossReferenceAdapter) {
-            super();
             this.crossReferenceAdapter = crossReferenceAdapter;
         }
 
+        private void safeAdd(Element value) {
+            if (value != null) {
+                dependentsToRemove.add(value);
+            }
+        }
+
         /**
          * Action to launch before deleting a {@link NamedElement}. Copy from
          * {@link org.eclipse.papyrus.uml.service.types.helper.advice.NamedElementHelperAdvice.getBeforeDestroyDependentsCommand(DestroyDependentsRequest)}
-         * 
+         *
          * <pre>
          * This method deletes {@link DirectedRelationship} related to the named element (source or target).
          * </pre>
-         * 
+         *
          * @param namedElementToDelete
          *                             the {@link NamedElement} to remove
-         * 
+         *
          */
         @Override
         public Void caseNamedElement(NamedElement namedElementToDelete) {
@@ -172,11 +169,11 @@ public class ElementDependencyCollector implements IDestroyerDependencyCollector
         /**
          * Action to launch before deleting a {@link ConnectorEnd}. Copy from
          * {@link org.eclipse.papyrus.uml.service.types.helper.advice.ConnectorEndHelperAdvice.getBeforeDestroyDependentsCommand(DestroyDependentsRequest))}
-         * 
+         *
          * <pre>
          * It deletes the related Connector in case this connector only has less than 2 ends left.
          * </pre>
-         * 
+         *
          * @param connectorEndToDelete
          *                             the {@link NamedElement} to remove
          */
@@ -192,10 +189,10 @@ public class ElementDependencyCollector implements IDestroyerDependencyCollector
         /**
          * Action to launch before deleting a {@link Property}. Copy from
          * {@link org.eclipse.papyrus.uml.service.types.helper.advice.PropertyHelperAdvice.getBeforeDestroyDependentsCommand(DestroyDependentsRequest)}
-         * 
+         *
          * @param propertyToDelete
          *                         the property to delete
-         * 
+         *
          */
         @Override
         public Void caseProperty(Property propertyToDelete) {
@@ -227,28 +224,7 @@ public class ElementDependencyCollector implements IDestroyerDependencyCollector
             return super.caseProperty(propertyToDelete);
         }
 
-        /**
-         * Action to launch before deleting a {@link Message}. Copy from
-         * {@link org.eclipse.papyrus.uml.service.types.helper.advice.MessageHelperAdvice.getBeforeDestroyDependentsCommand(DestroyDependentsRequest))}.
-         * <p>
-         * Deletes the related {@link MessageEnd} when they are set and not shared with
-         * other elements.
-         * 
-         * @param messageToDelete
-         *                        the {@link Message} to remove
-         */
-        @Override
-        public Void caseMessage(Message messageToDelete) {
-            MessageEnd sendEvent = messageToDelete.getSendEvent();
-            if (sendEvent != null && !(this.isSharedEvent(sendEvent, messageToDelete))) {
-                this.dependentsToRemove.add(sendEvent);
-            }
-            MessageEnd receiveEvent = messageToDelete.getReceiveEvent();
-            if (receiveEvent != null && !(this.isSharedEvent(receiveEvent, messageToDelete))) {
-                this.dependentsToRemove.add(receiveEvent);
-            }
-            return super.caseMessage(messageToDelete);
-        }
+
 
         @Override
         public Void caseElement(Element object) {
@@ -260,62 +236,19 @@ public class ElementDependencyCollector implements IDestroyerDependencyCollector
             return super.caseElement(object);
         }
 
-        /**
-         * Tests if the {@code messageEnd} is referenced by other elements than the
-         * known referencer (except its container).
-         * <p>
-         * This method ignores references from other metamodels. It also ignores
-         * {@link Lifeline} referencers that reference the {@code messageEnd} via the
-         * {@link UMLPackage#getLifeline_CoveredBy()} reference.
-         * <p>
-         * This code is copied from
-         * {@link org.eclipse.papyrus.uml.service.types.helper.advice.MessageHelperAdvice.isSharedEvent(MessageEnd,
-         * EObject))}.
-         * 
-         * @param messageEnd
-         *                        the message end to search the referencers from
-         * @param knownReferencer
-         *                        the known referencer to {@code messageEnd}
-         * @return {@code true} if the {@code messageEnd} is referenced by other
-         *         elements than the known referencer, {@code false} otherwise.
-         */
-        private boolean isSharedEvent(MessageEnd messageEnd, Message knownReferencer) {
-            EPackage mmPackage = messageEnd.eClass().getEPackage();
-
-            // Retrieve the list of elements referencing the messageEnd.
-            Set<EObject> crossReferences = new HashSet<EObject>();
-            for (Setting setting : this.crossReferenceAdapter.getInverseReferences(messageEnd)) {
-                EObject eObject = setting.getEObject();
-                if (!setting.getEStructuralFeature().equals(UMLPackage.eINSTANCE.getLifeline_CoveredBy())) {
-                    if (eObject.eClass().getEPackage().equals(mmPackage)) {
-                        crossReferences.add(eObject);
-                    }
-                }
-            }
-
-            // Remove the container of messageEnd.
-            crossReferences.remove(messageEnd.eContainer());
-            // Remove the knownReferencer from the list of references.
-            crossReferences.remove(knownReferencer);
-
-            // If no referencer remains in the list, the known element is the only usage and
-            // thus the messageEnd isn't shared.
-            return !(crossReferences.isEmpty());
-        }
-
         /**
          * Action to launch before deleting a {@link Classifier}. Copy from
          * {@link org.eclipse.papyrus.uml.service.types.helper.advice.ClassifierHelperAdvice.getBeforeDestroyDependentsCommand(DestroyDependentsRequest)}
-         * 
+         *
          * <pre>
          * This method deletes :
          * - Generalization related to the Classifier (source or target).
          * - Association related to the Classifier (source or target type).
          * </pre>
-         * 
+         *
          * @param classifierToDelete
          *                           the {@link Classifier} to remove
-         * 
+         *
          */
         @Override
         public Void caseClassifier(Classifier classifierToDelete) {
@@ -349,10 +282,10 @@ public class ElementDependencyCollector implements IDestroyerDependencyCollector
         /**
          * Action to launch before deleting a {@link Collaboration}. Copy from
          * {@link org.eclipse.papyrus.uml.service.types.helper.advice.CollaborationHelperAdvice.getBeforeDestroyDependentsCommand(DestroyDependentsRequest)}
-         * 
+         *
          * @param classifierToDelete
          *                           the {@link Collaboration} to remove
-         * 
+         *
          */
         @Override
         public Void caseCollaboration(Collaboration collaborationToDelete) {
@@ -361,33 +294,22 @@ public class ElementDependencyCollector implements IDestroyerDependencyCollector
             return super.caseCollaboration(collaborationToDelete);
         }
 
-        /**
-         * Action to launch before deleting a
-         * {@link DestructionOccurrenceSpecification}. Copy from
-         * {@link org.eclipse.papyrus.uml.service.types.helper.advice.DestructionOccurrenceSpecificationEditHelperAdvice.getBeforeDestroyDependentsCommand(DestroyDependentsRequest)}
-         * 
-         * @param destructionToDelete
-         *                            the {@link DestructionOccurrenceSpecification} to
-         *                            remove
-         */
         @Override
-        public Void caseDestructionOccurrenceSpecification(DestructionOccurrenceSpecification destructionToDelete) {
-            Interaction interaction = OccurrenceSpecificationHelper.getInteraction(destructionToDelete);
-
-            Stream<TimeConstraint> timeConstraints = OccurrenceSpecificationHelper.getTimeConstraints(interaction,
-                    destructionToDelete);
-            Stream<TimeObservation> timeObservations = OccurrenceSpecificationHelper.getTimeObservations(interaction,
-                    destructionToDelete);
-
-            this.dependentsToRemove.addAll(Stream.concat(timeConstraints, timeObservations).collect(toList()));
-            return super.caseDestructionOccurrenceSpecification(destructionToDelete);
-
+        public Void caseIntervalConstraint(IntervalConstraint interval) {
+            if (interval.getSpecification() instanceof Interval value) { // Only case allowed
+                for (ValueSpecification terminal : List.of(value.getMin(), value.getMax())) {
+                    if (terminal != null && UMLService.isOnlyUsage(terminal, value, crossReferenceAdapter)) {
+                        dependentsToRemove.add(terminal);
+                    }
+                }
+            }
+            return super.caseIntervalConstraint(interval);
         }
 
         /**
          * Action to launch before deleting a {@link ExecutionSpecification}. Copy from
          * {@link org.eclipse.papyrus.uml.service.types.helper.advice.ExecutionSpecificationHelperAdvice.getBeforeDestroyDependentsCommand(DestroyDependentsRequest)}
-         * 
+         *
          * @param esToDelete
          *                   the {@link ExecutionSpecification} to remove
          */
@@ -396,24 +318,47 @@ public class ElementDependencyCollector implements IDestroyerDependencyCollector
             // Check whether start - finish referenced OccurrenceSpecification should be
             // added to the dependents list
             OccurrenceSpecification osStart = esToDelete.getStart();
-            if (OccurrenceSpecificationHelper.shouldDestroyOccurrenceSpecification(esToDelete, osStart,
-                    this.crossReferenceAdapter) && (!(osStart instanceof MessageEnd))) {
+            if (OccurrenceSpecificationHelper.shouldDestroyWithExecution(esToDelete, osStart,
+                    this.crossReferenceAdapter)) {
                 this.dependentsToRemove.add(osStart);
             }
 
             OccurrenceSpecification osFinish = esToDelete.getFinish();
-            if (OccurrenceSpecificationHelper.shouldDestroyOccurrenceSpecification(esToDelete, osFinish,
-                    this.crossReferenceAdapter) && (!(osFinish instanceof MessageEnd))) {
+            if (OccurrenceSpecificationHelper.shouldDestroyWithExecution(esToDelete, osFinish,
+                    this.crossReferenceAdapter)) {
                 this.dependentsToRemove.add(osFinish);
             }
+            // add TimeElement and Duration
+            dependentsToRemove.addAll(UMLTemporalHelper.getTemporalElements(esToDelete, crossReferenceAdapter));
 
             return super.caseExecutionSpecification(esToDelete);
         }
 
+        /**
+         * Action to launch before deleting a {@link Message}. Copy from
+         * {@link org.eclipse.papyrus.uml.service.types.helper.advice.MessageHelperAdvice.getBeforeDestroyDependentsCommand(DestroyDependentsRequest))}.
+         * <p>
+         * Deletes the related {@link MessageEnd} when they are set and not shared with other elements.
+         *
+         * @param messageToDelete
+         *                        the {@link Message} to remove
+         */
+        @Override
+        public Void caseMessage(Message messageToDelete) {
+            safeAdd(messageToDelete.getReceiveEvent()); // Either MOS or Gate
+            safeAdd(messageToDelete.getSendEvent());
+
+            // add TimeElement and Duration
+            dependentsToRemove.addAll(UMLTemporalHelper.getTemporalElements(messageToDelete, crossReferenceAdapter));
+
+            return super.caseMessage(messageToDelete);
+        }
+
+
         /**
          * Action to launch before deleting a {@link Lifeline}. Copy from
          * {@link org.eclipse.papyrus.uml.service.types.helper.advice.LifelineHelperAdvice.getBeforeDestroyDependentsCommand(DestroyDependentsRequest)}
-         * 
+         *
          * @param lifelineToDelete
          *                         the {@link Lifeline} to remove
          */
@@ -425,16 +370,17 @@ public class ElementDependencyCollector implements IDestroyerDependencyCollector
                     this.dependentsToRemove.add(ift);
                 }
 
-                // Destroy related Message
-                // Destroy related Message
-                if ((ift instanceof MessageOccurrenceSpecification)
-                        && (((MessageOccurrenceSpecification) ift).getMessage() != null)) {
-                    this.dependentsToRemove.add(((MessageOccurrenceSpecification) ift).getMessage());
-                }
-
                 // Destroy covered OccurrenceSpecification
                 if (ift instanceof OccurrenceSpecification) {
                     this.dependentsToRemove.add(ift);
+                    // Destroy related Message
+                    if (ift instanceof MessageOccurrenceSpecification mos) {
+                        this.dependentsToRemove.add(mos.getMessage());
+                    }
+                }
+                // Destroy all the interactionFragments that cover only the lifeline being deleted
+                if (ift.getCovereds().size() == 1) {
+                    this.dependentsToRemove.add(ift);
                 }
             }
 
@@ -450,65 +396,28 @@ public class ElementDependencyCollector implements IDestroyerDependencyCollector
         /**
          * Action to launch before deleting a {@link OccurrenceSpecification}. Copy from
          * {@link org.eclipse.papyrus.uml.service.types.helper.advice.OccurrenceSpecificationHelperAdvice.getBeforeDestroyDependentsCommand(DestroyDependentsRequest)}
-         * 
+         *
          * <pre>
          * Add dependents to destroy :
          * - related time elements
          * - linked general ordering
          * </pre>
-         * 
+         *
          * @param osToDelete
          *                   the {@link OccurrenceSpecification} to remove
          */
         @Override
         public Void caseOccurrenceSpecification(OccurrenceSpecification osToDelete) {
-            // look for all Execution that references this Occurrence specification
-            InteractionFragment containerPackage = (InteractionFragment) osToDelete.getOwner();
-            if (containerPackage != null) {
-                Iterator<EObject> contentIterator = containerPackage.eAllContents();
-                while (contentIterator.hasNext()) {
-                    EObject currentEObject = contentIterator.next();
-                    if (currentEObject instanceof Message) {
-                        Message m = (Message) currentEObject;
-                        if (osToDelete.equals(m.getSendEvent())) {
-                            this.dependentsToRemove.add(m);
-                            if (m.getReceiveEvent() != null) {
-                                this.dependentsToRemove.add(m.getReceiveEvent());
-                            }
-                        }
-                        if (osToDelete.equals(m.getReceiveEvent())) {
-                            this.dependentsToRemove.add(m);
-                            if (m.getSendEvent() != null) {
-                                this.dependentsToRemove.add(m.getSendEvent());
-                            }
-                        }
-                    }
-                    if (currentEObject instanceof ExecutionSpecification) {
-                        ExecutionSpecification exec = (ExecutionSpecification) currentEObject;
-                        if (osToDelete.equals(exec.getStart())) {
-                            this.dependentsToRemove.add(exec);
-                            if (exec.getFinish() != null && !(exec.getFinish() instanceof MessageEnd)) {
-                                this.dependentsToRemove.add(exec.getFinish());
-                            }
-                        }
-                        if (osToDelete.equals(exec.getFinish())) {
-                            this.dependentsToRemove.add(exec);
-                            if (exec.getStart() != null && !(exec.getStart() instanceof MessageEnd)) {
-                                this.dependentsToRemove.add(exec.getStart());
-                            }
-                        }
-                    }
+            for (Optional<ExecutionSpecification> execution : List.of(
+                    OccurrenceSpecificationHelper.getExecutionFromStartOccurrence(osToDelete),
+                    OccurrenceSpecificationHelper.getExecutionFromFinishOccurrence(osToDelete))) {
+                if (execution.isPresent()) {
+                    dependentsToRemove.add(execution.get());
                 }
             }
+
             // delete linked time elements
-            this.dependentsToRemove
-                    .addAll(TimeObservationHelper.getTimeObservations(osToDelete, this.crossReferenceAdapter));
-            this.dependentsToRemove
-                    .addAll(TimeConstraintHelper.getTimeConstraintsOn(osToDelete, this.crossReferenceAdapter));
-            this.dependentsToRemove.addAll(
-                    DurationObservationHelper.getDurationObservationsOn(osToDelete, this.crossReferenceAdapter));
-            this.dependentsToRemove
-                    .addAll(DurationConstraintHelper.getDurationConstraintsOn(osToDelete, this.crossReferenceAdapter));
+            dependentsToRemove.addAll(UMLTemporalHelper.getTemporalElements(osToDelete, crossReferenceAdapter));
 
             // delete linked general ordering
             /**
@@ -522,6 +431,13 @@ public class ElementDependencyCollector implements IDestroyerDependencyCollector
             return super.caseOccurrenceSpecification(osToDelete);
         }
 
+        @Override
+        public Void caseMessageOccurrenceSpecification(MessageOccurrenceSpecification osToDelete) {
+            safeAdd(osToDelete.getMessage());
+
+            return super.caseMessageOccurrenceSpecification(osToDelete);
+        }
+
         /**
          * In the StateMachine, incoming and outgoing transitions are removed with the
          * Vertex (ex: State, PseudoState and InitialState)
@@ -536,10 +452,10 @@ public class ElementDependencyCollector implements IDestroyerDependencyCollector
         /**
          * Action to launch before deleting a {@link Association}. Copy from
          * {@link org.eclipse.papyrus.uml.service.types.helper.advice.AssociationEditHelperAdvice.getBeforeDestroyDependentsCommand(DestroyDependentsRequest)}
-         * 
+         *
          * @param association
          *                    the association to delete
-         * 
+         *
          */
         @Override
         public Void caseAssociation(Association association) {
diff --git a/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/destroy/ElementDestroyer.java b/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/destroy/ElementDestroyer.java
index 3e6a6d44947f9680b1ad9438fae2ec034e5f525e..96327d7c9550b80d41dfb47870ac5cd15e1780a1 100644
--- a/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/destroy/ElementDestroyer.java
+++ b/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/destroy/ElementDestroyer.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2022 CEA, Obeo.
+ * Copyright (c) 2022, 2024 CEA List, Obeo.
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v2.0
  * which accompanies this distribution, and is available at
@@ -44,7 +44,7 @@ public class ElementDestroyer implements IDestroyer {
 
     /**
      * Constructor.
-     * 
+     *
      * @param theCrossReferenceAdapter
      *                                 an adapter used to get inverse references
      */
@@ -58,7 +58,7 @@ public class ElementDestroyer implements IDestroyer {
 
     /**
      * Default Constructor.
-     * 
+     *
      * @param theCrossReferenceAdapter
      *                                 an adapter used to get inverse references
      * @return default Constructor.
@@ -80,7 +80,7 @@ public class ElementDestroyer implements IDestroyer {
 
     /**
      * Removes a semantic element value from its container. Inspired by
-     * 
+     *
      * @see org.eclipse.gmf.runtime.emf.type.core.edithelper.AbstractEditHelper#getEditCommand(IEditCommandRequest,
      *      IEditHelperAdvice[])
      *
@@ -122,30 +122,36 @@ public class ElementDestroyer implements IDestroyer {
         Set<EObject> notComputedDependencies = new LinkedHashSet<>();
 
         notComputedDependencies.add(semanticElement);
-
         while (!notComputedDependencies.isEmpty()) {
+            // Impossible to simply loop on 'notComputedDependencies'
+            // Collection is amended as element are analyzed.
 
+            // Remove First
             Iterator<EObject> iterator = notComputedDependencies.iterator();
             EObject toAnalyse = iterator.next();
             iterator.remove();
-            EMFUtils.eAllContentStreamWithSelf(toAnalyse).filter(e -> !toDeletes.contains(e)).forEach(e -> {
-                Set<EObject> itemDependencies = dependencyCollector.collectDependencies(e);
 
-                for (EObject o : itemDependencies) {
-                    if (!toDeletes.contains(o)) {
-                        notComputedDependencies.add(o);
-                    }
-                }
-                toDeletes.add(e);
-            });
+            EMFUtils.eAllContentStreamWithSelf(toAnalyse) // with all sub-elements
+                    .filter(e -> !toDeletes.contains(e)) // skip previous work
+                    .forEach(e -> {
+                        toDeletes.add(e);
+                        Set<EObject> itemDependencies = dependencyCollector.collectDependencies(e);
+                        // Amend Analysis
+                        for (EObject o : itemDependencies) {
+                            if (!toDeletes.contains(o)) {
+                                notComputedDependencies.add(o);
+                            }
+                        }
+                    });
         }
         return toDeletes;
     }
 
+
     /**
      * Tears down references to the object that we are destroying, from all other
      * objects in the resource set.
-     * 
+     *
      * @param destructee
      *                   the object being destroyed
      */
@@ -174,7 +180,7 @@ public class ElementDestroyer implements IDestroyer {
      * Tears down outgoing unidirectional references from the object being destroyed
      * to all other elements in the resource set. This is required so that
      * reverse-reference queries will not find the destroyed object.
-     * 
+     *
      * @param destructee
      *                   the object being destroyed
      */
diff --git a/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/drop/diagrams/SequenceExternalSourceToRepresentationDropBehaviorProvider.java b/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/drop/diagrams/SequenceExternalSourceToRepresentationDropBehaviorProvider.java
new file mode 100644
index 0000000000000000000000000000000000000000..a3e43119546881c4af7211dff75d1cdfca0f7ca8
--- /dev/null
+++ b/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/drop/diagrams/SequenceExternalSourceToRepresentationDropBehaviorProvider.java
@@ -0,0 +1,138 @@
+/*****************************************************************************
+ * Copyright (c) 2024 CEA LIST.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *  Obeo - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.domain.services.drop.diagrams;
+
+import java.util.Collections;
+import java.util.Set;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.util.ECrossReferenceAdapter;
+import org.eclipse.papyrus.uml.domain.services.EMFUtils;
+import org.eclipse.papyrus.uml.domain.services.IEditableChecker;
+import org.eclipse.papyrus.uml.domain.services.create.ElementConfigurer;
+import org.eclipse.papyrus.uml.domain.services.create.ElementCreator;
+import org.eclipse.papyrus.uml.domain.services.drop.DnDStatus;
+import org.eclipse.papyrus.uml.domain.services.drop.IExternalSourceToRepresentationDropBehaviorProvider;
+import org.eclipse.papyrus.uml.domain.services.modify.ElementFeatureModifier;
+import org.eclipse.uml2.uml.Interaction;
+import org.eclipse.uml2.uml.Lifeline;
+import org.eclipse.uml2.uml.Property;
+import org.eclipse.uml2.uml.Type;
+import org.eclipse.uml2.uml.UMLPackage;
+import org.eclipse.uml2.uml.util.UMLSwitch;
+
+/**
+ * Drop behavior provider of a semantic drop (from Model Explorer view) to a
+ * Sequence Diagram Element.
+ * 
+ * @author <a href="mailto:glenn.plouhinec@obeo.fr">Glenn Plouhinec</a>
+ */
+public class SequenceExternalSourceToRepresentationDropBehaviorProvider
+        implements IExternalSourceToRepresentationDropBehaviorProvider {
+
+    @Override
+    public DnDStatus drop(EObject droppedElement, EObject target, ECrossReferenceAdapter crossRef,
+            IEditableChecker editableChecker) {
+        return new SequenceDropInsideRepresentationBehaviorProviderSwitch(target, crossRef, editableChecker)
+                .doSwitch(droppedElement);
+    }
+
+    static class SequenceDropInsideRepresentationBehaviorProviderSwitch extends UMLSwitch<DnDStatus> {
+
+        private final EObject target;
+
+        private final ECrossReferenceAdapter crossRef;
+
+        private final IEditableChecker editableChecker;
+
+        SequenceDropInsideRepresentationBehaviorProviderSwitch(EObject target, ECrossReferenceAdapter crossRef,
+                IEditableChecker editableChecker) {
+            super();
+            this.target = target;
+            this.crossRef = crossRef;
+            this.editableChecker = editableChecker;
+        }
+
+        @Override
+        public DnDStatus caseProperty(Property property) {
+            if (this.target instanceof Interaction || this.target instanceof Lifeline) {
+                Lifeline lifeline = null;
+                Set<EObject> resultStatusElements;
+                if (this.target instanceof Interaction interaction) {
+                    // Drop a Property on an Interaction will create a Lifeline and type the Lifeline
+                    lifeline = createLifeline(interaction);
+                    resultStatusElements = Set.of(lifeline);
+                } else {
+                    // Drop a Property on a Lifeline will type the Lifeline
+                    lifeline = (Lifeline) this.target;
+                    resultStatusElements = Collections.emptySet();
+                }
+                lifeline.setRepresents(property);
+
+                return DnDStatus.createOKStatus(resultStatusElements);
+            }
+            return super.caseProperty(property);
+        }
+
+        @Override
+        public DnDStatus caseType(Type type) {
+            if (this.target instanceof Interaction || this.target instanceof Lifeline) {
+                Lifeline lifeline = null;
+                Property property = null;
+                Set<EObject> resultStatusElements;
+                if (this.target instanceof Interaction interaction) {
+                    // Drop a Classifier on an Interaction : create a new lifeline, a new Property
+                    // in the interaction typed by the dropped classifier and the new Lifeline will represent this property.
+                    property = createProperty(interaction);
+                    lifeline = createLifeline(interaction);
+                    resultStatusElements = Set.of(lifeline);
+                } else {
+                    // Drop a Classifier on a Lifeline : create a new Property in the interaction
+                    // typed by the dropped classifier and the target Lifeline will represent this property.
+                    property = createProperty(EMFUtils.getAncestor(Interaction.class, this.target));
+                    lifeline = (Lifeline) this.target;
+                    resultStatusElements = Collections.emptySet();
+                }
+                property.setType(type);
+                lifeline.setRepresents(property);
+
+                return DnDStatus.createOKStatus(resultStatusElements);
+            }
+            return super.caseType(type);
+        }
+
+        private ElementCreator initElementCreator() {
+            ElementFeatureModifier featureModifier = new ElementFeatureModifier(this.crossRef, this.editableChecker);
+            ElementCreator elementCreator = new ElementCreator(new ElementConfigurer(), featureModifier);
+            return elementCreator;
+        }
+
+        private Lifeline createLifeline(Interaction interaction) {
+            ElementCreator elementCreator = initElementCreator();
+            return (Lifeline) elementCreator.create(interaction, UMLPackage.eINSTANCE.getLifeline().getName(),
+                    UMLPackage.eINSTANCE.getInteraction_Lifeline().getName()).getElement();
+        }
+
+        private Property createProperty(Interaction parentInteraction) {
+            ElementCreator elementCreator = initElementCreator();
+            return (Property) elementCreator.create(parentInteraction, UMLPackage.eINSTANCE.getProperty().getName(),
+                    UMLPackage.eINSTANCE.getStructuredClassifier_OwnedAttribute().getName()).getElement();
+        }
+
+        @Override
+        public DnDStatus defaultCase(EObject obj) {
+            return DnDStatus.createFailingStatus("DnD is forbidden.", Collections.emptySet());
+        }
+    }
+}
diff --git a/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/drop/diagrams/SequenceExternalSourceToRepresentationDropChecker.java b/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/drop/diagrams/SequenceExternalSourceToRepresentationDropChecker.java
new file mode 100644
index 0000000000000000000000000000000000000000..5146686f4b1e4c2ae4930e8e8a3842358c900125
--- /dev/null
+++ b/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/drop/diagrams/SequenceExternalSourceToRepresentationDropChecker.java
@@ -0,0 +1,74 @@
+/*****************************************************************************
+ * Copyright (c) 2024 CEA LIST.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *  Obeo - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.domain.services.drop.diagrams;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.papyrus.uml.domain.services.drop.IExternalSourceToRepresentationDropChecker;
+import org.eclipse.papyrus.uml.domain.services.status.CheckStatus;
+import org.eclipse.uml2.uml.Interaction;
+import org.eclipse.uml2.uml.Lifeline;
+import org.eclipse.uml2.uml.Property;
+import org.eclipse.uml2.uml.Type;
+import org.eclipse.uml2.uml.util.UMLSwitch;
+
+/**
+ * Check semantic drop (from Explorer view) to a Sequence Diagram Element.
+ * 
+ * @author <a href="mailto:glenn.plouhinec@obeo.fr">Glenn Plouhinec</a>
+ */
+public class SequenceExternalSourceToRepresentationDropChecker implements IExternalSourceToRepresentationDropChecker {
+
+    @Override
+    public CheckStatus canDragAndDrop(EObject elementToDrop, EObject newSemanticContainer) {
+        return new SequenceDropInsideRepresentationCheckerSwitch(newSemanticContainer).doSwitch(elementToDrop);
+    }
+
+    static class SequenceDropInsideRepresentationCheckerSwitch extends UMLSwitch<CheckStatus> {
+
+        private final EObject target;
+
+        SequenceDropInsideRepresentationCheckerSwitch(EObject target) {
+            super();
+            this.target = target;
+        }
+
+        @Override
+        public CheckStatus caseProperty(Property property) {
+            final CheckStatus result;
+            if (this.target instanceof Lifeline || this.target instanceof Interaction) {
+                result = CheckStatus.YES;
+            } else {
+                result = CheckStatus.no("Property can only be drag and drop on an Interaction or a Lifeline.");
+            }
+            return result;
+        }
+
+        @Override
+        public CheckStatus caseType(Type type) {
+            final CheckStatus result;
+            if (this.target instanceof Lifeline || this.target instanceof Interaction) {
+                result = CheckStatus.YES;
+            } else {
+                result = CheckStatus.no("Type can only be drag and drop on an Interaction or a Lifeline.");
+            }
+            return result;
+        }
+
+        @Override
+        public CheckStatus defaultCase(EObject object) {
+            return CheckStatus.no("DnD is not authorized.");
+        }
+    }
+
+}
diff --git a/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/drop/diagrams/SequenceInternalSourceToRepresentationDropBehaviorProvider.java b/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/drop/diagrams/SequenceInternalSourceToRepresentationDropBehaviorProvider.java
new file mode 100644
index 0000000000000000000000000000000000000000..a2b33f537d046e3dad64a4c5ebbd39653158f03c
--- /dev/null
+++ b/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/drop/diagrams/SequenceInternalSourceToRepresentationDropBehaviorProvider.java
@@ -0,0 +1,101 @@
+/*****************************************************************************
+ * Copyright (c) 2024 CEA LIST.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *  Obeo - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.domain.services.drop.diagrams;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.util.ECrossReferenceAdapter;
+import org.eclipse.papyrus.uml.domain.services.IEditableChecker;
+import org.eclipse.papyrus.uml.domain.services.drop.IInternalSourceToRepresentationDropBehaviorProvider;
+import org.eclipse.papyrus.uml.domain.services.modify.ElementFeatureModifier;
+import org.eclipse.papyrus.uml.domain.services.modify.IFeatureModifier;
+import org.eclipse.papyrus.uml.domain.services.status.State;
+import org.eclipse.papyrus.uml.domain.services.status.Status;
+import org.eclipse.uml2.uml.Element;
+import org.eclipse.uml2.uml.util.UMLSwitch;
+
+/**
+ * Drop behavior provider of a diagram element to a Sequence Diagram Element.
+ * 
+ * @author <a href="mailto:glenn.plouhinec@obeo.fr">Glenn Plouhinec</a>
+ */
+public class SequenceInternalSourceToRepresentationDropBehaviorProvider
+        implements IInternalSourceToRepresentationDropBehaviorProvider {
+
+    @Override
+    public Status drop(EObject droppedElement, EObject oldContainer, EObject newContainer,
+            ECrossReferenceAdapter crossRef, IEditableChecker editableChecker) {
+        return new SequenceDropOutsideRepresentationBehaviorProviderSwitch(oldContainer, newContainer, crossRef,
+                editableChecker).doSwitch(droppedElement);
+    }
+
+    static class SequenceDropOutsideRepresentationBehaviorProviderSwitch extends UMLSwitch<Status> {
+
+        private final EObject oldContainer;
+
+        private final EObject newContainer;
+
+        private final ECrossReferenceAdapter crossRef;
+
+        private final IEditableChecker editableChecker;
+
+        /**
+         * Initializes the switch.
+         *
+         * @param oldContainer
+         *                        the old container of the element being dropped
+         * @param newContainer
+         *                        the new container of the element being dropped
+         * @param crossRef
+         *                        the cross referencer
+         * @param editableChecker
+         *                        the checker
+         */
+        SequenceDropOutsideRepresentationBehaviorProviderSwitch(EObject oldContainer, EObject newContainer,
+                ECrossReferenceAdapter crossRef, IEditableChecker editableChecker) {
+            super();
+            this.oldContainer = oldContainer;
+            this.newContainer = newContainer;
+            this.crossRef = crossRef;
+            this.editableChecker = editableChecker;
+        }
+
+        /**
+         * Default Behavior : UML element can be D&D by using the same reference
+         * containment.
+         *
+         * @see org.eclipse.uml2.uml.util.UMLSwitch#caseElement(org.eclipse.uml2.uml.Element)
+         *
+         * @param droppedElement
+         *                       the element to drop
+         * @return OK or Failing status according to the complete D&D.
+         */
+        @Override
+        public Status caseElement(Element droppedElement) {
+            Status dropStatus;
+            IFeatureModifier modifier = new ElementFeatureModifier(this.crossRef, this.editableChecker);
+            if (this.oldContainer != this.newContainer) {
+                String refName = droppedElement.eContainmentFeature().getName();
+                if (this.oldContainer.eClass().getEStructuralFeature(refName) != null
+                        && this.newContainer.eClass().getEStructuralFeature(refName) != null) {
+                    dropStatus = modifier.removeValue(this.oldContainer, refName, droppedElement);
+                    if (State.DONE == dropStatus.getState()) {
+                        dropStatus = modifier.addValue(this.newContainer, refName, droppedElement);
+                    }
+                    return dropStatus;
+                }
+            }
+            return super.caseElement(droppedElement);
+        }
+    }
+}
diff --git a/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/drop/diagrams/SequenceInternalSourceToRepresentationDropChecker.java b/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/drop/diagrams/SequenceInternalSourceToRepresentationDropChecker.java
new file mode 100644
index 0000000000000000000000000000000000000000..5572a2eda33eba31d93976636290648a28286c46
--- /dev/null
+++ b/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/drop/diagrams/SequenceInternalSourceToRepresentationDropChecker.java
@@ -0,0 +1,82 @@
+/*****************************************************************************
+ * Copyright (c) 2024 CEA LIST.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *  Obeo - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.domain.services.drop.diagrams;
+
+import java.text.MessageFormat;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.papyrus.uml.domain.services.drop.IInternalSourceToRepresentationDropChecker;
+import org.eclipse.papyrus.uml.domain.services.status.CheckStatus;
+import org.eclipse.uml2.uml.Comment;
+import org.eclipse.uml2.uml.Constraint;
+import org.eclipse.uml2.uml.Interaction;
+import org.eclipse.uml2.uml.InteractionOperand;
+import org.eclipse.uml2.uml.UMLPackage;
+import org.eclipse.uml2.uml.util.UMLSwitch;
+
+/**
+ * SourceToRepresentationDropChecker for Sequence diagram.
+ * 
+ * @author <a href="mailto:glenn.plouhinec@obeo.fr">Glenn Plouhinec</a>
+ */
+public class SequenceInternalSourceToRepresentationDropChecker implements IInternalSourceToRepresentationDropChecker {
+
+    private static final String DROP_ERROR_MSG = "{0} can only be drag and drop on {1}.";
+
+    private static final String COMA = ", ";
+
+    @Override
+    public CheckStatus canDragAndDrop(EObject elementToDrop, EObject newSemanticContainer) {
+        return new SequenceDropOutsideRepresentationCheckerSwitch(newSemanticContainer).doSwitch(elementToDrop);
+    }
+
+    static class SequenceDropOutsideRepresentationCheckerSwitch extends UMLSwitch<CheckStatus> {
+
+        private EObject newSemanticContainer;
+
+        SequenceDropOutsideRepresentationCheckerSwitch(EObject target) {
+            super();
+            this.newSemanticContainer = target;
+        }
+
+        @Override
+        public CheckStatus caseComment(Comment comment) {
+            final CheckStatus result;
+            if (this.newSemanticContainer instanceof Interaction
+                    || this.newSemanticContainer instanceof InteractionOperand) {
+                result = CheckStatus.YES;
+            } else {
+
+                result = CheckStatus.no(MessageFormat.format(DROP_ERROR_MSG, comment.eClass().getName(),
+                        UMLPackage.eINSTANCE.getInteraction().getName() + COMA
+                                + UMLPackage.eINSTANCE.getInteractionOperand().getName()));
+            }
+            return result;
+        }
+
+        @Override
+        public CheckStatus caseConstraint(Constraint constraint) {
+            final CheckStatus result;
+            if (this.newSemanticContainer instanceof Interaction
+                    || this.newSemanticContainer instanceof InteractionOperand) {
+                result = CheckStatus.YES;
+            } else {
+                result = CheckStatus.no(MessageFormat.format(DROP_ERROR_MSG, constraint.eClass().getName(),
+                        UMLPackage.eINSTANCE.getInteraction().getName() + COMA
+                                + UMLPackage.eINSTANCE.getInteractionOperand().getName()));
+            }
+            return result;
+        }
+    }
+}
diff --git a/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/internal/helpers/DurationConstraintHelper.java b/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/internal/helpers/DurationConstraintHelper.java
index 34560dcf5553e0200e28e473a1238dc57ca47584..dad1935f73c1787446a4874e6dd6605e507b43c1 100644
--- a/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/internal/helpers/DurationConstraintHelper.java
+++ b/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/internal/helpers/DurationConstraintHelper.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2022 CEA, Obeo.
+ * Copyright (c) 2022, 2024 CEA List, Obeo.
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v2.0
  * which accompanies this distribution, and is available at
@@ -12,21 +12,17 @@
  *******************************************************************************/
 package org.eclipse.papyrus.uml.domain.services.internal.helpers;
 
-import java.util.Collection;
-import java.util.LinkedList;
 import java.util.List;
 
-import org.eclipse.emf.ecore.EStructuralFeature.Setting;
 import org.eclipse.emf.ecore.util.ECrossReferenceAdapter;
 import org.eclipse.uml2.uml.DurationConstraint;
 import org.eclipse.uml2.uml.NamedElement;
-import org.eclipse.uml2.uml.UMLPackage;
 
 /**
  * This helper provides interesting features for DurationConstraint objects.
  * Copy from
  * {@link org.eclipse.papyrus.uml.diagram.common.helper.DurationConstraintHelper}
- * 
+ *
  * @author <a href="mailto:jessy.mallet@obeo.fr">Jessy Mallet</a>
  */
 public class DurationConstraintHelper {
@@ -34,25 +30,18 @@ public class DurationConstraintHelper {
     /**
      * Get the list of all DurationConstraint constraining a given element.
      *
+     * @deprecated Use UMLTemporalHelper instead.
      * @param element
      *                              the constrained element
      * @param crossReferenceAdapter
      *                              an adapter used to get inverse references
-     * 
+     *
      * @return list of DurationConstraint
      */
+    @Deprecated
     public static List<DurationConstraint> getDurationConstraintsOn(NamedElement element,
             ECrossReferenceAdapter crossReferenceAdapter) {
-        Collection<Setting> inverseReferences = crossReferenceAdapter.getInverseReferences(element, false);
-        // DurationConstraint referencing element
-        List<DurationConstraint> referencing = new LinkedList<DurationConstraint>();
-        for (Setting ref : inverseReferences) {
-            if (UMLPackage.eINSTANCE.getConstraint_ConstrainedElement().equals(ref.getEStructuralFeature())
-                    && ref.getEObject() instanceof DurationConstraint && ref.getEObject().eContainer() != null) {
-                referencing.add((DurationConstraint) ref.getEObject());
-            }
-        }
-        return referencing;
+        return UMLTemporalHelper.getDurationConstraints(element, crossReferenceAdapter);
     }
 
 }
diff --git a/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/internal/helpers/DurationObservationHelper.java b/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/internal/helpers/DurationObservationHelper.java
index c297480cbc8ebb726ae35428a3ddd3cd63685992..d7cabc9d490e09ceb8a8e828be91d6c56e558069 100644
--- a/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/internal/helpers/DurationObservationHelper.java
+++ b/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/internal/helpers/DurationObservationHelper.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2022 CEA, Obeo.
+ * Copyright (c) 2022, 2024 CEA List, Obeo.
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v2.0
  * which accompanies this distribution, and is available at
@@ -12,21 +12,17 @@
  *******************************************************************************/
 package org.eclipse.papyrus.uml.domain.services.internal.helpers;
 
-import java.util.Collection;
-import java.util.LinkedList;
 import java.util.List;
 
-import org.eclipse.emf.ecore.EStructuralFeature.Setting;
 import org.eclipse.emf.ecore.util.ECrossReferenceAdapter;
 import org.eclipse.uml2.uml.DurationObservation;
 import org.eclipse.uml2.uml.NamedElement;
-import org.eclipse.uml2.uml.UMLPackage;
 
 /**
  * This helper provides interesting features for DurationObservation objects.
  * Copy from
  * {@link org.eclipse.papyrus.uml.diagram.common.helper.DurationObservationHelper}
- * 
+ *
  * @author <a href="mailto:jessy.mallet@obeo.fr">Jessy Mallet</a>
  */
 public class DurationObservationHelper {
@@ -35,24 +31,17 @@ public class DurationObservationHelper {
      * Get the list of all DurationObservation observing duration from or to an
      * element.
      *
+     * @deprecated Use UMLTemporalHelper instead.
      * @param element
      *                              the observed element
      * @param crossReferenceAdapter
      *                              an adapter used to get inverse references
-     * 
+     *
      * @return list of DurationObservation
      */
+    @Deprecated
     public static List<DurationObservation> getDurationObservationsOn(NamedElement element,
             ECrossReferenceAdapter crossReferenceAdapter) {
-        Collection<Setting> inverseReferences = crossReferenceAdapter.getInverseReferences(element, false);
-        // DurationObservation referencing element
-        List<DurationObservation> referencing1 = new LinkedList<DurationObservation>();
-        for (Setting ref : inverseReferences) {
-            if (UMLPackage.eINSTANCE.getDurationObservation_Event().equals(ref.getEStructuralFeature())
-                    && ref.getEObject().eContainer() != null) {
-                referencing1.add((DurationObservation) ref.getEObject());
-            }
-        }
-        return referencing1;
+        return UMLTemporalHelper.getDurationObservations(element, crossReferenceAdapter);
     }
 }
diff --git a/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/internal/helpers/OccurrenceSpecificationHelper.java b/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/internal/helpers/OccurrenceSpecificationHelper.java
index f6e6b2adbf1f5989533e9da54c66a134d46b7d50..9f5edcc719cb3c13c2fda00f216a85255940934c 100644
--- a/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/internal/helpers/OccurrenceSpecificationHelper.java
+++ b/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/internal/helpers/OccurrenceSpecificationHelper.java
@@ -1,7 +1,7 @@
 /*****************************************************************************
- * Copyright (c) 2022, 2023 CEA LIST, Obeo.
+ * Copyright (c) 2022, 2024 CEA LIST.
  *
- * All rights reserved. This program and the accompanying materials
+ * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
  * which accompanies this distribution, and is available at
  * https://www.eclipse.org/legal/epl-2.0/
@@ -13,10 +13,14 @@
  *****************************************************************************/
 package org.eclipse.papyrus.uml.domain.services.internal.helpers;
 
+import java.util.Collection;
 import java.util.List;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.stream.Stream;
 
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature.Setting;
 import org.eclipse.emf.ecore.util.ECrossReferenceAdapter;
 import org.eclipse.uml2.common.util.CacheAdapter;
 import org.eclipse.uml2.uml.Constraint;
@@ -26,6 +30,7 @@ import org.eclipse.uml2.uml.ExecutionSpecification;
 import org.eclipse.uml2.uml.Interaction;
 import org.eclipse.uml2.uml.InteractionFragment;
 import org.eclipse.uml2.uml.Lifeline;
+import org.eclipse.uml2.uml.MessageOccurrenceSpecification;
 import org.eclipse.uml2.uml.NamedElement;
 import org.eclipse.uml2.uml.OccurrenceSpecification;
 import org.eclipse.uml2.uml.TimeConstraint;
@@ -34,14 +39,14 @@ import org.eclipse.uml2.uml.UMLPackage;
 
 /**
  * This helper provides some utils method on {@link OccurrenceSpecification}.
- * 
+ *
  * @author <a href="mailto:jessy.mallet@obeo.fr">Jessy Mallet</a>
  */
 public class OccurrenceSpecificationHelper {
 
     /**
      * Get interaction from a given {@link Element}.
-     * 
+     *
      * @param element
      *                the element attached to an interaction
      * @return its matching interaction.
@@ -59,8 +64,8 @@ public class OccurrenceSpecificationHelper {
     }
 
     /**
-     * Get time constraints in the contextual {@code interaction} that constrain
-     * only the {@code constrained} element and no others.
+     * Get time constraints in the contextual {@code interaction} that constrain only the {@code constrained} element
+     * and no others.
      *
      * @param interaction
      *                    the contextual interaction
@@ -74,16 +79,17 @@ public class OccurrenceSpecificationHelper {
             return Stream.empty();
         }
 
-        return CacheAdapter.getInstance().getNonNavigableInverseReferences(constrained).stream().filter(
-                setting -> setting.getEStructuralFeature() == UMLPackage.Literals.CONSTRAINT__CONSTRAINED_ELEMENT)
-                .map(setting -> (Constraint) setting.getEObject()).filter(TimeConstraint.class::isInstance)
-                .filter(c -> c.getConstrainedElements().size() == 1).filter(c -> getInteraction(c) == interaction)
+        return CacheAdapter.getInstance().getNonNavigableInverseReferences(constrained).stream()
+                .filter(setting -> setting.getEStructuralFeature() == UMLPackage.Literals.CONSTRAINT__CONSTRAINED_ELEMENT)
+                .map(setting -> (Constraint) setting.getEObject())
+                .filter(TimeConstraint.class::isInstance)
+                .filter(c -> c.getConstrainedElements().size() == 1)
+                .filter(c -> getInteraction(c) == interaction)
                 .map(TimeConstraint.class::cast);
     }
 
     /**
-     * Get time observations in the contextual {@code interaction} that reference
-     * the given {@code observed} element.
+     * Get time observations in the contextual {@code interaction} that reference the given {@code observed} element.
      *
      * @param interaction
      *                    the contextual interaction
@@ -116,18 +122,20 @@ public class OccurrenceSpecificationHelper {
      * </pre>
      *
      * @param es
-     *           {@link ExecutionSpecification} which references
-     *           {@link OccurrenceSpecification} (by means of #start/#finish
-     *           references)
+     *           {@link ExecutionSpecification} which references {@link OccurrenceSpecification} (by means of
+     *           #start/#finish references)
      * @param os
-     *           start or finish {@link OccurrenceSpecification} which defines the
-     *           duration of {@link ExecutionSpecification}
+     *           start or finish {@link OccurrenceSpecification} which defines the duration of
+     *           {@link ExecutionSpecification}
      * @return true in case {@link OccurrenceSpecification} should be destroyed
      */
-    public static boolean shouldDestroyOccurrenceSpecification(ExecutionSpecification es, OccurrenceSpecification os,
+    public static boolean shouldDestroyWithExecution(ExecutionSpecification es, OccurrenceSpecification os,
             ECrossReferenceAdapter crossReferenceAdapter) {
-        return os instanceof ExecutionOccurrenceSpecification
-                || (os != null && UMLService.isOnlyUsage(os, es, crossReferenceAdapter));
+        return os != null //
+                && !(os instanceof MessageOccurrenceSpecification)
+                && (os instanceof ExecutionOccurrenceSpecification
+                        // Strange case of unrelated event occurrence
+                        || UMLService.isOnlyUsage(os, es, crossReferenceAdapter));
     }
 
     /**
@@ -135,21 +143,20 @@ public class OccurrenceSpecificationHelper {
      * <p>
      * This element can be:
      * <ul>
-     * <li>An {@link ExecutionSpecification} if the {@code occurrenceSpecification}
-     * is positioned between the {@link ExecutionSpecification#getStart()} and
-     * {@link ExecutionSpecification#getFinish()} occurrences in the enclosing
-     * {@link Interaction#getFragments()}
-     * <li>It's first covered {@link Lifeline} otherwise (see
-     * {@link OccurrenceSpecification#getCovereds()})
-     * 
+     * <li>An {@link ExecutionSpecification} if the {@code occurrenceSpecification} is positioned between the
+     * {@link ExecutionSpecification#getStart()} and {@link ExecutionSpecification#getFinish()} occurrences in the
+     * enclosing {@link Interaction#getFragments()}, or if {@code occurrenceSpecification} is the start or finish of the
+     * execution.</li>
+     * <li>It's first covered {@link Lifeline} otherwise (see {@link OccurrenceSpecification#getCovereds()})</li>
+     * </ul>
+     * </p>
+     *
      * @param occurrenceSpecification
-     *                                the {@link OccurrenceSpecification} to
-     *                                retrieve the enclosing element from
+     *                                the {@link OccurrenceSpecification} to retrieve the enclosing element from
      * @return the element enclosing the {@code occurrenceSpecification}
-     * 
+     *
      * @throws NullPointerException
-     *                              if {@code occurrenceSpecification} is
-     *                              {@code null}
+     *                              if {@code occurrenceSpecification} is {@code null}
      */
     public static NamedElement findEnclosingElement(OccurrenceSpecification occurrenceSpecification) {
         Objects.requireNonNull(occurrenceSpecification);
@@ -176,20 +183,25 @@ public class OccurrenceSpecificationHelper {
                 fragments = List.of();
             }
 
-            ExecutionSpecification enclosingExecutionSpecification = null;
-            for (InteractionFragment fragment : fragments) {
-                if (fragment == occurrenceSpecification) {
-                    break;
-                } else if (fragment instanceof ExecutionSpecification) {
-                    enclosingExecutionSpecification = (ExecutionSpecification) fragment;
-                } else if (fragment instanceof OccurrenceSpecification) {
-                    OccurrenceSpecification occurrenceSpecificationFragment = (OccurrenceSpecification) fragment;
-                    if (enclosingExecutionSpecification != null && Objects
-                            .equals(enclosingExecutionSpecification.getFinish(), occurrenceSpecificationFragment)) {
-                        enclosingExecutionSpecification = null;
+            ExecutionSpecification enclosingExecutionSpecification = getStartingOrFinishingExecution(
+                    occurrenceSpecification);
+            if (enclosingExecutionSpecification == null) {
+                // The occurrence isn't the start/finish of an execution, iterate the fragments
+                // to find the execution wrapping it.
+                for (InteractionFragment fragment : fragments) {
+                    if (fragment == occurrenceSpecification) {
+                        break;
+                    } else if (fragment instanceof ExecutionSpecification) {
+                        enclosingExecutionSpecification = (ExecutionSpecification) fragment;
+                    } else if (fragment instanceof OccurrenceSpecification occurrenceSpecificationFragment) {
+                        if (enclosingExecutionSpecification != null && Objects
+                                .equals(enclosingExecutionSpecification.getFinish(), occurrenceSpecificationFragment)) {
+                            enclosingExecutionSpecification = null;
+                        }
                     }
                 }
             }
+
             if (enclosingExecutionSpecification != null) {
                 // Return the enclosing ExecutionSpecification if we found one, otherwise return
                 // the enclosing Lifeline
@@ -198,4 +210,87 @@ public class OccurrenceSpecificationHelper {
         }
         return enclosingElement;
     }
+
+    /**
+     * Returns the {@link ExecutionSpecification} that has {@code occurrence} as its {@code start} or {@code finish}.
+     *
+     * @param occurrence
+     *                   the {@link OccurrenceSpecification} to get the execution from
+     * @return the {@link ExecutionSpecification} if it exists, {@code null} otherwise
+     */
+    private static ExecutionSpecification getStartingOrFinishingExecution(OccurrenceSpecification occurrence) {
+        return getExecutionFromStartOccurrence(occurrence)
+                .orElseGet(() -> getExecutionFromFinishOccurrence(occurrence).orElse(null));
+    }
+
+    /**
+     * Returns {@code true} if {@code occurrence} is the start of an {@link ExecutionSpecification}.
+     *
+     * @param occurrence
+     *                   the {@link OccurrenceSpecification} to check
+     * @return {@code true} if {@code occurrence} is the start of an {@link ExecutionSpecification}
+     * @see #getExecutionFromStartOccurrence(OccurrenceSpecification)
+     */
+    public static boolean isExecutionStartOccurrence(OccurrenceSpecification occurrence) {
+        return getExecutionFromStartOccurrence(occurrence).isPresent();
+    }
+
+    /**
+     * Returns {@code true} if {@code occurrence} is the finish of an {@link ExecutionSpecification}.
+     *
+     * @param occurrence
+     *                   the {@link OccurrenceSpecification} to check
+     * @return {@code true} if {@code occurrence} is the finish of an {@link ExecutionSpecification}
+     * @see #getExecutionFromFinishOccurrence(OccurrenceSpecification)
+     */
+    public static boolean isExecutionFinishOccurrence(OccurrenceSpecification occurrence) {
+        return getExecutionFromFinishOccurrence(occurrence).isPresent();
+    }
+
+    /**
+     * Returns the {@link ExecutionSpecification} that contains {@code occurrence} as its start.
+     *
+     * @param occurrence
+     *                   the {@link OccurrenceSpecification} to check
+     * @return an {@link Optional} containing the {@link ExecutionSpecification}, or {@link Optional#empty()}
+     * @see #isExecutionStartOccurrence(OccurrenceSpecification)
+     */
+    public static Optional<ExecutionSpecification> getExecutionFromStartOccurrence(OccurrenceSpecification occurrence) {
+        return getExecutionFromOccurrence(occurrence, UMLPackage.eINSTANCE.getExecutionSpecification_Start());
+    }
+
+    /**
+     * Returns the {@link ExecutionSpecification} that contains {@code occurrence} as its finish.
+     *
+     * @param occurrence
+     *                   the {@link OccurrenceSpecification} to check
+     * @return an {@link Optional} containing the {@link ExecutionSpecification}, or {@link Optional#empty()}
+     * @see #isExecutionFinishOccurrence(OccurrenceSpecification)
+     */
+    public static Optional<ExecutionSpecification> getExecutionFromFinishOccurrence(
+            OccurrenceSpecification occurrence) {
+        return getExecutionFromOccurrence(occurrence, UMLPackage.eINSTANCE.getExecutionSpecification_Finish());
+    }
+
+    /**
+     * Returns the {@link ExecutionSpecification} that contains {@code occurrence} in its {@code executionReference}.
+     *
+     * @param occurrence
+     *                           the {@link OccurrenceSpecification} to check
+     * @param executionReference
+     *                           the {@link EReference} to check
+     * @return an {@link Optional} containing the {@link ExecutionSpecification}, or {@link Optional#empty()}
+     */
+    private static Optional<ExecutionSpecification> getExecutionFromOccurrence(OccurrenceSpecification occurrence,
+            EReference executionReference) {
+        // Cross referencer is required for transformation:
+        // Element may not be in the same container.
+        ECrossReferenceAdapter crossReferenceAdapter = ECrossReferenceAdapter.getCrossReferenceAdapter(occurrence);
+        Collection<Setting> settings = crossReferenceAdapter.getInverseReferences(occurrence, executionReference, true);
+        return settings.stream() // Reference
+                .map(Setting::getEObject) // source
+                .filter(ExecutionSpecification.class::isInstance) // adapt
+                .map(ExecutionSpecification.class::cast) // collect
+                .findFirst();
+    }
 }
diff --git a/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/internal/helpers/TimeConstraintHelper.java b/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/internal/helpers/TimeConstraintHelper.java
index c2dc981b6354410c5f406b45325d2d49b4eff3be..a58df9be354a16e458284d3a7e6bbe304bc83e42 100644
--- a/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/internal/helpers/TimeConstraintHelper.java
+++ b/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/internal/helpers/TimeConstraintHelper.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2022 CEA, Obeo.
+ * Copyright (c) 2022, 2024 CEA List, Obeo.
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v2.0
  * which accompanies this distribution, and is available at
@@ -12,21 +12,17 @@
  *******************************************************************************/
 package org.eclipse.papyrus.uml.domain.services.internal.helpers;
 
-import java.util.Collection;
-import java.util.LinkedList;
 import java.util.List;
 
-import org.eclipse.emf.ecore.EStructuralFeature.Setting;
 import org.eclipse.emf.ecore.util.ECrossReferenceAdapter;
 import org.eclipse.uml2.uml.NamedElement;
 import org.eclipse.uml2.uml.TimeConstraint;
-import org.eclipse.uml2.uml.UMLPackage;
 
 /**
  * This helper provides interesting features for TimeConstraint objects. Copy
  * from
  * {@link org.eclipse.papyrus.uml.diagram.common.helper.TimeConstraintHelper}
- * 
+ *
  * @author <a href="mailto:jessy.mallet@obeo.fr">Jessy Mallet</a>
  */
 public class TimeConstraintHelper {
@@ -34,24 +30,17 @@ public class TimeConstraintHelper {
     /**
      * Get the list of all TimeConstraint constraining a given element.
      *
+     * @deprecated Use UMLTemporalHelper instead.
      * @param element
      *                              the constrained element
      * @param crossReferenceAdapter
      *                              an adapter used to get inverse references
-     * 
+     *
      * @return list of TimeConstraint
      */
+    @Deprecated
     public static List<TimeConstraint> getTimeConstraintsOn(NamedElement element,
             ECrossReferenceAdapter crossReferenceAdapter) {
-        Collection<Setting> inverseReferences = crossReferenceAdapter.getInverseReferences(element, false);
-        // TimeConstraint referencing element
-        List<TimeConstraint> referencing = new LinkedList<>();
-        for (Setting ref : inverseReferences) {
-            if (UMLPackage.eINSTANCE.getConstraint_ConstrainedElement().equals(ref.getEStructuralFeature())
-                    && ref.getEObject() instanceof TimeConstraint && ref.getEObject().eContainer() != null) {
-                referencing.add((TimeConstraint) ref.getEObject());
-            }
-        }
-        return referencing;
+        return UMLTemporalHelper.getTimeConstraints(element, crossReferenceAdapter);
     }
 }
diff --git a/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/internal/helpers/TimeObservationHelper.java b/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/internal/helpers/TimeObservationHelper.java
index 9bffbce5990d27f53e40fd5911410c08b00417a1..21aef28fe28aa0a0209f0a74f6bff4f0a28cb658 100644
--- a/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/internal/helpers/TimeObservationHelper.java
+++ b/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/internal/helpers/TimeObservationHelper.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2022 CEA, Obeo.
+ * Copyright (c) 2022, 2024 CEA List, Obeo.
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v2.0
  * which accompanies this distribution, and is available at
@@ -12,21 +12,17 @@
  *******************************************************************************/
 package org.eclipse.papyrus.uml.domain.services.internal.helpers;
 
-import java.util.Collection;
-import java.util.LinkedList;
 import java.util.List;
 
-import org.eclipse.emf.ecore.EStructuralFeature.Setting;
 import org.eclipse.emf.ecore.util.ECrossReferenceAdapter;
 import org.eclipse.uml2.uml.NamedElement;
 import org.eclipse.uml2.uml.TimeObservation;
-import org.eclipse.uml2.uml.UMLPackage;
 
 /**
  * This helper provides interesting features for TimeObservation objects. Copy
  * from
  * {@link org.eclipse.papyrus.uml.diagram.common.helper.TimeObservationHelper}
- * 
+ *
  * @author <a href="mailto:jessy.mallet@obeo.fr">Jessy Mallet</a>
  */
 public class TimeObservationHelper {
@@ -34,24 +30,17 @@ public class TimeObservationHelper {
     /**
      * Get the list of all TimeObservation observing a given element.
      *
+     * @deprecated Use UMLTemporalHelper instead.
      * @param element
      *                              the observed element
      * @param crossReferenceAdapter
      *                              an adapter used to get inverse references
-     * 
+     *
      * @return list of TimeObservation
      */
+    @Deprecated
     public static List<TimeObservation> getTimeObservations(NamedElement element,
             ECrossReferenceAdapter crossReferenceAdapter) {
-        Collection<Setting> inverseReferences = crossReferenceAdapter.getInverseReferences(element, false);
-        // TimeConstraint referencing element
-        List<TimeObservation> referencing = new LinkedList<TimeObservation>();
-        for (Setting ref : inverseReferences) {
-            if (UMLPackage.eINSTANCE.getTimeObservation_Event().equals(ref.getEStructuralFeature())
-                    && ref.getEObject().eContainer() != null) {
-                referencing.add((TimeObservation) ref.getEObject());
-            }
-        }
-        return referencing;
+        return UMLTemporalHelper.getTimeObservations(element, crossReferenceAdapter);
     }
 }
diff --git a/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/internal/helpers/UMLService.java b/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/internal/helpers/UMLService.java
index 335c2ced64303ced973f4a9788fa19b1b67db2d2..fdf0bac8f09b51b58cb2097228273e1d98f60841 100644
--- a/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/internal/helpers/UMLService.java
+++ b/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/internal/helpers/UMLService.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2022, 2023 CEA, Obeo
+ * Copyright (c) 2022, 2024 CEA List, Obeo.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -18,10 +18,8 @@ import static java.util.stream.Collectors.toList;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Set;
 import java.util.function.Predicate;
 import java.util.stream.Stream;
 
@@ -29,7 +27,6 @@ import org.eclipse.emf.common.notify.Notifier;
 import org.eclipse.emf.common.util.EList;
 import org.eclipse.emf.ecore.EClass;
 import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.EPackage;
 import org.eclipse.emf.ecore.EReference;
 import org.eclipse.emf.ecore.EStructuralFeature;
 import org.eclipse.emf.ecore.EStructuralFeature.Setting;
@@ -42,6 +39,7 @@ import org.eclipse.uml2.uml.CombinedFragment;
 import org.eclipse.uml2.uml.Element;
 import org.eclipse.uml2.uml.Interaction;
 import org.eclipse.uml2.uml.InteractionOperand;
+import org.eclipse.uml2.uml.UMLPackage;
 
 /**
  * Generic service for UML metamodel.
@@ -100,14 +98,14 @@ public class UMLService {
         }
     }
 
-    
+
     public static Stream<Resource> getUmlResources(EList<Resource> resources) {
         return resources.stream().filter(r -> !r.getContents().isEmpty() && r.getContents().get(0) instanceof Element);
     }
 
     /**
      * Check if a given {@link EObject} is an Interaction container.
-     * 
+     *
      * @param object
      *               the Object to check
      * @return <code>true</code> if the given {@link EObject} is an Interaction
@@ -123,7 +121,7 @@ public class UMLService {
      * all referencers of a particular element. The search can be narrowed down by
      * passing the list of Reference features to match. <code>features</code> can be
      * null.
-     * 
+     *
      * @param eObject
      *                 The referenced object.
      * @param features
@@ -177,29 +175,19 @@ public class UMLService {
      */
     public static boolean isOnlyUsage(EObject usedObject, EObject knownReferencer,
             ECrossReferenceAdapter crossReferenceAdapter) {
-        boolean isUsed = false;
-        EPackage mmPackage = usedObject.eClass().getEPackage();
+        EObject container = usedObject.eContainer();
 
-        // Retrieve the list of elements referencing the usedObject.
-        Set<EObject> crossReferences = new HashSet<>();
         for (Setting setting : crossReferenceAdapter.getInverseReferences(usedObject, false)) {
             EObject eObj = setting.getEObject();
-            if (eObj.eClass().getEPackage().equals(mmPackage)) {
-                crossReferences.add(eObj);
+            if (eObj.eClass().getEPackage() == UMLPackage.eINSTANCE
+                    // ignore accessible through remote navigation
+                    && !setting.getEStructuralFeature().isDerived()
+                    // Ignore well known references
+                    && eObj != knownReferencer && eObj != container) {
+                return false;
             }
         }
 
-        // Remove the container of used object.
-        crossReferences.remove(usedObject.eContainer());
-        // Remove the knownReferencer from the list of references.
-        crossReferences.remove(knownReferencer);
-
-        // If no referencer remains in the list, the known element is the only
-        // usage.
-        if (crossReferences.isEmpty()) {
-            isUsed = true;
-        }
-
-        return isUsed;
+        return true;
     }
 }
diff --git a/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/internal/helpers/UMLTemporalHelper.java b/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/internal/helpers/UMLTemporalHelper.java
new file mode 100644
index 0000000000000000000000000000000000000000..2f1d07189399aaf78370c05aef24bf8bf26ebd7f
--- /dev/null
+++ b/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/internal/helpers/UMLTemporalHelper.java
@@ -0,0 +1,224 @@
+/*******************************************************************************
+ * Copyright (c) 2024 CEA LIST.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *  Obeo - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.papyrus.uml.domain.services.internal.helpers;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature.Setting;
+import org.eclipse.emf.ecore.util.ECrossReferenceAdapter;
+import org.eclipse.uml2.uml.DurationConstraint;
+import org.eclipse.uml2.uml.DurationObservation;
+import org.eclipse.uml2.uml.NamedElement;
+import org.eclipse.uml2.uml.PackageableElement;
+import org.eclipse.uml2.uml.TimeConstraint;
+import org.eclipse.uml2.uml.TimeObservation;
+import org.eclipse.uml2.uml.UMLPackage;
+
+/**
+ * This helper provides interesting features for DurationConstraint objects.
+ * Copy from
+ * {@link org.eclipse.papyrus.uml.diagram.common.helper.DurationConstraintHelper}
+ *
+ * @author <a href="mailto:nicolas.peransin@obeo.fr">Nicolas Peransin</a>
+ */
+public class UMLTemporalHelper {
+
+    private static final UMLPackage UML = UMLPackage.eINSTANCE;
+
+    /**
+     * Descriptions of temporal relationship.
+     */
+    private enum TemporalRelation {
+
+        /** Reference of TimeObservation. */
+        timeObservation(TimeObservation.class, UML.getTimeObservation_Event()),
+        /** Reference of DurationObservation. */
+        durationObservation(DurationObservation.class, UML.getDurationObservation_Event()),
+        /** Reference of TimeConstraint. */
+        timeConstraint(TimeConstraint.class, UML.getConstraint_ConstrainedElement()),
+        /** Reference of DurationConstraint. */
+        durationConstraint(DurationConstraint.class, UML.getConstraint_ConstrainedElement()),
+
+        /** Reference of TimeObservation and TimeConstraint. */
+        timeElement(List.of(TimeConstraint.class, TimeObservation.class), UML.getConstraint_ConstrainedElement(),
+                UML.getTimeObservation_Event()),
+        /** Reference of DurationConstraint and DurationObservation. */
+        durationElement(List.of(DurationConstraint.class, DurationObservation.class),
+                UML.getConstraint_ConstrainedElement(), UML.getTimeObservation_Event()),
+
+        /** Reference of all temporal indications. */
+        all(List.of(TimeConstraint.class, DurationConstraint.class, TimeObservation.class, DurationObservation.class), // PackageableElement
+                UML.getConstraint_ConstrainedElement(), UML.getDurationObservation_Event(),
+                UML.getTimeObservation_Event());
+
+        /** Filter based on type of referencing element. */
+        private Predicate<EObject> typeFilter;
+        /** Filter based on reference of referencing element. */
+        private final Predicate<Setting> referencefilter;
+
+        /**
+         * Constructor with single type.
+         *
+         * @param type
+         *                  class of the relation
+         * @param reference
+         *                  EMF reference
+         */
+        TemporalRelation(Class<? extends PackageableElement> type, EReference reference) {
+            this(Collections.singletonList(type), reference);
+        }
+
+        /**
+         * Constructor for multiple type.
+         *
+         * @param subTypes
+         *                  classes of the relation
+         * @param reference
+         *                  EMF reference
+         */
+        TemporalRelation(List<? extends Class<? extends PackageableElement>> subTypes,
+                EReference... references) {
+
+            Collection<EReference> refs = Arrays.asList(references);
+            referencefilter = setting -> refs.contains(setting.getEStructuralFeature());
+            typeFilter = value -> {
+                for (Class<?> subType : subTypes) {
+                    if (subType.isInstance(value)) {
+                        return true;
+                    }
+                }
+                return false;
+            };
+        }
+
+        @SuppressWarnings("unchecked") // private call will ensure compatibility
+        private <R extends PackageableElement> List<R> getRelatedElements(NamedElement element,
+                ECrossReferenceAdapter crossRef) {
+            return (List<R>) crossRef.getInverseReferences(element, false) // references
+                    .stream() // filtering
+                    .filter(referencefilter) // right relation
+                    .map(Setting::getEObject) // To target
+                    .filter(typeFilter) // With expected type
+                    .collect(Collectors.toList());
+        }
+    }
+
+    /**
+     * Returns all {@link DurationConstraint}s constraining a given element.
+     *
+     * @param element
+     *                 the constrained element
+     * @param crossRef
+     *                 an adapter used to get inverse references
+     *
+     * @return list of DurationConstraints
+     */
+    public static List<DurationConstraint> getDurationConstraints(NamedElement element,
+            ECrossReferenceAdapter crossRef) {
+        return TemporalRelation.durationConstraint.getRelatedElements(element, crossRef);
+    }
+
+    /**
+     * Returns all {@link TimeConstraint}s constraining a given element.
+     *
+     * @param element
+     *                 the constrained element
+     * @param crossRef
+     *                 an adapter used to get inverse references
+     *
+     * @return list of TimeConstraints
+     */
+    public static List<TimeConstraint> getTimeConstraints(NamedElement element, ECrossReferenceAdapter crossRef) {
+        return TemporalRelation.timeConstraint.getRelatedElements(element, crossRef);
+    }
+
+    /**
+     * Returns all {@link DurationObservation}s constraining a given element.
+     *
+     * @param element
+     *                 the constrained element
+     * @param crossRef
+     *                 an adapter used to get inverse references
+     *
+     * @return list of DurationObservations
+     */
+    public static List<DurationObservation> getDurationObservations(NamedElement element,
+            ECrossReferenceAdapter crossRef) {
+        return TemporalRelation.durationObservation.getRelatedElements(element, crossRef);
+    }
+
+    /**
+     * Returns all {@link TimeObservation}s constraining a given element.
+     *
+     * @param element
+     *                 the constrained element
+     * @param crossRef
+     *                 an adapter used to get inverse references
+     *
+     * @return list of TimeObservations
+     */
+    public static List<TimeObservation> getTimeObservations(NamedElement element, ECrossReferenceAdapter crossRef) {
+        return TemporalRelation.timeObservation.getRelatedElements(element, crossRef);
+    }
+
+    /**
+     * Returns all {@link TimeConstraint}s constraining a given element.
+     *
+     * @param element
+     *                 the constrained element
+     * @param crossRef
+     *                 an adapter used to get inverse references
+     *
+     * @return list of TimeConstraints
+     */
+    public static List<PackageableElement> getTemporalElements(NamedElement element, ECrossReferenceAdapter crossRef) {
+        return TemporalRelation.all.getRelatedElements(element, crossRef);
+    }
+
+    /**
+     * Returns all time {@link PackageableElement}s related to a given element.
+     *
+     * @param element
+     *                 the constrained element
+     * @param crossRef
+     *                 an adapter used to get inverse references
+     *
+     * @return list of PackageableElement
+     */
+    public static List<PackageableElement> getTimeElements(NamedElement element, ECrossReferenceAdapter crossRef) {
+        return TemporalRelation.timeElement.getRelatedElements(element, crossRef);
+    }
+
+    /**
+     * Returns all duration {@link PackageableElement}s related to a given element.
+     *
+     * @param element
+     *                 the constrained element
+     * @param crossRef
+     *                 an adapter used to get inverse references
+     *
+     * @return list of PackageableElement
+     */
+    public static List<PackageableElement> getDurationElements(NamedElement element, ECrossReferenceAdapter crossRef) {
+        return TemporalRelation.durationElement.getRelatedElements(element, crossRef);
+    }
+
+}
diff --git a/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/labels/ElementLabelProvider.java b/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/labels/ElementLabelProvider.java
index c0e24ab0daa29719f535e4263cb284a0964b012f..b2e8af66caf5680ea75dbf2bed9b28ecb7a15797 100644
--- a/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/labels/ElementLabelProvider.java
+++ b/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/labels/ElementLabelProvider.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2022, 2023, 2024 CEA LIST, Obeo, Artal Technologies.
+ * Copyright (c) 2022, 2024 CEA LIST, Obeo, Artal Technologies.
  *
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -17,7 +17,6 @@ package org.eclipse.papyrus.uml.domain.services.labels;
 import static org.eclipse.papyrus.uml.domain.services.labels.UMLCharacters.CLOSE_ANGLE_BRACKET;
 import static org.eclipse.papyrus.uml.domain.services.labels.UMLCharacters.CLOSE_BRACKET;
 import static org.eclipse.papyrus.uml.domain.services.labels.UMLCharacters.D_DOTS;
-import static org.eclipse.papyrus.uml.domain.services.labels.UMLCharacters.EMPTY;
 import static org.eclipse.papyrus.uml.domain.services.labels.UMLCharacters.EOL;
 import static org.eclipse.papyrus.uml.domain.services.labels.UMLCharacters.EQL;
 import static org.eclipse.papyrus.uml.domain.services.labels.UMLCharacters.OPEN_ANGLE_BRACKET;
@@ -26,6 +25,7 @@ import static org.eclipse.papyrus.uml.domain.services.labels.UMLCharacters.SPACE
 import static org.eclipse.papyrus.uml.domain.services.labels.UMLCharacters.ST_LEFT;
 import static org.eclipse.papyrus.uml.domain.services.labels.UMLCharacters.ST_RIGHT;
 
+import java.util.Objects;
 import java.util.function.Function;
 import java.util.stream.Collectors;
 
@@ -51,17 +51,17 @@ import org.eclipse.uml2.uml.ConditionalNode;
 import org.eclipse.uml2.uml.ConnectableElement;
 import org.eclipse.uml2.uml.Constraint;
 import org.eclipse.uml2.uml.Duration;
+import org.eclipse.uml2.uml.DurationObservation;
 import org.eclipse.uml2.uml.Element;
 import org.eclipse.uml2.uml.ExpansionKind;
 import org.eclipse.uml2.uml.ExpansionRegion;
-import org.eclipse.uml2.uml.Expression;
 import org.eclipse.uml2.uml.InformationFlow;
 import org.eclipse.uml2.uml.InteractionConstraint;
 import org.eclipse.uml2.uml.InteractionOperand;
 import org.eclipse.uml2.uml.InteractionUse;
+import org.eclipse.uml2.uml.IntervalConstraint;
 import org.eclipse.uml2.uml.JoinNode;
 import org.eclipse.uml2.uml.Lifeline;
-import org.eclipse.uml2.uml.LiteralSpecification;
 import org.eclipse.uml2.uml.LoopNode;
 import org.eclipse.uml2.uml.NamedElement;
 import org.eclipse.uml2.uml.OpaqueExpression;
@@ -71,8 +71,10 @@ import org.eclipse.uml2.uml.Property;
 import org.eclipse.uml2.uml.Reception;
 import org.eclipse.uml2.uml.Region;
 import org.eclipse.uml2.uml.SequenceNode;
+import org.eclipse.uml2.uml.StateInvariant;
 import org.eclipse.uml2.uml.StructuredActivityNode;
 import org.eclipse.uml2.uml.TimeExpression;
+import org.eclipse.uml2.uml.TimeObservation;
 import org.eclipse.uml2.uml.Transition;
 import org.eclipse.uml2.uml.Type;
 import org.eclipse.uml2.uml.ValueSpecification;
@@ -170,22 +172,32 @@ public final class ElementLabelProvider implements IViewLabelProvider {
 
     static final class ElementLabelProviderSwitch extends UMLSwitch<String> {
 
-        private static final String WEIGHT = "weight";
+        private static final String REF = "ref";
 
-        private static final String CONDITIONAL = "conditional";
+        private static final String ASSIGNED = SPACE + EQL + SPACE;
 
-        private static final String SEQUENCE = "sequence";
+        private static final String WEIGHT = "weight" + EQL;
 
-        private static final String LOOP_NODE = "loop node";
+        private static final String CONDITIONAL = ST_LEFT + "conditional" + ST_RIGHT;
 
-        private static final String STRUCTURED = "structured";
+        private static final String SEQUENCE = ST_LEFT + "sequence" + ST_RIGHT;
 
-        private static final String JOIN_SPEC = "joinSpec";
+        private static final String LOOP_NODE = ST_LEFT + "loop node" + ST_RIGHT;
+
+        private static final String STRUCTURED = ST_LEFT + "structured" + ST_RIGHT;
+
+        private static final String JOIN_SPEC = "joinSpec" + ASSIGNED;
 
         private static final String NATURAL = "NATURAL";
 
         private static final String NULL_CONSTRAINT = "<NULL Constraint>";
 
+        private static final String TIME_OBSERVATION = ASSIGNED + "now";
+
+        private static final String DURATION_OBSERVATION = ASSIGNED + "duration";
+
+        private static final String TYPED = SPACE + D_DOTS + SPACE;
+
         private CollaborationUseLabelHelper collaborationUseLabelHelper;
 
         private PropertyLabelHelper propertyLabelHelper;
@@ -199,16 +211,12 @@ public final class ElementLabelProvider implements IViewLabelProvider {
         private ValueSpecificationLabelHelper valueSpecificationHelper;
 
         private final OperationLabelHelper operationLabelHelper;
-        
+
         private final ReceptionLabelHelper receptionLabelHelper;
 
-        ElementLabelProviderSwitch() {
-            this(null);
-        }
 
         ElementLabelProviderSwitch(INamedElementNameProvider namedElementNameProvider) {
-            super();
-            this.namedElementNameProvider = namedElementNameProvider;
+            this.namedElementNameProvider = Objects.requireNonNull(namedElementNameProvider);
             this.visibilityLabelHelper = new VisibilityLabelHelper();
             this.collaborationUseLabelHelper = new CollaborationUseLabelHelper(namedElementNameProvider,
                     this.visibilityLabelHelper);
@@ -278,7 +286,7 @@ public final class ElementLabelProvider implements IViewLabelProvider {
 
         @Override
         public String caseInteractionUse(InteractionUse interactionUse) {
-            return "ref";
+            return REF;
         }
 
         private String getConveyeds(EList<Classifier> conveyeds) {
@@ -317,45 +325,65 @@ public final class ElementLabelProvider implements IViewLabelProvider {
         @Override
         public String caseConstraint(Constraint constraint) {
             StringBuilder constLabel = new StringBuilder();
-            String body = EMPTY;
-            String lang = EMPTY;
-            ValueSpecification valueSpec = constraint.getSpecification();
             constLabel.append(constraint.getName());
             constLabel.append(EOL);
-            constLabel.append(OPEN_BRACKET);
-            if (valueSpec == null) {
-                constLabel.append(NULL_CONSTRAINT);
-            } else if (valueSpec instanceof OpaqueExpression) {
-                OpaqueExpression opaqueEsp = (OpaqueExpression) valueSpec;
-                if (!opaqueEsp.getBodies().isEmpty() && !opaqueEsp.getLanguages().isEmpty()) {
-                    body = opaqueEsp.getBodies().get(0);
-                    lang = opaqueEsp.getLanguages().get(0);
-                    constLabel.append(OPEN_BRACKET);
-                    constLabel.append(lang);
-                    constLabel.append(CLOSE_BRACKET);
-                    constLabel.append(SPACE);
-                    constLabel.append(body);
+
+            ValueSpecification value = constraint.getSpecification();
+            String specLabel;
+            if (value == null) {
+                specLabel = NULL_CONSTRAINT;
+            } else if (value instanceof OpaqueExpression expression) {
+                if (!expression.getBodies().isEmpty()) {
+                    String lang = expression.getLanguages().get(0);
+                    specLabel = expression.getBodies().get(0);
+                    if (!lang.isEmpty()) { // if language is available, prefix the label.
+                        specLabel = encloseInBrackets(lang) + SPACE + specLabel;
+                    }
                 } else {
-                    constLabel.append(OPEN_BRACKET);
-                    constLabel.append(NATURAL);
-                    constLabel.append(CLOSE_BRACKET);
-                    constLabel.append(SPACE);
+                    specLabel = encloseInBrackets(NATURAL) + SPACE;
                 }
+            } else {
+                specLabel = valueSpecificationHelper.getSpecificationValue(value, false);
             }
-            constLabel.append(CLOSE_BRACKET);
-            return constLabel.toString();
+
+            return encloseInBrackets(specLabel, constLabel).toString();
         }
 
         @Override
         public String caseOperation(Operation operation) {
             return this.operationLabelHelper.getLabel(operation);
         }
-        
+
         @Override
         public String caseReception(Reception reception) {
             return this.receptionLabelHelper.getLabel(reception);
         }
 
+        @Override
+        public String caseStateInvariant(StateInvariant stateInvariant) {
+            ValueSpecification value = null;
+            if (stateInvariant.getInvariant() != null) {
+                value = stateInvariant.getInvariant().getSpecification();
+            }
+            return getValueBasedLabel(stateInvariant, value);
+        }
+
+        @Override
+        public String caseDurationObservation(DurationObservation object) {
+            return namedElementNameProvider.getName(object) + DURATION_OBSERVATION;
+        }
+
+        @Override
+        public String caseTimeObservation(TimeObservation object) {
+            return namedElementNameProvider.getName(object) + TIME_OBSERVATION;
+        }
+
+        @Override
+        public String caseIntervalConstraint(IntervalConstraint object) {
+            // Time and Duration constraint.
+            return getValueBasedLabel(object, object.getSpecification());
+        }
+
         @Override
         public String caseTimeExpression(TimeExpression timeExpression) {
             StringBuilder constLabel = new StringBuilder();
@@ -408,11 +436,8 @@ public final class ElementLabelProvider implements IViewLabelProvider {
             StringBuilder constLabel = new StringBuilder();
             ValueSpecification joinSpec = joinNode.getJoinSpec();
             if (joinSpec != null) {
-                constLabel.append(OPEN_BRACKET);
-                constLabel.append(JOIN_SPEC);
-                constLabel.append(SPACE + EQL + SPACE);
-                constLabel.append(this.valueSpecificationHelper.getSpecificationValue(joinSpec, true));
-                constLabel.append(CLOSE_BRACKET);
+                encloseInBrackets(JOIN_SPEC + this.valueSpecificationHelper.getSpecificationValue(joinSpec, true),
+                        constLabel);
                 constLabel.append(EOL);
             }
             constLabel.append(this.namedElementNameProvider.getName(joinNode));
@@ -421,22 +446,22 @@ public final class ElementLabelProvider implements IViewLabelProvider {
 
         @Override
         public String caseStructuredActivityNode(StructuredActivityNode structuredActivityNode) {
-            return ST_LEFT + STRUCTURED + ST_RIGHT;
+            return STRUCTURED;
         }
 
         @Override
         public String caseLoopNode(LoopNode loopNode) {
-            return ST_LEFT + LOOP_NODE + ST_RIGHT;
+            return LOOP_NODE;
         }
 
         @Override
         public String caseSequenceNode(SequenceNode sequenceNode) {
-            return ST_LEFT + SEQUENCE + ST_RIGHT;
+            return SEQUENCE;
         }
 
         @Override
         public String caseConditionalNode(ConditionalNode conditionalNode) {
-            return ST_LEFT + CONDITIONAL + ST_RIGHT;
+            return CONDITIONAL;
         }
 
         @Override
@@ -445,30 +470,25 @@ public final class ElementLabelProvider implements IViewLabelProvider {
             ConnectableElement connectableElement = lifeline.getRepresents();
             ValueSpecification selector = lifeline.getSelector();
             if (connectableElement == null) {
-                if (!(selector instanceof LiteralSpecification) && !(selector instanceof Expression)
-                        && !(selector instanceof OpaqueExpression) && !(selector instanceof TimeExpression)) {
-                    String lifelineName = this.namedElementNameProvider.getName(lifeline);
-                    if (lifelineName != null) {
-                        lifelineLabel.append(lifelineName);
-                    }
+
+                String lifelineName = this.namedElementNameProvider.getName(lifeline);
+                if (lifelineName != null) {
+                    lifelineLabel.append(lifelineName);
                 }
+
             } else {
                 String connectableElementName = this.namedElementNameProvider.getName(connectableElement);
-                if (connectableElement != null) {
+                if (connectableElementName != null) {
                     lifelineLabel.append(connectableElementName);
                 }
                 if (selector != null) {
-                    if (selector instanceof LiteralSpecification) {
-                        lifelineLabel.append(OPEN_ANGLE_BRACKET);
-                        lifelineLabel.append(this.valueSpecificationHelper.getSpecificationValue(selector, true));
-                        lifelineLabel.append(CLOSE_ANGLE_BRACKET);
-                    }
+                    lifelineLabel.append(OPEN_ANGLE_BRACKET);
+                    lifelineLabel.append(this.valueSpecificationHelper.getSpecificationValue(selector, true));
+                    lifelineLabel.append(CLOSE_ANGLE_BRACKET);
                 }
                 Type type = connectableElement.getType();
-                if (type != null && type.getName() != null && type.getName().length() > 0) {
-                    lifelineLabel.append(SPACE);
-                    lifelineLabel.append(D_DOTS);
-                    lifelineLabel.append(SPACE);
+                if (type != null) {
+                    lifelineLabel.append(TYPED);
                     lifelineLabel.append(this.namedElementNameProvider.getName(type));
                 }
             }
@@ -485,10 +505,8 @@ public final class ElementLabelProvider implements IViewLabelProvider {
                 if (!objectFlowStringBuilder.isEmpty()) {
                     objectFlowStringBuilder.append(EOL);
                 }
-                objectFlowStringBuilder.append(OPEN_BRACKET);
-                objectFlowStringBuilder.append(WEIGHT + EQL);
-                objectFlowStringBuilder.append(this.valueSpecificationHelper.getSpecificationValue(weight, true));
-                objectFlowStringBuilder.append(CLOSE_BRACKET);
+                encloseInBrackets(WEIGHT + valueSpecificationHelper.getSpecificationValue(weight, true),
+                        objectFlowStringBuilder);
             }
             if (guard != null) {
                 if (!objectFlowStringBuilder.isEmpty()) {
@@ -500,6 +518,25 @@ public final class ElementLabelProvider implements IViewLabelProvider {
             }
             return objectFlowStringBuilder.toString();
         }
+
+        private String getValueBasedLabel(NamedElement element, ValueSpecification value) {
+            // Without content, show the name.
+            if (value == null) {
+                return namedElementNameProvider.getName(element);
+            }
+            return encloseInBrackets(valueSpecificationHelper.getSpecificationValue(value, false));
+        }
+    }
+
+    private static StringBuilder encloseInBrackets(String content, StringBuilder builder) {
+        builder.append(OPEN_BRACKET);
+        builder.append(content);
+        builder.append(CLOSE_BRACKET);
+        return builder;
+    }
+
+    private static String encloseInBrackets(String content) {
+        return encloseInBrackets(content, new StringBuilder()).toString();
     }
 
     public static Builder builder() {
diff --git a/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/labels/UMLCharacters.java b/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/labels/UMLCharacters.java
index 1a8b5259e115fc9d2436412e48f9538e2295a344..88aee9b809fb657f290c610549dfb928826fb39a 100644
--- a/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/labels/UMLCharacters.java
+++ b/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/labels/UMLCharacters.java
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (c) 2022, 2023 CEA LIST, Obeo.
+ * Copyright (c) 2022, 2024 CEA LIST, Obeo.
  *
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -43,7 +43,9 @@ public final class UMLCharacters {
 
     public static final String EQL = "="; //$NON-NLS-1$
 
-    public static final String EOL = System.lineSeparator();
+    // Do not use System line separator.
+    // Linux and Windows must edit model in the same way.
+    public static final String EOL = "\n"; //$NON-NLS-1$
 
     public static final String TILDE = "\u007E"; //$NON-NLS-1$
 
@@ -51,16 +53,18 @@ public final class UMLCharacters {
 
     public static final String OPEN_BRACKET = "{"; //$NON-NLS-1$
 
-    /**
-     * Open quote mark.
-     */
+    /** Open guillemet quote mark. */
     public static final String ST_LEFT = "\u00AB"; //$NON-NLS-1$
 
-    /**
-     * Close quote mark.
-     */
+    /** Close guillemet quote mark. */
     public static final String ST_RIGHT = "\u00BB"; //$NON-NLS-1$
 
+    /** Open quote mark. */
+    public static final String Q_LEFT = "\u201C"; //$NON-NLS-1$
+
+    /** Close quote mark. */
+    public static final String Q_RIGHT = "\u201D"; //$NON-NLS-1$
+
     /** The * KeyWord to represent an unlimited integer (infinite). */
     public static final String UNLIMITED_KEYWORD = "*"; //$NON-NLS-1$
 
diff --git a/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/labels/domains/ValueSpecificationLabelHelper.java b/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/labels/domains/ValueSpecificationLabelHelper.java
index 65b4938999e09cbc97251c60fde01a7341e474f0..33f2cae62b7f174d017f36269575868c370fc5e7 100644
--- a/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/labels/domains/ValueSpecificationLabelHelper.java
+++ b/plugins/org.eclipse.papyrus.uml.domain.services/src/org/eclipse/papyrus/uml/domain/services/labels/domains/ValueSpecificationLabelHelper.java
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (c) 2008, 2023 CEA LIST.
+ * Copyright (c) 2008, 2024 CEA LIST.
  *
  *
  * All rights reserved. This program and the accompanying materials
@@ -26,6 +26,7 @@ import static org.eclipse.papyrus.uml.domain.services.labels.UMLCharacters.TRUE;
 import java.util.Collection;
 
 import org.eclipse.papyrus.uml.domain.services.labels.INamedElementNameProvider;
+import org.eclipse.papyrus.uml.domain.services.labels.UMLCharacters;
 import org.eclipse.uml2.uml.Constraint;
 import org.eclipse.uml2.uml.Duration;
 import org.eclipse.uml2.uml.Expression;
@@ -34,7 +35,6 @@ import org.eclipse.uml2.uml.Interval;
 import org.eclipse.uml2.uml.LiteralBoolean;
 import org.eclipse.uml2.uml.LiteralInteger;
 import org.eclipse.uml2.uml.LiteralNull;
-import org.eclipse.uml2.uml.LiteralReal;
 import org.eclipse.uml2.uml.LiteralString;
 import org.eclipse.uml2.uml.LiteralUnlimitedNatural;
 import org.eclipse.uml2.uml.OpaqueExpression;
@@ -53,10 +53,8 @@ public class ValueSpecificationLabelHelper {
 
     private static final String ONE = "1"; //$NON-NLS-1$
 
-    /** The * KeyWord to represent an unlimited integer (infinite) */
-    private static final String UNLIMITED_KEYWORD = "*"; //$NON-NLS-1$
-
-    private static final String INTERVAL_FORMAT = "%1s..%2s"; //$NON-NLS-1$
+    /** The '*' KeyWord to represent an unlimited integer (infinite) */
+    private static final String UNLIMITED_KEYWORD = UMLCharacters.MANY;
 
     /**
      * Provider of element name.
@@ -100,20 +98,11 @@ public class ValueSpecificationLabelHelper {
         if (specification != null && specification.eClass() != null) {
             switch (specification.eClass().getClassifierID()) {
             case UMLPackage.LITERAL_STRING:
-                value = ((LiteralString) specification).getValue();
-                break;
             case UMLPackage.LITERAL_BOOLEAN:
-                value = Boolean.toString(((LiteralBoolean) specification).booleanValue());
-                break;
             case UMLPackage.LITERAL_INTEGER:
-                value = Integer.toString(((LiteralInteger) specification).getValue());
-                break;
             case UMLPackage.LITERAL_UNLIMITED_NATURAL:
-                value = Integer.toString(((LiteralUnlimitedNatural) specification).getValue());
-                if ("-1".equals(value)) { //$NON-NLS-1$
-                    value = UNLIMITED_KEYWORD;
-                }
-                break;
+            case UMLPackage.LITERAL_REAL:
+                value = specification.stringValue();
             case UMLPackage.LITERAL_NULL:
                 break;
             case UMLPackage.OPAQUE_EXPRESSION:
@@ -153,7 +142,7 @@ public class ValueSpecificationLabelHelper {
             case UMLPackage.DURATION:
                 Duration durationExpr = (Duration) specification;
                 if (durationExpr.getExpr() != null) {
-                    value = this.getSpecificationValue(durationExpr.getExpr());
+                    value = safeReferenceValue(specification, durationExpr.getExpr());
                 } else if (durationExpr.getObservations().size() > 0) {
                     if (useInternationalization) {
                         value = this.namedElementNameProvider.getName(durationExpr.getObservations().get(0));
@@ -165,7 +154,7 @@ public class ValueSpecificationLabelHelper {
             case UMLPackage.TIME_EXPRESSION:
                 TimeExpression timeExpr = (TimeExpression) specification;
                 if (timeExpr.getExpr() != null) {
-                    value = this.getSpecificationValue(timeExpr.getExpr());
+                    value = safeReferenceValue(specification, timeExpr.getExpr());
                 } else if (timeExpr.getObservations().size() > 0) {
                     if (useInternationalization) {
                         value = this.namedElementNameProvider.getName(timeExpr.getObservations().get(0));
@@ -177,18 +166,16 @@ public class ValueSpecificationLabelHelper {
             case UMLPackage.INTERVAL:
             case UMLPackage.TIME_INTERVAL:
             case UMLPackage.DURATION_INTERVAL:
-                if (!(specification instanceof Interval)) { // safety test for bug 430525, but should not be necessary
-                                                            // to perform a test here...
+                if (!(specification instanceof Interval interval)) {
+                    // safety test for bug 430525, but should not be necessary
+                    // to perform a test here...
                     break;
                 }
-                Interval interval = (Interval) specification;
-                String min = this.getSpecificationValue(interval.getMin());
-                String max = this.getSpecificationValue(interval.getMax());
-                value = String.format(INTERVAL_FORMAT, min, max);
+                String min = safeReferenceValue(specification, interval.getMin());
+                String max = safeReferenceValue(specification, interval.getMax());
+
+                value = min + UMLCharacters.CARD_SEP + max;
                 break;
-            case UMLPackage.LITERAL_REAL:
-                LiteralReal real = (LiteralReal) specification;
-                return Double.toString(real.getValue()); // Precision?
             default: {
                 break;
             }
@@ -196,9 +183,19 @@ public class ValueSpecificationLabelHelper {
         }
         return value;
     }
-
     // CHECKSTYLE:ON
 
+
+    private String safeReferenceValue(ValueSpecification caller, ValueSpecification called) {
+    	// UML can have reference in ValueSpecification without containment.
+    	// This is a naive implementation (1-level) for basic mistake.
+    	// A proper implementation would require an expensive call stack.
+        if (caller == called) {
+            return EMPTY;
+        }
+        return getSpecificationValue(called);
+    }
+
     /**
      * Get a string representing a Constraint.
      *
@@ -297,11 +294,7 @@ public class ValueSpecificationLabelHelper {
      *                      the new value
      */
     public static void restoreLiteralBoolean(LiteralBoolean specification, String value) {
-        if (TRUE.equals(value) || ONE.equals(value)) {
-            specification.setValue(true);
-        } else {
-            specification.setValue(false);
-        }
+        specification.setValue(TRUE.equals(value) || ONE.equals(value));
     }
 
     /**
diff --git a/pom.xml b/pom.xml
index dee199d2213f61c9f3c35236767337c7132d7e66..795c1a84fa99e9c83d05ffd08c2486f0ccca2d74 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
 	<modelVersion>4.0.0</modelVersion>
 	<groupId>org.eclipse.papyrus.domainservices</groupId>
 	<artifactId>container</artifactId>
-	<version>0.23.0-SNAPSHOT</version>
+	<version>0.24.0</version>
 	<packaging>pom</packaging>
 	<name>Papyrus-UML-services</name>
 
diff --git a/releng/category/org.eclipse.papyrus.uml.domain.services.updatesite/pom.xml b/releng/category/org.eclipse.papyrus.uml.domain.services.updatesite/pom.xml
index e4153157dafd7dc9b1f456cb0d50dac3cc8f574e..a71f6086403305224d94d23eafa980713a4d06a9 100644
--- a/releng/category/org.eclipse.papyrus.uml.domain.services.updatesite/pom.xml
+++ b/releng/category/org.eclipse.papyrus.uml.domain.services.updatesite/pom.xml
@@ -7,7 +7,7 @@
 	<parent>
 		<groupId>org.eclipse.papyrus.domainservices</groupId>
 	    <artifactId>parent</artifactId>
-		<version>0.23.0-SNAPSHOT</version>
+		<version>0.24.0</version>
 		<relativePath>../../../parent</relativePath>
 	</parent>
 
diff --git a/releng/targetplatform/org.eclipse.papyrus.uml.domain.services.releng.target/papyrusSiriusServices.target b/releng/targetplatform/org.eclipse.papyrus.uml.domain.services.releng.target/papyrusSiriusServices.target
index 289124c15c9520956d6427b0d9d7f760160dccc3..2ad6b0bf2bc18014840fb57ad1fa058381e095f5 100644
--- a/releng/targetplatform/org.eclipse.papyrus.uml.domain.services.releng.target/papyrusSiriusServices.target
+++ b/releng/targetplatform/org.eclipse.papyrus.uml.domain.services.releng.target/papyrusSiriusServices.target
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <?pde?>
 <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
-<target name="Papyrus-Uml-Services - 2024-06" sequenceNumber="1718979530">
+<target name="Papyrus-Uml-Services - 2024-06" sequenceNumber="1734687882">
   <locations>
     <location includeMode="planner" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="false" type="InstallableUnit">
       <unit id="org.eclipse.uml2.sdk.feature.group" version="5.5.3.v20221116-1811"/>
@@ -12,12 +12,12 @@
       <repository id="Eclipse-Shared-License" location="https://download.eclipse.org/cbi/updates/license"/>
     </location>
     <location includeMode="planner" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="false" type="InstallableUnit">
-      <unit id="org.slf4j.api" version="0.0.0"/>
-      <unit id="org.junit.jupiter.api" version="0.0.0"/>
-      <unit id="org.junit.jupiter.params" version="0.0.0"/>
-      <unit id="org.junit.platform.commons" version="0.0.0"/>
-      <unit id="org.junit.platform.engine" version="0.0.0"/>
-      <repository id="orbit" location="https://download.eclipse.org/tools/orbit/downloads/drops/S20230516204213/repository"/>
+      <unit id="slf4j.api" version="0.0.0"/>
+      <unit id="junit-jupiter-api" version="0.0.0"/>
+      <unit id="junit-jupiter-params" version="0.0.0"/>
+      <unit id="junit-platform-commons" version="0.0.0"/>
+      <unit id="junit-platform-engine" version="0.0.0"/>
+      <repository id="orbit" location="https://download.eclipse.org/tools/orbit/simrel/orbit-aggregation/2024-06"/>
     </location>
     <location includeMode="planner" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="false" type="InstallableUnit">
       <unit id="org.eclipse.sdk.feature.group" version="0.0.0"/>
diff --git a/releng/targetplatform/org.eclipse.papyrus.uml.domain.services.releng.target/papyrusSiriusServices.tpd b/releng/targetplatform/org.eclipse.papyrus.uml.domain.services.releng.target/papyrusSiriusServices.tpd
index e73a996bcf2117a454e2461b4fa1aedaeac3ac2c..b76bf80fefde767d9c4fcfdf87df5ae206bcb77d 100644
--- a/releng/targetplatform/org.eclipse.papyrus.uml.domain.services.releng.target/papyrusSiriusServices.tpd
+++ b/releng/targetplatform/org.eclipse.papyrus.uml.domain.services.releng.target/papyrusSiriusServices.tpd
@@ -11,13 +11,12 @@ location Eclipse-Shared-License "https://download.eclipse.org/cbi/updates/licens
 }
 
 // manual update
-location orbit "https://download.eclipse.org/tools/orbit/downloads/drops/S20230516204213/repository" {
-	org.slf4j.api lazy
-	org.junit.jupiter.api lazy
-	org.junit.jupiter.params lazy
-	org.junit.platform.commons lazy
-	org.junit.platform.engine lazy
-	
+location orbit "https://download.eclipse.org/tools/orbit/simrel/orbit-aggregation/2024-06" {
+	slf4j.api lazy
+	junit-jupiter-api lazy
+	junit-jupiter-params lazy
+	junit-platform-commons lazy
+	junit-platform-engine lazy
 }
 
 // manual update
diff --git a/releng/targetplatform/org.eclipse.papyrus.uml.domain.services.releng.target/pom.xml b/releng/targetplatform/org.eclipse.papyrus.uml.domain.services.releng.target/pom.xml
index bf7b4a9d290e1997a4bcfaa31ff91d4a6ea898c5..14c22cf0c72a1f2ef581b4769a61f04d10c3e63a 100644
--- a/releng/targetplatform/org.eclipse.papyrus.uml.domain.services.releng.target/pom.xml
+++ b/releng/targetplatform/org.eclipse.papyrus.uml.domain.services.releng.target/pom.xml
@@ -7,7 +7,7 @@
 	<parent>
 		<groupId>org.eclipse.papyrus.domainservices</groupId>
 	    <artifactId>parent</artifactId>
-		<version>0.23.0-SNAPSHOT</version>
+		<version>0.24.0</version>
 		<relativePath>../../../parent</relativePath>
 	</parent>