Enable the capability to animate the model according to RTC steps
beginning and end.

Change-Id: Ib566f89fb46bf51f4712d01cd63e83cb313eec91
Signed-off-by: jeremie.tatibouet <jeremie.tatibouet@cea.fr>
diff --git a/bundles/core/engines/org.eclipse.papyrus.moka.composites/pom.xml b/bundles/core/engines/org.eclipse.papyrus.moka.composites/pom.xml
index e2ebdbb..85e2cbc 100644
--- a/bundles/core/engines/org.eclipse.papyrus.moka.composites/pom.xml
+++ b/bundles/core/engines/org.eclipse.papyrus.moka.composites/pom.xml
@@ -41,6 +41,7 @@
 							<verbose>true</verbose>
 							<showWeaveInfo>true</showWeaveInfo>
 							<aspectDirectory>${fuml-aspects}</aspectDirectory>
+							<aspectDirectory>${project.basedir}/aspects</aspectDirectory>
 							<source>1.8</source>
 							<target>1.8</target>
 						</configuration>
diff --git a/bundles/core/engines/org.eclipse.papyrus.moka.fuml.statemachines/pom.xml b/bundles/core/engines/org.eclipse.papyrus.moka.fuml.statemachines/pom.xml
index abb84c4..e8f73ba 100644
--- a/bundles/core/engines/org.eclipse.papyrus.moka.fuml.statemachines/pom.xml
+++ b/bundles/core/engines/org.eclipse.papyrus.moka.fuml.statemachines/pom.xml
@@ -16,6 +16,11 @@
 	<name>org.eclipse.papyrus.moka.fuml.statemachines</name>
 	<description>Execution engine implementing PSSM (Precise Semantics for UML State Machines)</description>
 
+	<!-- Properties -->
+	<properties>
+		<fuml-aspects>${project.basedir}/../org.eclipse.papyrus.moka.fuml/aspects</fuml-aspects>
+	</properties>
+	
 	<!-- Build specificities -->
 	<build>
 		<plugins>
@@ -35,6 +40,7 @@
 						<configuration>
 							<verbose>true</verbose>
 							<showWeaveInfo>true</showWeaveInfo>
+							<aspectDirectory>${fuml-aspects}</aspectDirectory>
 							<aspectDirectory>${project.basedir}/aspects</aspectDirectory>
 							<source>1.8</source>
 							<target>1.8</target>
diff --git a/bundles/core/engines/org.eclipse.papyrus.moka.fuml/aspects/org/eclipse/papyrus/moka/fuml/profiling/Semantics/CommonBehaviors/Communications/ObjectActivationProfiler.aj b/bundles/core/engines/org.eclipse.papyrus.moka.fuml/aspects/org/eclipse/papyrus/moka/fuml/profiling/Semantics/CommonBehaviors/Communications/ObjectActivationProfiler.aj
new file mode 100644
index 0000000..09ccbf5
--- /dev/null
+++ b/bundles/core/engines/org.eclipse.papyrus.moka.fuml/aspects/org/eclipse/papyrus/moka/fuml/profiling/Semantics/CommonBehaviors/Communications/ObjectActivationProfiler.aj
@@ -0,0 +1,44 @@
+package org.eclipse.papyrus.moka.fuml.profiling.Semantics.CommonBehaviors.Communications;

+

+import org.eclipse.papyrus.moka.fuml.Semantics.Classes.Kernel.IReference;

+import org.eclipse.papyrus.moka.fuml.Semantics.CommonBehaviors.Communications.IObjectActivation;

+import org.eclipse.papyrus.moka.fuml.Semantics.impl.Classes.Kernel.Reference;

+import org.eclipse.papyrus.moka.fuml.profiling.MokaObservable;

+import org.eclipse.papyrus.moka.service.IMokaExecutionListener;

+import org.eclipse.papyrus.moka.service.IMokaStepListener;

+

+public aspect ObjectActivationProfiler extends MokaObservable{

+	

+	pointcut stepStart(IObjectActivation objectActivation):

+		target(objectActivation) &&

+		call(* IObjectActivation.dispatchNextEvent());

+	

+	before(IObjectActivation objectActivation) : stepStart(objectActivation){

+		this.notifyStepStart(objectActivation);

+	}

+	

+	after(IObjectActivation objectActivation) : stepStart(objectActivation){

+		this.notifyStepEnd(objectActivation);

+	}

+	

+	protected void notifyStepStart(IObjectActivation objectActivation) {

+		for(IMokaExecutionListener listener : this.listeners) {

+			if(listener instanceof IMokaStepListener) {

+				IReference reference = new Reference();

+				reference.setReferent(objectActivation.getObject());

+				((IMokaStepListener)listener).stepStart(reference);

+			}

+		}

+	}

+	

+	protected void notifyStepEnd(IObjectActivation objectActivation) {

+		for(IMokaExecutionListener listener : this.listeners) {

+			if(listener instanceof IMokaStepListener) {

+				IReference reference = new Reference();

+				reference.setReferent(objectActivation.getObject());

+				((IMokaStepListener)listener).stepEnd(reference);

+			}

+		}

+	}

+

+}

diff --git a/bundles/core/services/org.eclipse.papyrus.moka.animation/plugin.xml b/bundles/core/services/org.eclipse.papyrus.moka.animation/plugin.xml
index ff133a9..2f7c67b 100644
--- a/bundles/core/services/org.eclipse.papyrus.moka.animation/plugin.xml
+++ b/bundles/core/services/org.eclipse.papyrus.moka.animation/plugin.xml
@@ -74,18 +74,10 @@
       <animator

             class="org.eclipse.papyrus.moka.animation.engine.animators.ActivityAnimator"

             priority="0">

-         <derivedAnimationAction

-               class="org.eclipse.papyrus.moka.animation.engine.animators.actions.fuml.InvocationActionDerivedAnimation"></derivedAnimationAction>

-         <derivedAnimationAction

-               class="org.eclipse.papyrus.moka.animation.engine.animators.actions.fuml.AddStructuralFeatureValueActionDerivedAnimation">

-         </derivedAnimationAction>

       </animator>

       <animator

             class="org.eclipse.papyrus.moka.animation.engine.animators.StructuralAnimator"

             priority="0">

-         <derivedAnimationAction

-               class="org.eclipse.papyrus.moka.animation.engine.animators.actions.composite.FeatureValueTypeDerivedAnimation">

-         </derivedAnimationAction>

       </animator>

    </extension>

 

diff --git a/bundles/core/services/org.eclipse.papyrus.moka.animation/src/org/eclipse/papyrus/moka/animation/engine/AnimationService.java b/bundles/core/services/org.eclipse.papyrus.moka.animation/src/org/eclipse/papyrus/moka/animation/engine/AnimationService.java
index 1a91815..ca8b6c8 100644
--- a/bundles/core/services/org.eclipse.papyrus.moka.animation/src/org/eclipse/papyrus/moka/animation/engine/AnimationService.java
+++ b/bundles/core/services/org.eclipse.papyrus.moka.animation/src/org/eclipse/papyrus/moka/animation/engine/AnimationService.java
@@ -25,13 +25,15 @@
 import org.eclipse.papyrus.moka.animation.engine.rendering.DiagramHandler;

 import org.eclipse.papyrus.moka.animation.engine.rendering.IAnimation;

 import org.eclipse.papyrus.moka.fuml.Semantics.Classes.Kernel.IObject_;

+import org.eclipse.papyrus.moka.fuml.Semantics.Classes.Kernel.IReference;

 import org.eclipse.papyrus.moka.fuml.Semantics.Classes.Kernel.IValue;

 import org.eclipse.papyrus.moka.fuml.Semantics.Loci.LociL1.ISemanticVisitor;

 import org.eclipse.papyrus.moka.service.AbstractMokaService;

 import org.eclipse.papyrus.moka.service.IMokaExecutionListener;

+import org.eclipse.papyrus.moka.service.IMokaStepListener;

 import org.eclipse.papyrus.moka.utils.constants.MokaConstants;

 

-public class AnimationService extends AbstractMokaService implements IAnimation, IMokaExecutionListener {

+public class AnimationService extends AbstractMokaService implements IAnimation, IMokaExecutionListener, IMokaStepListener {

 

 	// The handler responsible for markers application

 	// TODO: the animation engine shall be contributed through an extension point.

@@ -133,6 +135,26 @@
 		}

 	}

 

+	@Override

+	public void stepStart(IReference context) {

+		if (MokaConstants.MOKA_AUTOMATIC_ANIMATION) {

+			Animator animator = this.getAnimator(context);

+			if (animator != null) {

+				animator.stepStart(context);

+			}

+		}

+	}

+

+	@Override

+	public void stepEnd(IReference context) {

+		if (MokaConstants.MOKA_AUTOMATIC_ANIMATION) {

+			Animator animator = this.getAnimator(context);

+			if (animator != null) {

+				animator.stepEnd(context);

+			}

+		}

+	}

+	

 	public void dispose() {

 		this.engine.clean();

 	}

diff --git a/bundles/core/services/org.eclipse.papyrus.moka.animation/src/org/eclipse/papyrus/moka/animation/engine/animators/ActivityAnimator.java b/bundles/core/services/org.eclipse.papyrus.moka.animation/src/org/eclipse/papyrus/moka/animation/engine/animators/ActivityAnimator.java
index 2c04020..375d2ea 100644
--- a/bundles/core/services/org.eclipse.papyrus.moka.animation/src/org/eclipse/papyrus/moka/animation/engine/animators/ActivityAnimator.java
+++ b/bundles/core/services/org.eclipse.papyrus.moka.animation/src/org/eclipse/papyrus/moka/animation/engine/animators/ActivityAnimator.java
@@ -18,31 +18,48 @@
 import org.eclipse.papyrus.moka.fuml.Semantics.Activities.IntermediateActivities.IActivityNodeActivation;

 import org.eclipse.papyrus.moka.fuml.Semantics.Loci.LociL1.ISemanticVisitor;

 import org.eclipse.papyrus.moka.utils.constants.MokaConstants;

+import org.eclipse.uml2.uml.ActivityNode;

+import org.eclipse.uml2.uml.CallAction;

+import org.eclipse.uml2.uml.InvocationAction;

 

-public class ActivityAnimator extends Animator{

+public class ActivityAnimator extends Animator {

 

 	@Override

 	public void nodeVisited_(ISemanticVisitor nodeVisitor) {

-		// When a node is visited by the execution engine, the following animation logic applies:

-		// 1] If the visitor is for an activity node then if its an accept event action or a call action then the

-		// representation of this node gets the ANIMATED style applied. If it is any other kind of activity

-		// node activation it also gets the ANIMATED style but for a given period of time. After this period

-		// of time the VISITED style gets automatically applied.

-		// 2] If the visitor is for an object flow or a control flow then it gets the ANIMTED style applied.

+		// When a node is visited by the execution engine, the following animation logic

+		// applies:

+		// 1] If the visitor is for an activity node then if its an accept event action

+		// or a synchronous call action then the representation of this node gets the

+		// ANIMATED style applied. If it is any other kind of activity node activation

+		// it also gets the ANIMATED style but for a given period of time. After this 

+		// period of time the VISITED style gets automatically  applied.

+		// 2] If the visitor is for an object flow or a control flow then it gets the

+		// ANIMTED style applied.

 		if (nodeVisitor instanceof IActivityNodeActivation) {

 			IActivityNodeActivation activation = (IActivityNodeActivation) nodeVisitor;

-			if (activation.getNode() != null) {

-				if (activation instanceof IAcceptEventActionActivation | activation instanceof ICallActionActivation) {

-					this.engine.renderAs(activation.getNode(), activation.getExecutionContext(), AnimationKind.ANIMATED);

+			ActivityNode activityNode = activation.getNode();

+			if (activityNode != null) {

+				if (activation instanceof IAcceptEventActionActivation) {

+					this.engine.renderAs(activityNode, activation.getExecutionContext(), AnimationKind.ANIMATED);

+				} else if (activation instanceof ICallActionActivation && ((CallAction) activityNode).isSynchronous()) {

+					this.engine.renderAs(activation.getNode(), activation.getExecutionContext(),

+							AnimationKind.ANIMATED);

 				} else {

-					this.engine.renderAs(activation.getNode(), activation.getExecutionContext(), AnimationKind.ANIMATED, AnimationKind.VISITED, MokaConstants.MOKA_ANIMATION_DELAY);

+					this.engine.renderAs(activityNode, activation.getExecutionContext(), AnimationKind.ANIMATED,

+							AnimationKind.VISITED, MokaConstants.MOKA_ANIMATION_DELAY);

+				}

+				if (activityNode instanceof InvocationAction) {

+					this.engine.renderAs(((InvocationAction) activityNode).getOnPort(),

+							activation.getExecutionContext(), AnimationKind.ANIMATED, AnimationKind.VISITED,

+							MokaConstants.MOKA_ANIMATION_DELAY);

 				}

 			}

-		} else{

-			if (nodeVisitor instanceof IActivityEdgeInstance){

+		} else {

+			if (nodeVisitor instanceof IActivityEdgeInstance) {

 				IActivityEdgeInstance edgeInstance = (IActivityEdgeInstance) nodeVisitor;

 				if (edgeInstance.getEdge() != null) {

-					this.engine.startRendering(edgeInstance.getEdge(), edgeInstance.getGroup().getActivityExecution().getContext(), AnimationKind.ANIMATED);

+					this.engine.startRendering(edgeInstance.getEdge(),

+							edgeInstance.getGroup().getActivityExecution().getContext(), AnimationKind.ANIMATED);

 				}

 			}

 		}

@@ -50,21 +67,29 @@
 

 	@Override

 	public void nodeLeft_(ISemanticVisitor nodeVisitor) {

-		// When a node is left by the execution engine (i.e., the execution of this node is done), the following

-		// animation logic applies.

-		// 1] If the visitor is for a node that is either an accept event action or a call action then the VISITED

-		// style gets applied. For any other node the style remain unchanged.

-		// 2] If the visitor is for an object flow or a control flow then the VISITED style gets applied.

+		// When a node is left by the execution engine (i.e., the execution of this node

+		// is done), the following animation logic applies:

+		// 1] If the visitor is for a node that is either an accept event action or a

+		// synchronous call action then the VISITED style gets applied. For any other

+		// node the style remain  unchanged.

+		// 2] If the visitor is for an object flow or a control flow then the VISITED

+		// style gets applied.

 		if (nodeVisitor instanceof IActivityNodeActivation) {

 			IActivityNodeActivation activation = (IActivityNodeActivation) nodeVisitor;

-			if (activation.getNode() != null && (activation instanceof IAcceptEventActionActivation | activation instanceof ICallActionActivation)) {

-				this.engine.renderAs(activation.getNode(), activation.getExecutionContext(), AnimationKind.VISITED);

+			ActivityNode activityNode = activation.getNode();

+			if (activityNode != null) {

+				if (activation instanceof IAcceptEventActionActivation) {

+					this.engine.renderAs(activation.getNode(), activation.getExecutionContext(), AnimationKind.VISITED);

+				} else if (activation instanceof ICallActionActivation && ((CallAction) activityNode).isSynchronous()) {

+					this.engine.renderAs(activation.getNode(), activation.getExecutionContext(), AnimationKind.VISITED);

+				}

 			}

 		} else {

 			if (nodeVisitor instanceof IActivityEdgeInstance) {

 				IActivityEdgeInstance edgeInstance = (IActivityEdgeInstance) nodeVisitor;

 				if (edgeInstance.getEdge() != null) {

-					this.engine.renderAs(edgeInstance.getEdge(), edgeInstance.getGroup().getActivityExecution().getContext(), AnimationKind.VISITED);

+					this.engine.renderAs(edgeInstance.getEdge(),

+							edgeInstance.getGroup().getActivityExecution().getContext(), AnimationKind.VISITED);

 				}

 			}

 		}

@@ -72,12 +97,13 @@
 

 	@Override

 	public boolean accept(ISemanticVisitor visitor) {

-		// If the visitor are either for activity nodes or activity edges then they can be accepted

+		// If the visitor are either for activity nodes or activity edges then they can

+		// be accepted

 		// by this animator to perform animation.

 		boolean accept = false;

-		if(visitor instanceof IActivityNodeActivation){

+		if (visitor instanceof IActivityNodeActivation) {

 			accept = true;

-		}else if (visitor instanceof IActivityEdgeInstance) {

+		} else if (visitor instanceof IActivityEdgeInstance) {

 			accept = true;

 		}

 		return accept;

diff --git a/bundles/core/services/org.eclipse.papyrus.moka.animation/src/org/eclipse/papyrus/moka/animation/engine/animators/Animator.java b/bundles/core/services/org.eclipse.papyrus.moka.animation/src/org/eclipse/papyrus/moka/animation/engine/animators/Animator.java
index 00c7382..7296958 100644
--- a/bundles/core/services/org.eclipse.papyrus.moka.animation/src/org/eclipse/papyrus/moka/animation/engine/animators/Animator.java
+++ b/bundles/core/services/org.eclipse.papyrus.moka.animation/src/org/eclipse/papyrus/moka/animation/engine/animators/Animator.java
@@ -15,11 +15,13 @@
 

 import org.eclipse.papyrus.moka.animation.engine.animators.actions.DerivedAnimationAction;

 import org.eclipse.papyrus.moka.animation.engine.rendering.AnimationEngine;

+import org.eclipse.papyrus.moka.fuml.Semantics.Classes.Kernel.IReference;

 import org.eclipse.papyrus.moka.fuml.Semantics.Classes.Kernel.IValue;

 import org.eclipse.papyrus.moka.fuml.Semantics.Loci.LociL1.ISemanticVisitor;

 import org.eclipse.papyrus.moka.service.IMokaExecutionListener;

+import org.eclipse.papyrus.moka.service.IMokaStepListener;

 

-public abstract class Animator implements IMokaExecutionListener{

+public abstract class Animator implements IMokaExecutionListener, IMokaStepListener{

 

 	// The animation engine associated to the animator

 	protected AnimationEngine engine;

@@ -62,7 +64,7 @@
 	public abstract boolean accept(ISemanticVisitor visitor);

 	

 	@Override

-	public void nodeVisited(ISemanticVisitor nodeVisitor) {

+	public final void nodeVisited(ISemanticVisitor nodeVisitor) {

 		// Apply PRE and POST actions attached to the animator when

 		// an acceptable node is visited.

 		for(DerivedAnimationAction derivedAction : this.derivedAnimationAction) {

@@ -101,12 +103,20 @@
 	

 	@Override

 	public void valueCreated(IValue value) {

-		// Do nothing

+		// By default do nothing

 	}

 

 	@Override

 	public void valueDestroyed(IValue value) {

-		// Do nothing

+		// By default do nothing

+	}

+	

+	public void stepStart(IReference context) {

+		// By default do nothing

+	}

+	

+	public void stepEnd(IReference context) {

+		// By default do nothing

 	}

 	

 }

diff --git a/bundles/core/services/org.eclipse.papyrus.moka.animation/src/org/eclipse/papyrus/moka/animation/engine/animators/StructuralAnimator.java b/bundles/core/services/org.eclipse.papyrus.moka.animation/src/org/eclipse/papyrus/moka/animation/engine/animators/StructuralAnimator.java
index d361128..b39db71 100644
--- a/bundles/core/services/org.eclipse.papyrus.moka.animation/src/org/eclipse/papyrus/moka/animation/engine/animators/StructuralAnimator.java
+++ b/bundles/core/services/org.eclipse.papyrus.moka.animation/src/org/eclipse/papyrus/moka/animation/engine/animators/StructuralAnimator.java
@@ -14,7 +14,6 @@
 package org.eclipse.papyrus.moka.animation.engine.animators;

 

 import java.util.Iterator;

-import java.util.List;

 

 import org.eclipse.papyrus.moka.animation.engine.rendering.AnimationKind;

 import org.eclipse.papyrus.moka.composites.interfaces.Semantics.CompositeStructures.StructuredClasses.ICS_InteractionPoint;

@@ -23,35 +22,134 @@
 import org.eclipse.papyrus.moka.fuml.Semantics.Classes.Kernel.IExtensionalValue;

 import org.eclipse.papyrus.moka.fuml.Semantics.Classes.Kernel.IFeatureValue;

 import org.eclipse.papyrus.moka.fuml.Semantics.Classes.Kernel.IObject_;

+import org.eclipse.papyrus.moka.fuml.Semantics.Classes.Kernel.IReference;

 import org.eclipse.papyrus.moka.fuml.Semantics.Classes.Kernel.IValue;

+import org.eclipse.papyrus.moka.fuml.Semantics.Loci.LociL1.ILocus;

 import org.eclipse.papyrus.moka.fuml.Semantics.Loci.LociL1.ISemanticVisitor;

 import org.eclipse.papyrus.moka.utils.constants.MokaConstants;

-import org.eclipse.uml2.uml.Type;

 import org.eclipse.uml2.uml.Class;

 import org.eclipse.uml2.uml.Classifier;

+import org.eclipse.uml2.uml.Type;

 

 public class StructuralAnimator extends Animator {

 

 	@Override

 	public void nodeVisited_(ISemanticVisitor nodeVisitor) {

 		if (nodeVisitor instanceof ICS_InteractionPoint) {

-			// If the visited element is the runtime manifestation of a port then it is

-			// animated and then after the specified delay marked as visited.

+			// The visitor is for a port. A port is visited when a event occurrence

+			// or an operation call flows in or out of the port

 			this.engine.renderAs(((ICS_InteractionPoint) nodeVisitor).getDefiningPort(),

 					((ICS_InteractionPoint) nodeVisitor).getOwner().getReferent(), AnimationKind.ANIMATED,

 					AnimationKind.VISITED, MokaConstants.MOKA_ANIMATION_DELAY);

 		} else if (nodeVisitor instanceof ICS_ConnectorLink) {

-			// If the visited element is the runtime manifestation of a connector then it

-			// animated and then after the specified delay marked as visited.

+			// The visitor is for a connector. A connector is visited when an event

+			// occurrence or an operation call flows on the connector

 			this.engine.renderAs(((ICS_ConnectorLink) nodeVisitor).getConnector(), null, AnimationKind.ANIMATED,

 					AnimationKind.VISITED, MokaConstants.MOKA_ANIMATION_DELAY);

 		} else if (nodeVisitor instanceof IFeatureValueWrapper) {

-			// If the visited element is a structural feature newly associated to values

-			// then the structural feature is marked as being visited

+			// The visitor is for a feature value. A feature value is visited when

+			// a value is added in its set of value through the PSCS default construct

+			// strategy.

 			IFeatureValueWrapper featureValue = (IFeatureValueWrapper) nodeVisitor;

-			Type type = featureValue.getFeature().getType();

-			if (type instanceof Class) {

-				this.engine.renderAs(featureValue.getFeature(), featureValue.getContext(), AnimationKind.VISITED);

+			this.engine.renderAs(featureValue.getFeature(), featureValue.getContext(), AnimationKind.VISITED);

+		}

+	}

+

+	@Override

+	public void stepStart(IReference context) {

+		// This method is triggered by the beginning of a RTC step in an active

+		// object. It ensures that upon the beginning of the step, active classes

+		// typing this object are animated. It also make sure that any feature

+		// of other object referencing the object performing the step are animated.

+		IObject_ referent = context.getReferent();

+		if (referent != null) {

+			for (Type type : referent.getTypes()) {

+				if (type instanceof Class && ((Class) type).isActive()) {

+					this.engine.renderAs(type, referent, AnimationKind.ANIMATED);

+				}

+			}

+			ILocus locus = referent.getLocus();

+			if (locus != null) {

+				Iterator<IExtensionalValue> extensionalValueIterator = locus.getExtensionalValues().iterator();

+				while (extensionalValueIterator.hasNext()) {

+					IExtensionalValue extensionalValue = extensionalValueIterator.next();

+					if (extensionalValue instanceof IObject_ && !referent.getFeatureValues().isEmpty()) {

+						for (IFeatureValue featureValue : (((IObject_) extensionalValue).getFeatureValues())) {

+							Iterator<IValue> valueIterator = featureValue.getValues().iterator();

+							boolean found = false;

+							while (!found && valueIterator.hasNext()) {

+								found = valueIterator.next().equals(context);

+							}

+							if (found) {

+								this.engine.renderAs(featureValue.getFeature(), (IObject_) extensionalValue,

+										AnimationKind.ANIMATED);

+							}

+						}

+					}

+				}

+			}

+		}

+	}

+

+	@Override

+	public void stepEnd(IReference context) {

+		// This method is triggered by the end of a RTC step in an active object.

+		// It ensures that when the step end, any active class typing the object

+		// is marked as being visited. In addition, it makes sure that any feature

+		// referencing the object performing the step is marked as being visited.

+		IObject_ referent = context.getReferent();

+		if (referent != null) {

+			for (Type type : referent.getTypes()) {

+				if (type instanceof Class && ((Class) type).isActive()) {

+					this.engine.renderAs(type, referent, AnimationKind.VISITED);

+				}

+			}

+			ILocus locus = referent.getLocus();

+			if (locus != null) {

+				Iterator<IExtensionalValue> extensionalValueIterator = locus.getExtensionalValues().iterator();

+				while (extensionalValueIterator.hasNext()) {

+					IExtensionalValue extensionalValue = extensionalValueIterator.next();

+					if (extensionalValue instanceof IObject_ && !referent.getFeatureValues().isEmpty()) {

+						for (IFeatureValue featureValue : ((IObject_) extensionalValue).getFeatureValues()) {

+							Iterator<IValue> valueIterator = featureValue.getValues().iterator();

+							boolean found = false;

+							while (!found && valueIterator.hasNext()) {

+								found = valueIterator.next().equals(context);

+							}

+							if (found) {

+								this.engine.renderAs(featureValue.getFeature(), (IObject_) extensionalValue,

+										AnimationKind.VISITED);

+							}

+						}

+					}

+				}

+			}

+		}

+	}

+

+	@Override

+	public void valueCreated(IValue value) {

+		// When a value is created and this value is an object then all

+		// classifiers typing this object are marked as being visited

+		if(value instanceof IObject_) {

+			for(Classifier classifier : ((IObject_)value).getTypes()) {

+				this.engine.renderAs(classifier, (IObject_)value, AnimationKind.VISITED);

+			}

+		}

+	}

+

+	@Override

+	public void valueDestroyed(IValue value) {

+		// When a value is destroyed and this value is an object then all

+		// classifiers typing this object are freed from any rendering

+		// constraints (i.e., any ongoing animation gets stopped). This only

+		// apply if no instance of the classifier can be found at the locus.

+		if(value instanceof IObject_) {

+			for(Classifier classifier : ((IObject_)value).getTypes()) {

+				ILocus locus = ((IObject_)value).getLocus();

+				if(locus != null && locus.getExtent(classifier).isEmpty()) {

+					this.engine.removeRenderingRules(classifier);

+				}

 			}

 		}

 	}

@@ -62,33 +160,6 @@
 	}

 

 	@Override

-	public void valueCreated(IValue value) {

-		// Whenever an object is created, the classes typing this object are

-		// animated. If a class is active then it remains in the ANIMATED state

-		// while if it is passive it remains in the VISITED state

-		IObject_ object = (IObject_) value;

-		for (Classifier classifier : object.getTypes()) {

-			this.engine.renderAs((Class) classifier, object, AnimationKind.VISITED);

-		}

-	}

-

-	@Override

-	public void valueDestroyed(IValue value) {

-		// Whenever an object is destroyed, if there are no other objects

-		// in the locus that are classified under the same types are displayed

-		// according to their original style

-		IObject_ object = (IObject_) value;

-		Iterator<Classifier> classifierIterator = object.getTypes().iterator();

-		while (classifierIterator.hasNext()) {

-			Classifier classifier = classifierIterator.next();

-			List<IExtensionalValue> extensionalValues = object.getLocus().getExtent(classifierIterator.next());

-			if(!extensionalValues.isEmpty()) {

-				this.engine.removeRenderingRules(classifier);

-			}

-		}

-	}

-

-	@Override

 	public boolean accept(ISemanticVisitor visitor) {

 		// The composite animator enables the following nodes to be animated:

 		// any feature value with newly associated value, connector and send signal

@@ -101,6 +172,8 @@
 			return true;

 		} else if (visitor instanceof IObject_) {

 			return true;

+		} else if (visitor instanceof IReference) {

+			return true;

 		}

 		return false;

 	}

diff --git a/bundles/core/services/org.eclipse.papyrus.moka.animation/src/org/eclipse/papyrus/moka/animation/engine/animators/actions/composite/FeatureValueTypeDerivedAnimation.java b/bundles/core/services/org.eclipse.papyrus.moka.animation/src/org/eclipse/papyrus/moka/animation/engine/animators/actions/composite/FeatureValueTypeDerivedAnimation.java
deleted file mode 100644
index 930d2a2..0000000
--- a/bundles/core/services/org.eclipse.papyrus.moka.animation/src/org/eclipse/papyrus/moka/animation/engine/animators/actions/composite/FeatureValueTypeDerivedAnimation.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*****************************************************************************

- * Copyright (c) 2017 CEA LIST.

- * 

- * All rights reserved. This program and the accompanying materials

- * are made available under the terms of the Eclipse Public License v1.0

- * which accompanies this distribution, and is available at

- * http://www.eclipse.org/legal/epl-v10.html

- *

- * Contributors:

- *  CEA LIST Initial API and implementation

- *****************************************************************************/

-

-package org.eclipse.papyrus.moka.animation.engine.animators.actions.composite;

-

-import org.eclipse.papyrus.moka.animation.engine.animators.actions.DerivedAnimationAction;

-import org.eclipse.papyrus.moka.animation.engine.rendering.AnimationKind;

-import org.eclipse.papyrus.moka.animation.engine.rendering.IRenderingEngine;

-import org.eclipse.papyrus.moka.fuml.Profiling.Semantics.Kernel.Classes.IFeatureValueWrapper;

-import org.eclipse.papyrus.moka.fuml.Semantics.Loci.LociL1.ISemanticVisitor;

-import org.eclipse.uml2.uml.Type;

-import org.eclipse.uml2.uml.Class;

-

-public class FeatureValueTypeDerivedAnimation extends DerivedAnimationAction{

-

-	public void postVisitAction(final IRenderingEngine engine, ISemanticVisitor visitor) {

-		// Enable the animation of the type of the new value

-		org.eclipse.papyrus.moka.fuml.Profiling.Semantics.Kernel.Classes.IFeatureValueWrapper featureValue = (IFeatureValueWrapper) visitor;

-		Type type = featureValue.getFeature().getType();

-		if(type instanceof Class) {

-			engine.renderAs(type, featureValue.getContext(), AnimationKind.VISITED);

-		}

-	}

-	

-	@Override

-	public boolean accept(ISemanticVisitor visitor) {

-		// If the visitor is for a FeatureValue with new values 

-		if(visitor instanceof IFeatureValueWrapper) {

-			return true;

-		}

-		return false;

-	}

-

-}

diff --git a/bundles/core/services/org.eclipse.papyrus.moka.animation/src/org/eclipse/papyrus/moka/animation/engine/animators/actions/fuml/AddStructuralFeatureValueActionDerivedAnimation.java b/bundles/core/services/org.eclipse.papyrus.moka.animation/src/org/eclipse/papyrus/moka/animation/engine/animators/actions/fuml/AddStructuralFeatureValueActionDerivedAnimation.java
deleted file mode 100644
index 819bb62..0000000
--- a/bundles/core/services/org.eclipse.papyrus.moka.animation/src/org/eclipse/papyrus/moka/animation/engine/animators/actions/fuml/AddStructuralFeatureValueActionDerivedAnimation.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*****************************************************************************

- * Copyright (c) 2017 CEA LIST.

- * 

- * All rights reserved. This program and the accompanying materials

- * are made available under the terms of the Eclipse Public License v1.0

- * which accompanies this distribution, and is available at

- * http://www.eclipse.org/legal/epl-v10.html

- *

- * Contributors:

- *  CEA LIST Initial API and implementation

- *****************************************************************************/

-

-package org.eclipse.papyrus.moka.animation.engine.animators.actions.fuml;

-

-import org.eclipse.papyrus.moka.animation.engine.animators.actions.DerivedAnimationAction;

-import org.eclipse.papyrus.moka.animation.engine.rendering.AnimationKind;

-import org.eclipse.papyrus.moka.animation.engine.rendering.IRenderingEngine;

-import org.eclipse.papyrus.moka.fuml.Semantics.Actions.BasicActions.IActionActivation;

-import org.eclipse.papyrus.moka.fuml.Semantics.Loci.LociL1.ISemanticVisitor;

-import org.eclipse.papyrus.moka.utils.constants.MokaConstants;

-import org.eclipse.uml2.uml.AddStructuralFeatureValueAction;

-

-public class AddStructuralFeatureValueActionDerivedAnimation extends DerivedAnimationAction {

-

-	@Override

-	public void postVisitAction(IRenderingEngine engine, ISemanticVisitor visitor) {

-		// Enable the animation of the represented feature

-		AddStructuralFeatureValueAction action = (AddStructuralFeatureValueAction) ((IActionActivation) visitor)

-				.getNode();

-		engine.renderAs(action.getStructuralFeature(), ((IActionActivation) visitor).getExecutionContext(),

-				AnimationKind.ANIMATED, AnimationKind.VISITED, MokaConstants.MOKA_ANIMATION_DELAY);

-	}

-

-	@Override

-	public boolean accept(ISemanticVisitor visitor) {

-		// If the visitor is for an AddStructuralfeatureValueAction

-		if (visitor instanceof IActionActivation

-				&& ((IActionActivation) visitor).getNode() instanceof AddStructuralFeatureValueAction) {

-			return true;

-		}

-		return false;

-	}

-

-}

diff --git a/bundles/core/services/org.eclipse.papyrus.moka.animation/src/org/eclipse/papyrus/moka/animation/engine/animators/actions/fuml/InvocationActionDerivedAnimation.java b/bundles/core/services/org.eclipse.papyrus.moka.animation/src/org/eclipse/papyrus/moka/animation/engine/animators/actions/fuml/InvocationActionDerivedAnimation.java
deleted file mode 100644
index 9ad9c4b..0000000
--- a/bundles/core/services/org.eclipse.papyrus.moka.animation/src/org/eclipse/papyrus/moka/animation/engine/animators/actions/fuml/InvocationActionDerivedAnimation.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*****************************************************************************

- * Copyright (c) 2017 CEA LIST.

- * 

- * All rights reserved. This program and the accompanying materials

- * are made available under the terms of the Eclipse Public License v1.0

- * which accompanies this distribution, and is available at

- * http://www.eclipse.org/legal/epl-v10.html

- *

- * Contributors:

- *  CEA LIST Initial API and implementation

- *****************************************************************************/

-

-package org.eclipse.papyrus.moka.animation.engine.animators.actions.fuml;

-

-import org.eclipse.papyrus.moka.animation.engine.animators.actions.DerivedAnimationAction;

-import org.eclipse.papyrus.moka.animation.engine.rendering.AnimationKind;

-import org.eclipse.papyrus.moka.animation.engine.rendering.IRenderingEngine;

-import org.eclipse.papyrus.moka.fuml.Semantics.Actions.BasicActions.IActionActivation;

-import org.eclipse.papyrus.moka.fuml.Semantics.Loci.LociL1.ISemanticVisitor;

-import org.eclipse.papyrus.moka.utils.constants.MokaConstants;

-import org.eclipse.uml2.uml.InvocationAction;

-

-public final class InvocationActionDerivedAnimation extends DerivedAnimationAction {

-

-	@Override

-	public void postVisitAction(final IRenderingEngine engine, final ISemanticVisitor visitor) {

-		// After the InvocationAction was visited then animate the

-		// referenced port

-		InvocationAction action = (InvocationAction) ((IActionActivation) visitor).getNode();

-		engine.renderAs(action.getOnPort(), ((IActionActivation) visitor).getExecutionContext(),

-				AnimationKind.ANIMATED, AnimationKind.VISITED, MokaConstants.MOKA_ANIMATION_DELAY);

-	}

-

-	@Override

-	public boolean accept(final ISemanticVisitor visitor) {

-		// If the source model element is an InvocationAction and its

-		// 'onPort' property is set the return true otherwise return

-		// false

-		if (visitor instanceof IActionActivation && ((IActionActivation) visitor).getNode() instanceof InvocationAction

-				&& ((InvocationAction) ((IActionActivation) visitor).getNode()).getOnPort() != null) {

-			return true;

-		}

-		return false;

-	}

-

-}

diff --git a/bundles/core/services/org.eclipse.papyrus.moka.service/src/org/eclipse/papyrus/moka/service/IMokaStepListener.java b/bundles/core/services/org.eclipse.papyrus.moka.service/src/org/eclipse/papyrus/moka/service/IMokaStepListener.java
new file mode 100644
index 0000000..0a3779d
--- /dev/null
+++ b/bundles/core/services/org.eclipse.papyrus.moka.service/src/org/eclipse/papyrus/moka/service/IMokaStepListener.java
@@ -0,0 +1,11 @@
+package org.eclipse.papyrus.moka.service;

+

+import org.eclipse.papyrus.moka.fuml.Semantics.Classes.Kernel.IReference;

+

+public interface IMokaStepListener {

+	

+	public void stepStart(IReference context);

+	

+	public void stepEnd(IReference context);

+	

+}

diff --git a/bundles/core/tools/org.eclipse.papyrus.moka.fuml.libraries.tools.annotations/xtend-gen/org/eclipse/papyrus/moka/fuml/libraries/tools/annotations/xtend/OpaqueBehaviorExecutionGenerator.java b/bundles/core/tools/org.eclipse.papyrus.moka.fuml.libraries.tools.annotations/xtend-gen/org/eclipse/papyrus/moka/fuml/libraries/tools/annotations/xtend/OpaqueBehaviorExecutionGenerator.java
deleted file mode 100644
index b55f855..0000000
--- a/bundles/core/tools/org.eclipse.papyrus.moka.fuml.libraries.tools.annotations/xtend-gen/org/eclipse/papyrus/moka/fuml/libraries/tools/annotations/xtend/OpaqueBehaviorExecutionGenerator.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/**

- * Copyright (c) 2016 CEA LIST.

- * 

- * 

- * All rights reserved. This program and the accompanying materials

- * are made available under the terms of the Eclipse Public License v1.0

- * which accompanies this distribution, and is available at

- * http://www.eclipse.org/legal/epl-v10.html

- * 

- * Contributors:

- *  David LOPEZ BETANCUR (CEA LIST) - david.lopez@cea.fr

- */

-package org.eclipse.papyrus.moka.fuml.libraries.tools.annotations.xtend;

-

-import com.google.common.base.Objects;

-import java.util.List;

-import javax.lang.model.element.Name;

-import org.eclipse.papyrus.moka.fuml.libraries.tools.annotations.processor.FumlLibraryData;

-import org.eclipse.xtend2.lib.StringConcatenation;

-import org.eclipse.xtext.xbase.lib.StringExtensions;

-

-@SuppressWarnings("all")

-public class OpaqueBehaviorExecutionGenerator {

-  public static String className(final FumlLibraryData.OpaqueFunction f) {

-    StringConcatenation _builder = new StringConcatenation();

-    String _firstUpper = StringExtensions.toFirstUpper(f.name());

-    _builder.append(_firstUpper);

-    _builder.append("Behavior");

-    return _builder.toString();

-  }

-  

-  public static String genInputParamString(final FumlLibraryData.OpaqueFunctionParameter p, final int i, final int size) {

-    StringConcatenation _builder = new StringConcatenation();

-    _builder.append("(");

-    String _fqType = p.fqType();

-    _builder.append(_fqType);

-    _builder.append(") in.get(");

-    _builder.append(i);

-    _builder.append(").getValues().get(0)");

-    {

-      if ((i != (size - 1))) {

-        _builder.append(",");

-        _builder.newLineIfNotEmpty();

-      }

-    }

-    return _builder.toString();

-  }

-  

-  public static String generate(final FumlLibraryData.OpaqueFunction f, final FumlLibraryData lib) {

-    StringConcatenation _builder = new StringConcatenation();

-    _builder.append("package ");

-    String _packageName = lib.packageName();

-    _builder.append(_packageName);

-    _builder.append(";");

-    _builder.newLineIfNotEmpty();

-    int _countParams = f.countParams(FumlLibraryData.ParameterDirection.OUT);

-    boolean hasOutput = (_countParams > 0);

-    _builder.newLineIfNotEmpty();

-    _builder.newLine();

-    {

-      if (hasOutput) {

-        _builder.append("import java.util.ArrayList;");

-        _builder.newLine();

-      }

-    }

-    _builder.append("import java.util.List;");

-    _builder.newLine();

-    _builder.newLine();

-    _builder.append("import org.eclipse.papyrus.moka.fuml.Semantics.Classes.Kernel.IValue;");

-    _builder.newLine();

-    _builder.append("import org.eclipse.papyrus.moka.fuml.Semantics.CommonBehaviors.BasicBehaviors.IParameterValue;");

-    _builder.newLine();

-    _builder.append("import org.eclipse.papyrus.moka.fuml.Semantics.impl.CommonBehaviors.BasicBehaviors.OpaqueBehaviorExecution;");

-    _builder.newLine();

-    _builder.newLine();

-    _builder.append("public class ");

-    String _className = OpaqueBehaviorExecutionGenerator.className(f);

-    _builder.append(_className);

-    _builder.append(" extends OpaqueBehaviorExecution{");

-    _builder.newLineIfNotEmpty();

-    _builder.append("\t");

-    _builder.newLine();

-    _builder.append("\t");

-    _builder.append("@Override");

-    _builder.newLine();

-    _builder.append("\t");

-    _builder.append("public void doBody(List<IParameterValue> in, List<IParameterValue> out) {");

-    _builder.newLine();

-    _builder.append("\t\t");

-    int inputIdx = 0;

-    _builder.newLineIfNotEmpty();

-    {

-      if (hasOutput) {

-        _builder.append("\t\t");

-        _builder.append("List<IValue> outputs = new ArrayList<IValue>();");

-        _builder.newLine();

-      }

-    }

-    _builder.append("\t\t");

-    _builder.newLine();

-    {

-      List<FumlLibraryData.OpaqueFunctionParameter> _params = f.params();

-      for(final FumlLibraryData.OpaqueFunctionParameter op : _params) {

-        {

-          FumlLibraryData.ParameterDirection _direction = op.direction();

-          boolean _equals = Objects.equal(_direction, FumlLibraryData.ParameterDirection.OUT);

-          if (_equals) {

-            _builder.append("\t\t");

-            String _fqType = op.fqType();

-            _builder.append(_fqType, "\t\t");

-            _builder.append(" ");

-            String _name = op.name();

-            _builder.append(_name, "\t\t");

-            _builder.append(" = new ");

-            String _fqType_1 = op.fqType();

-            _builder.append(_fqType_1, "\t\t");

-            _builder.append("(); ");

-            _builder.newLineIfNotEmpty();

-            _builder.append("\t\t");

-            _builder.append("outputs.add(");

-            String _name_1 = op.name();

-            _builder.append(_name_1, "\t\t");

-            _builder.append(");");

-            _builder.newLineIfNotEmpty();

-          }

-        }

-        {

-          FumlLibraryData.ParameterDirection _direction_1 = op.direction();

-          boolean _equals_1 = Objects.equal(_direction_1, FumlLibraryData.ParameterDirection.IN);

-          if (_equals_1) {

-            _builder.append("\t\t");

-            String _fqType_2 = op.fqType();

-            _builder.append(_fqType_2, "\t\t");

-            _builder.append(" ");

-            String _name_2 = op.name();

-            _builder.append(_name_2, "\t\t");

-            _builder.append(" = (");

-            String _fqType_3 = op.fqType();

-            _builder.append(_fqType_3, "\t\t");

-            _builder.append(") in.get(");

-            int _plusPlus = inputIdx++;

-            _builder.append(_plusPlus, "\t\t");

-            _builder.append(").getValues().get(0);");

-            _builder.newLineIfNotEmpty();

-          }

-        }

-      }

-    }

-    _builder.append("\t\t");

-    _builder.newLine();

-    _builder.append("\t\t");

-    Name _simpleName = lib.classElement().getSimpleName();

-    _builder.append(_simpleName, "\t\t");

-    _builder.append(".");

-    String _methodName = f.methodName();

-    _builder.append(_methodName, "\t\t");

-    _builder.append("(");

-    {

-      List<FumlLibraryData.OpaqueFunctionParameter> _params_1 = f.params();

-      boolean _hasElements = false;

-      for(final FumlLibraryData.OpaqueFunctionParameter op_1 : _params_1) {

-        if (!_hasElements) {

-          _hasElements = true;

-        } else {

-          _builder.appendImmediate(",", "\t\t");

-        }

-        String _name_3 = op_1.name();

-        _builder.append(_name_3, "\t\t");

-      }

-    }

-    _builder.append(");");

-    _builder.newLineIfNotEmpty();

-    _builder.newLine();

-    {

-      if (hasOutput) {

-        _builder.append("\t\t");

-        _builder.append("out.get(0).setValues(outputs);");

-        _builder.newLine();

-      }

-    }

-    _builder.append("\t");

-    _builder.append("}");

-    _builder.newLine();

-    _builder.append("\t");

-    _builder.newLine();

-    _builder.append("\t");

-    _builder.append("@Override");

-    _builder.newLine();

-    _builder.append("\t");

-    _builder.append("public IValue new_() {");

-    _builder.newLine();

-    _builder.append("\t\t");

-    _builder.append("return new ");

-    String _className_1 = OpaqueBehaviorExecutionGenerator.className(f);

-    _builder.append(_className_1, "\t\t");

-    _builder.append("();");

-    _builder.newLineIfNotEmpty();

-    _builder.append("\t");

-    _builder.append("}");

-    _builder.newLine();

-    _builder.append("}");

-    _builder.newLine();

-    return _builder.toString();

-  }

-}