add support for exception

Change-Id: I0d322022d88883e717be91c9354b68059778399b
Signed-off-by: jeremie.tatibouet <jeremie.tatibouet@cea.fr>
diff --git a/plugins/org.eclipse.papyrus.moka.engine.uml.scheduling/src/org/eclipse/papyrus/moka/engine/uml/scheduling/UMLTaskExecution.java b/plugins/org.eclipse.papyrus.moka.engine.uml.scheduling/src/org/eclipse/papyrus/moka/engine/uml/scheduling/UMLTaskExecution.java
index 8d9878f..9381843 100644
--- a/plugins/org.eclipse.papyrus.moka.engine.uml.scheduling/src/org/eclipse/papyrus/moka/engine/uml/scheduling/UMLTaskExecution.java
+++ b/plugins/org.eclipse.papyrus.moka.engine.uml.scheduling/src/org/eclipse/papyrus/moka/engine/uml/scheduling/UMLTaskExecution.java
@@ -421,4 +421,14 @@
 
 	}
 	
+	@Override
+	public void propagateException(IValue exception) {
+		
+	}
+	
+	@Override
+	public IValue getException() {
+		return null;
+	}
+	
 }
diff --git a/plugins/org.eclipse.papyrus.moka.fuml.interfaces/src/org/eclipse/papyrus/moka/fuml/actions/IActionActivation.java b/plugins/org.eclipse.papyrus.moka.fuml.interfaces/src/org/eclipse/papyrus/moka/fuml/actions/IActionActivation.java
index acb7685..5833c59 100644
--- a/plugins/org.eclipse.papyrus.moka.fuml.interfaces/src/org/eclipse/papyrus/moka/fuml/actions/IActionActivation.java
+++ b/plugins/org.eclipse.papyrus.moka.fuml.interfaces/src/org/eclipse/papyrus/moka/fuml/actions/IActionActivation.java
@@ -18,6 +18,7 @@
 import java.util.List;
 
 import org.eclipse.papyrus.moka.fuml.activities.IActivityNodeActivation;
+import org.eclipse.papyrus.moka.fuml.activities.IExceptionHandlerActivation;
 import org.eclipse.papyrus.moka.fuml.simpleclassifiers.IBooleanValue;
 import org.eclipse.papyrus.moka.fuml.simpleclassifiers.IValue;
 import org.eclipse.papyrus.moka.fuml.structuredclassifiers.ILink;
@@ -46,5 +47,11 @@
 	public Boolean valueParticipatesInLink(IValue value, ILink link);
 
 	public IBooleanValue makeBooleanValue(Boolean value);
+	
+	public void propagateException(IValue exception);
+	
+	public void catchException(IValue exception, IExceptionHandlerActivation handler);
+	
+	public List<IExceptionHandlerActivation> getExceptionHandler(IValue exception);
 
 }
diff --git a/plugins/org.eclipse.papyrus.moka.fuml.interfaces/src/org/eclipse/papyrus/moka/fuml/activities/IExceptionHandlerActivation.java b/plugins/org.eclipse.papyrus.moka.fuml.interfaces/src/org/eclipse/papyrus/moka/fuml/activities/IExceptionHandlerActivation.java
new file mode 100644
index 0000000..120deb8
--- /dev/null
+++ b/plugins/org.eclipse.papyrus.moka.fuml.interfaces/src/org/eclipse/papyrus/moka/fuml/activities/IExceptionHandlerActivation.java
@@ -0,0 +1,17 @@
+package org.eclipse.papyrus.moka.fuml.activities;

+

+import org.eclipse.papyrus.moka.fuml.actions.IActionActivation;

+import org.eclipse.papyrus.moka.fuml.simpleclassifiers.IValue;

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

+

+public interface IExceptionHandlerActivation {

+

+	public void setHandler(ExceptionHandler handler);

+	

+	public void setDeclaringActionActivation(IActionActivation activation);

+	

+	public boolean match(IValue exception);

+	

+	public boolean handle(IValue exception);

+	

+}

diff --git a/plugins/org.eclipse.papyrus.moka.fuml.interfaces/src/org/eclipse/papyrus/moka/fuml/commonbehavior/IExecution.java b/plugins/org.eclipse.papyrus.moka.fuml.interfaces/src/org/eclipse/papyrus/moka/fuml/commonbehavior/IExecution.java
index 3e1b180..4ae4139 100644
--- a/plugins/org.eclipse.papyrus.moka.fuml.interfaces/src/org/eclipse/papyrus/moka/fuml/commonbehavior/IExecution.java
+++ b/plugins/org.eclipse.papyrus.moka.fuml.interfaces/src/org/eclipse/papyrus/moka/fuml/commonbehavior/IExecution.java
@@ -17,6 +17,7 @@
 
 import java.util.List;
 
+import org.eclipse.papyrus.moka.fuml.simpleclassifiers.IValue;
 import org.eclipse.papyrus.moka.fuml.structuredclassifiers.IObject_;
 import org.eclipse.uml2.uml.Behavior;
 import org.eclipse.uml2.uml.Parameter;
@@ -36,6 +37,10 @@
 	public Behavior getBehavior();
 
 	public void terminate();
+	
+	public void propagateException(IValue exception);
+	
+	public IValue getException();
 
 	public void setContext(IObject_ context);
 
diff --git a/plugins/org.eclipse.papyrus.moka.fuml/aspects/org/eclipse/papyrus/moka/fuml/profiling/activities/AcceptEventActivationWrapper.java b/plugins/org.eclipse.papyrus.moka.fuml/aspects/org/eclipse/papyrus/moka/fuml/profiling/activities/AcceptEventActivationWrapper.java
index e881e57..e367a2b 100644
--- a/plugins/org.eclipse.papyrus.moka.fuml/aspects/org/eclipse/papyrus/moka/fuml/profiling/activities/AcceptEventActivationWrapper.java
+++ b/plugins/org.eclipse.papyrus.moka.fuml/aspects/org/eclipse/papyrus/moka/fuml/profiling/activities/AcceptEventActivationWrapper.java
@@ -23,6 +23,7 @@
 import org.eclipse.papyrus.moka.fuml.activities.IActivityExecution;
 import org.eclipse.papyrus.moka.fuml.activities.IActivityNodeActivation;
 import org.eclipse.papyrus.moka.fuml.activities.IActivityNodeActivationGroup;
+import org.eclipse.papyrus.moka.fuml.activities.IExceptionHandlerActivation;
 import org.eclipse.papyrus.moka.fuml.activities.IToken;
 import org.eclipse.papyrus.moka.fuml.commonbehavior.IEventOccurrence;
 import org.eclipse.papyrus.moka.fuml.loci.ILocus;
@@ -284,4 +285,19 @@
 		return this.acceptEventActivation.getEventAccepter();
 	}
 
+	@Override
+	public void propagateException(IValue exception) {
+		acceptEventActivation.propagateException(exception);
+	}
+
+	@Override
+	public void catchException(IValue exception, IExceptionHandlerActivation handler) {
+		acceptEventActivation.catchException(exception, handler);
+	}
+
+	@Override
+	public List<IExceptionHandlerActivation> getExceptionHandler(IValue exception) {
+		return acceptEventActivation.getExceptionHandler(exception);
+	}
+
 }
diff --git a/plugins/org.eclipse.papyrus.moka.fuml/aspects/org/eclipse/papyrus/moka/fuml/profiling/debug/NullTokenPropagationProfiler.aj b/plugins/org.eclipse.papyrus.moka.fuml/aspects/org/eclipse/papyrus/moka/fuml/profiling/debug/NullTokenPropagationProfiler.aj
index 646008c..004d41e 100644
--- a/plugins/org.eclipse.papyrus.moka.fuml/aspects/org/eclipse/papyrus/moka/fuml/profiling/debug/NullTokenPropagationProfiler.aj
+++ b/plugins/org.eclipse.papyrus.moka.fuml/aspects/org/eclipse/papyrus/moka/fuml/profiling/debug/NullTokenPropagationProfiler.aj
@@ -36,7 +36,7 @@
 	after(OutputPinActivation objectNode) returning(List<IToken> tokens): getUnofferedTokens(objectNode){
 		if (checkAssistantValidity()) {
 			if (tokens.isEmpty() && ((OutputPin) objectNode.getNode()).getLower() > 0) {
-				throw new DebugAssistantException(this, objectNode);
+				//throw new DebugAssistantException(this, objectNode);
 			}
 		}
 	}
diff --git a/plugins/org.eclipse.papyrus.moka.fuml/src/org/eclipse/papyrus/moka/fuml/actions/ActionActivation.java b/plugins/org.eclipse.papyrus.moka.fuml/src/org/eclipse/papyrus/moka/fuml/actions/ActionActivation.java
index bae4803..8e21438 100644
--- a/plugins/org.eclipse.papyrus.moka.fuml/src/org/eclipse/papyrus/moka/fuml/actions/ActionActivation.java
+++ b/plugins/org.eclipse.papyrus.moka.fuml/src/org/eclipse/papyrus/moka/fuml/actions/ActionActivation.java
@@ -21,19 +21,20 @@
 import java.util.Iterator;
 import java.util.List;
 
-import org.eclipse.papyrus.moka.fuml.actions.IActionActivation;
-import org.eclipse.papyrus.moka.fuml.actions.IPinActivation;
 import org.eclipse.papyrus.moka.fuml.activities.ActivityEdgeInstance;
 import org.eclipse.papyrus.moka.fuml.activities.ActivityNodeActivation;
 import org.eclipse.papyrus.moka.fuml.activities.ControlToken;
+import org.eclipse.papyrus.moka.fuml.activities.ExceptionHandlerActivation;
 import org.eclipse.papyrus.moka.fuml.activities.ForkNodeActivation;
 import org.eclipse.papyrus.moka.fuml.activities.IActivityEdgeInstance;
 import org.eclipse.papyrus.moka.fuml.activities.IActivityNodeActivation;
 import org.eclipse.papyrus.moka.fuml.activities.IActivityNodeActivationGroup;
+import org.eclipse.papyrus.moka.fuml.activities.IExceptionHandlerActivation;
 import org.eclipse.papyrus.moka.fuml.activities.IObjectToken;
 import org.eclipse.papyrus.moka.fuml.activities.IToken;
 import org.eclipse.papyrus.moka.fuml.activities.ObjectToken;
 import org.eclipse.papyrus.moka.fuml.debug.Debug;
+import org.eclipse.papyrus.moka.fuml.loci.IChoiceStrategy;
 import org.eclipse.papyrus.moka.fuml.simpleclassifiers.BooleanValue;
 import org.eclipse.papyrus.moka.fuml.simpleclassifiers.IFeatureValue;
 import org.eclipse.papyrus.moka.fuml.simpleclassifiers.IValue;
@@ -41,6 +42,7 @@
 import org.eclipse.uml2.uml.Action;
 import org.eclipse.uml2.uml.ActivityNode;
 import org.eclipse.uml2.uml.ConditionalNode;
+import org.eclipse.uml2.uml.ExceptionHandler;
 import org.eclipse.uml2.uml.InputPin;
 import org.eclipse.uml2.uml.LiteralBoolean;
 import org.eclipse.uml2.uml.LoopNode;
@@ -50,24 +52,30 @@
 
 public abstract class ActionActivation extends ActivityNodeActivation implements IActionActivation {
 
+	protected List<IExceptionHandlerActivation> exceptionHandlerActivations = new ArrayList<IExceptionHandlerActivation>();
+
 	/*
-	 * The activations of the pins owned by the action of this action
-	 * activation.
+	 * The activations of the pins owned by the action of this action activation.
 	 */
 	public List<IPinActivation> pinActivations = new ArrayList<IPinActivation>();
 
 	/*
-	 * Whether this action activation is already firing. This attribute is only
-	 * used if the action for this action activation has isLocallyReentrant =
-	 * false (the default). If isLocallyReentrant=true, then firing always just
-	 * remains false.
+	 * Whether this action activation is already firing. This attribute is only used
+	 * if the action for this action activation has isLocallyReentrant = false (the
+	 * default). If isLocallyReentrant=true, then firing always just remains false.
 	 */
 	public Boolean firing;
 
 	@Override
 	public void run() {
-		// Run this action activation and any outoging fork node attached to it.
+		// Run this action activation and any outgoing fork node attached to it.
 		super.run();
+		for (ExceptionHandler handler : ((Action) node).getHandlers()) {
+			IExceptionHandlerActivation handlerActivation = new ExceptionHandlerActivation();
+			handlerActivation.setDeclaringActionActivation(this);
+			handlerActivation.setHandler(handler);
+			exceptionHandlerActivations.add(handlerActivation);
+		}
 		if (this.outgoingEdges.size() > 0) {
 			this.outgoingEdges.get(0).getTarget().run();
 		}
@@ -120,7 +128,8 @@
 		// offered to it.
 		do {
 			Debug.println("[fire] Action " + this.node.getName() + "...");
-			Debug.println("[event] Fire activity=" + this.getActivityExecution().getBehavior().getName() + " action=" + this.node.getName());
+			Debug.println("[event] Fire activity=" + this.getActivityExecution().getBehavior().getName() + " action="
+					+ this.node.getName());
 			this.doAction();
 			incomingTokens = this.completeAction();
 		} while (incomingTokens.size() > 0);
@@ -245,7 +254,8 @@
 		IActivityNodeActivation forkNodeActivation;
 		if (this.outgoingEdges.size() == 0) {
 			forkNodeActivation = new ForkNodeActivation();
-			forkNodeActivation.setRunning(false); // fUML12-10 certain boolean flags are not properly initialized in come cases
+			forkNodeActivation.setRunning(false); // fUML12-10 certain boolean flags are not properly initialized in
+													// come cases
 			IActivityEdgeInstance newEdge = new ActivityEdgeInstance();
 			super.addOutgoingEdge(newEdge);
 			forkNodeActivation.addIncomingEdge(newEdge);
@@ -384,6 +394,46 @@
 	}
 
 	protected static List<OutputPin> getOutputs(Action action) {
-		return action instanceof LoopNode ? ((LoopNode) action).getResults() : action instanceof ConditionalNode ? ((ConditionalNode) action).getResults() : action.getOutputs();
+		return action instanceof LoopNode ? ((LoopNode) action).getResults()
+				: action instanceof ConditionalNode ? ((ConditionalNode) action).getResults() : action.getOutputs();
+	}
+
+	@Override
+	public void propagateException(IValue exception) {
+		List<IExceptionHandlerActivation> matchingHandlers = getExceptionHandler(exception);
+		if (matchingHandlers.isEmpty()) {
+			terminate();
+			if (getGroup() != null) {
+				if (getGroup().getContainingActivation() != null) {
+					getGroup().getContainingActivation().propagateException(exception);
+				} else {
+					getGroup().getActivityExecution().propagateException(exception);
+					getGroup().getActivityExecution().terminate();
+				}
+			}
+		} else {
+			IChoiceStrategy strategy = (IChoiceStrategy) getExecutionLocus().getFactory().getStrategy("choice");
+			if (strategy != null) {
+				catchException(exception, matchingHandlers.get(strategy.choose(matchingHandlers.size()) - 1));
+			}
+		}
+	}
+
+	@Override
+	public void catchException(IValue exception, IExceptionHandlerActivation handler) {
+		if (exception != null && handler != null) {
+			handler.handle(exception);
+		}
+	}
+
+	@Override
+	public List<IExceptionHandlerActivation> getExceptionHandler(IValue exception) {
+		List<IExceptionHandlerActivation> matchingHandlers = new ArrayList<IExceptionHandlerActivation>();
+		for (IExceptionHandlerActivation handler : exceptionHandlerActivations) {
+			if (handler.match(exception)) {
+				matchingHandlers.add(handler);
+			}
+		}
+		return matchingHandlers;
 	}
 }
diff --git a/plugins/org.eclipse.papyrus.moka.fuml/src/org/eclipse/papyrus/moka/fuml/actions/CallActionActivation.java b/plugins/org.eclipse.papyrus.moka.fuml/src/org/eclipse/papyrus/moka/fuml/actions/CallActionActivation.java
index 14cdd7f..fd7c309 100644
--- a/plugins/org.eclipse.papyrus.moka.fuml/src/org/eclipse/papyrus/moka/fuml/actions/CallActionActivation.java
+++ b/plugins/org.eclipse.papyrus.moka.fuml/src/org/eclipse/papyrus/moka/fuml/actions/CallActionActivation.java
@@ -24,6 +24,7 @@
 import org.eclipse.papyrus.moka.fuml.commonbehavior.IExecution;
 import org.eclipse.papyrus.moka.fuml.commonbehavior.IParameterValue;
 import org.eclipse.papyrus.moka.fuml.commonbehavior.ParameterValue;
+import org.eclipse.papyrus.moka.fuml.simpleclassifiers.IValue;
 import org.eclipse.uml2.uml.CallAction;
 import org.eclipse.uml2.uml.InputPin;
 import org.eclipse.uml2.uml.OutputPin;
@@ -54,6 +55,7 @@
 			List<Parameter> parameters = callExecution.getBehavior().getOwnedParameters();
 			int pinNumber = 1;
 			int i = 1;
+			IValue exception = null;
 			while (i <= parameters.size()) {
 				Parameter parameter = parameters.get(i - 1);
 				if (parameter.getDirection() == ParameterDirectionKind.IN_LITERAL | parameter.getDirection() == ParameterDirectionKind.INOUT_LITERAL) {
@@ -66,22 +68,27 @@
 				i = i + 1;
 			}
 			callExecution.execute();
-			List<IParameterValue> outputParameterValues = callExecution.getOutputParameterValues();
-			pinNumber = 1;
-			i = 1;
-			while (i <= parameters.size()) {
-				Parameter parameter = parameters.get(i - 1);
-				if ((parameter.getDirection() == ParameterDirectionKind.INOUT_LITERAL) | (parameter.getDirection() == ParameterDirectionKind.OUT_LITERAL) | (parameter.getDirection() == ParameterDirectionKind.RETURN_LITERAL)) {
-					for (int j = 0; j < outputParameterValues.size(); j++) {
-						IParameterValue outputParameterValue = outputParameterValues.get(j);
-						if (outputParameterValue.getParameter() == parameter) {
-							OutputPin resultPin = resultPins.get(pinNumber - 1);
-							this.putTokens(resultPin, outputParameterValue.getValues());
+			exception = callExecution.getException();
+			if(callExecution.getException() != null) {
+				propagateException(exception);
+			} else {
+				List<IParameterValue> outputParameterValues = callExecution.getOutputParameterValues();
+				pinNumber = 1;
+				i = 1;
+				while (i <= parameters.size()) {
+					Parameter parameter = parameters.get(i - 1);
+					if ((parameter.getDirection() == ParameterDirectionKind.INOUT_LITERAL) | (parameter.getDirection() == ParameterDirectionKind.OUT_LITERAL) | (parameter.getDirection() == ParameterDirectionKind.RETURN_LITERAL)) {
+						for (int j = 0; j < outputParameterValues.size(); j++) {
+							IParameterValue outputParameterValue = outputParameterValues.get(j);
+							if (outputParameterValue.getParameter() == parameter) {
+								OutputPin resultPin = resultPins.get(pinNumber - 1);
+								this.putTokens(resultPin, outputParameterValue.getValues());
+							}
 						}
+						pinNumber = pinNumber + 1;
 					}
-					pinNumber = pinNumber + 1;
+					i = i + 1;
 				}
-				i = i + 1;
 			}
 			callExecution.destroy();
 			this.removeCallExecution(callExecution);
diff --git a/plugins/org.eclipse.papyrus.moka.fuml/src/org/eclipse/papyrus/moka/fuml/actions/RaiseExceptionActionActivation.java b/plugins/org.eclipse.papyrus.moka.fuml/src/org/eclipse/papyrus/moka/fuml/actions/RaiseExceptionActionActivation.java
new file mode 100644
index 0000000..6852c00
--- /dev/null
+++ b/plugins/org.eclipse.papyrus.moka.fuml/src/org/eclipse/papyrus/moka/fuml/actions/RaiseExceptionActionActivation.java
@@ -0,0 +1,34 @@
+/*****************************************************************************

+ * Copyright (c) 2020 CEA LIST.

+ *

+ *

+ * All rights reserved. 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:

+ *  Jeremie TATIBOUET (CEA LIST) <jeremie.taibouet@cea.fr>

+  *****************************************************************************/

+

+package org.eclipse.papyrus.moka.fuml.actions;

+

+import java.util.Iterator;

+

+import org.eclipse.papyrus.moka.fuml.simpleclassifiers.IValue;

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

+

+public class RaiseExceptionActionActivation extends ActionActivation{

+

+	@Override

+	public void doAction() {

+		RaiseExceptionAction action  = (RaiseExceptionAction) node;

+		Iterator<IValue> itValue = this.takeTokens(action.getException()).iterator();

+		if(itValue.hasNext()) {

+			propagateException(itValue.next());

+		}

+	}

+	

+}

diff --git a/plugins/org.eclipse.papyrus.moka.fuml/src/org/eclipse/papyrus/moka/fuml/activities/ActivityNodeActivationGroup.java b/plugins/org.eclipse.papyrus.moka.fuml/src/org/eclipse/papyrus/moka/fuml/activities/ActivityNodeActivationGroup.java
index 520952d..fcb71ed 100644
--- a/plugins/org.eclipse.papyrus.moka.fuml/src/org/eclipse/papyrus/moka/fuml/activities/ActivityNodeActivationGroup.java
+++ b/plugins/org.eclipse.papyrus.moka.fuml/src/org/eclipse/papyrus/moka/fuml/activities/ActivityNodeActivationGroup.java
@@ -24,11 +24,6 @@
 import org.eclipse.papyrus.moka.fuml.actions.IExpansionNodeActivation;
 import org.eclipse.papyrus.moka.fuml.actions.IPinActivation;
 import org.eclipse.papyrus.moka.fuml.actions.IStructuredActivityNodeActivation;
-import org.eclipse.papyrus.moka.fuml.activities.IActivityEdgeInstance;
-import org.eclipse.papyrus.moka.fuml.activities.IActivityExecution;
-import org.eclipse.papyrus.moka.fuml.activities.IActivityNodeActivation;
-import org.eclipse.papyrus.moka.fuml.activities.IActivityNodeActivationGroup;
-import org.eclipse.papyrus.moka.fuml.activities.IActivityParameterNodeActivation;
 import org.eclipse.papyrus.moka.fuml.debug.Debug;
 import org.eclipse.uml2.uml.Action;
 import org.eclipse.uml2.uml.ActivityEdge;
@@ -49,29 +44,31 @@
 	public List<IActivityNodeActivation> nodeActivations = new ArrayList<IActivityNodeActivation>();
 
 	/*
-	 * The activity execution to which this group belongs. (This will be empty
-	 * if the group is for a structured activity node activation.)
+	 * The activity execution to which this group belongs. (This will be empty if
+	 * the group is for a structured activity node activation.)
 	 */
 	public IActivityExecution activityExecution;
 
 	/*
-	 * The structured activity node activation to which this group belongs.
-	 * (This will be empty if the group is for an activity execution.)
+	 * The structured activity node activation to which this group belongs. (This
+	 * will be empty if the group is for an activity execution.)
 	 */
 	public IStructuredActivityNodeActivation containingNodeActivation;
 
 	/*
-	 * Activity node activations in this activation group that are suspended
-	 * waiting for an event occurrence. If an activation group has a containing
-	 * node activation and any suspended activations, then the containing node
-	 * activation will also be suspended.
+	 * Activity node activations in this activation group that are suspended waiting
+	 * for an event occurrence. If an activation group has a containing node
+	 * activation and any suspended activations, then the containing node activation
+	 * will also be suspended.
 	 */
 	public List<IActivityNodeActivation> suspendedActivations = new ArrayList<IActivityNodeActivation>();
 
 	public void run(List<IActivityNodeActivation> activations) {
-		// Run the given node activations. 
-		// Then concurrently send offers to all input activity parameter node activations (if any). 
-		// Finally, concurrently send offers to all activations of other kinds of nodes that have 
+		// Run the given node activations.
+		// Then concurrently send offers to all input activity parameter node
+		// activations (if any).
+		// Finally, concurrently send offers to all activations of other kinds of nodes
+		// that have
 		// no incoming edges with the given set (if any).
 		for (int i = 0; i < activations.size(); i++) {
 			IActivityNodeActivation activation = activations.get(i);
@@ -83,7 +80,7 @@
 		for (int i = 0; i < activations.size(); i++) {
 			IActivityNodeActivation activation = activations.get(i);
 			Debug.println("[run] Checking node " + activation.getNode().getName() + "...");
-			if (!(activation instanceof IPinActivation |activation instanceof IExpansionNodeActivation)) {
+			if (!(activation instanceof IPinActivation | activation instanceof IExpansionNodeActivation)) {
 				boolean isEnabled = this.checkIncomingEdges(activation.getIncomingEdges(), activations);
 				// For an action activation, also consider incoming edges to
 				// input pins
@@ -92,7 +89,8 @@
 					int j = 1;
 					while (j <= inputPins.size() & isEnabled) {
 						InputPin inputPin = inputPins.get(j - 1);
-						List<IActivityEdgeInstance> inputEdges = ((IActionActivation) activation).getPinActivation(inputPin).getIncomingEdges();
+						List<IActivityEdgeInstance> inputEdges = ((IActionActivation) activation)
+								.getPinActivation(inputPin).getIncomingEdges();
 						isEnabled = this.checkIncomingEdges(inputEdges, activations);
 						j = j + 1;
 					}
@@ -100,17 +98,17 @@
 				if (isEnabled) {
 					Debug.println("[run] Node " + activation.getNode().getName() + " is enabled.");
 					if (activation instanceof ActivityParameterNodeActivation) {
-					    enabledParameterNodeActivations.add(activation);
+						enabledParameterNodeActivations.add(activation);
 					} else {
-					    enabledOtherActivations.add(activation);
+						enabledOtherActivations.add(activation);
 					}
 				}
 			}
 		}
 		// *** Send offers to all enabled activity parameter nodes concurrently. ***
 		for (Iterator<IActivityNodeActivation> i = enabledParameterNodeActivations.iterator(); i.hasNext();) {
-		    IActivityNodeActivation activation = (IActivityNodeActivation) i.next();
-		    activation.receiveOffer();
+			IActivityNodeActivation activation = (IActivityNodeActivation) i.next();
+			activation.receiveOffer();
 		}
 		// Debug.println("[run] " + enabledActivations.size() +
 		// " node(s) are enabled.");
@@ -122,7 +120,8 @@
 		}
 	}
 
-	public Boolean checkIncomingEdges(List<IActivityEdgeInstance> incomingEdges, List<IActivityNodeActivation> activations) {
+	public Boolean checkIncomingEdges(List<IActivityEdgeInstance> incomingEdges,
+			List<IActivityNodeActivation> activations) {
 		// Check if any incoming edges have a source in a given set of
 		// activations.
 		int j = 1;
@@ -178,7 +177,7 @@
 		// group and create edge instances between them.
 		for (int i = 0; i < nodes.size(); i++) {
 			ActivityNode node = nodes.get(i);
-			Debug.println("[createNodeActivations] Creating a node activation for " + node.getName() + "...");
+			System.out.println("[createNodeActivations] Creating a node activation for " + node.getName() + "...");
 			this.createNodeActivation(node);
 		}
 	}
@@ -189,7 +188,8 @@
 
 		// fUML12-10 certain boolean flags are not properly initialized in come cases
 
-		IActivityNodeActivation activation = (IActivityNodeActivation) (this.getActivityExecution().getLocus().getFactory().instantiateVisitor(node));
+		IActivityNodeActivation activation = (IActivityNodeActivation) (this.getActivityExecution().getLocus()
+				.getFactory().instantiateVisitor(node));
 		activation.initialize(node, this);
 		this.nodeActivations.add(activation);
 		activation.createNodeActivations();
@@ -223,9 +223,11 @@
 
 		for (int i = 0; i < edges.size(); i++) {
 			ActivityEdge edge = edges.get(i);
-			Debug.println("[createEdgeInstances] Creating an edge instance from " + edge.getSource().getName() + " to " + edge.getTarget().getName() + ".");
+			Debug.println("[createEdgeInstances] Creating an edge instance from " + edge.getSource().getName() + " to "
+					+ edge.getTarget().getName() + ".");
 			// Note creation of visitors for edge instance is made by the execution factory
-			IActivityEdgeInstance edgeInstance = (IActivityEdgeInstance) (this.getActivityExecution().getLocus().getFactory().instantiateVisitor(edge));
+			IActivityEdgeInstance edgeInstance = (IActivityEdgeInstance) (this.getActivityExecution().getLocus()
+					.getFactory().instantiateVisitor(edge));
 			edgeInstance.setEdge(edge);
 			edgeInstance.setGroup(this);
 			this.edgeInstances.add(edgeInstance);
@@ -340,7 +342,7 @@
 
 	public void setActivityExecution_(IActivityExecution execution) {
 		this.activityExecution = execution;
-		
+
 	}
 
 	public IActivityExecution getActivityExecution_() {
diff --git a/plugins/org.eclipse.papyrus.moka.fuml/src/org/eclipse/papyrus/moka/fuml/activities/ExceptionHandlerActivation.java b/plugins/org.eclipse.papyrus.moka.fuml/src/org/eclipse/papyrus/moka/fuml/activities/ExceptionHandlerActivation.java
new file mode 100644
index 0000000..bb455b8
--- /dev/null
+++ b/plugins/org.eclipse.papyrus.moka.fuml/src/org/eclipse/papyrus/moka/fuml/activities/ExceptionHandlerActivation.java
@@ -0,0 +1,96 @@
+/*****************************************************************************

+ * Copyright (c) 2020 CEA LIST.

+ *

+ *

+ * All rights reserved. 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:

+ *  Jeremie TATIBOUET (CEA LIST) <jeremie.taibouet@cea.fr>

+  *****************************************************************************/

+

+package org.eclipse.papyrus.moka.fuml.activities;

+

+import java.util.ArrayList;

+import java.util.Iterator;

+import java.util.List;

+

+import org.eclipse.papyrus.moka.fuml.actions.IActionActivation;

+import org.eclipse.papyrus.moka.fuml.actions.IPinActivation;

+import org.eclipse.papyrus.moka.fuml.simpleclassifiers.IValue;

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

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

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

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

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

+

+public class ExceptionHandlerActivation implements IExceptionHandlerActivation {

+

+	protected ExceptionHandler handler;

+

+	protected IActionActivation declaringActionActivation;

+

+	public void setHandler(ExceptionHandler handler) {

+		this.handler = handler;

+	}

+	

+	@Override

+	public void setDeclaringActionActivation(IActionActivation activation) {

+		declaringActionActivation = activation;

+	}

+

+	public boolean match(IValue exception) {

+		boolean match = false;

+		if (handler != null && exception != null) {

+			Iterator<Classifier> itExceptionTypes = handler.getExceptionTypes().iterator();

+			while (!match && itExceptionTypes.hasNext()) {

+				match = exception.isInstanceOf(itExceptionTypes.next());

+			}

+		}

+		return match;

+	}

+

+	@Override

+	public boolean handle(IValue exception) {

+		boolean handled = false;

+		if (declaringActionActivation != null && exception != null) {

+			IActivityNodeActivationGroup group = declaringActionActivation.getGroup();

+			if (group != null) {

+				IActionActivation actionActivation = (IActionActivation) group

+						.getNodeActivation(handler.getHandlerBody());

+				if (actionActivation != null) {

+					IPinActivation pinActivation = actionActivation.getPinActivation((Pin) handler.getExceptionInput());

+					if(pinActivation != null) {

+						IObjectToken token = new ObjectToken();

+						token.setValue(exception);

+						pinActivation.addToken(token);

+						if(actionActivation.isReady()) {

+							handled = true;

+							actionActivation.receiveOffer();

+							transferOutputs(actionActivation);

+						}

+					}

+				}

+			}

+		}

+		return handled;

+	}

+	

+	public void transferOutputs(IActionActivation source) {

+		List<OutputPin> sourceOutputs = ((Action)source.getNode()).getOutputs();

+		List<OutputPin> targetOutputs = ((Action)declaringActionActivation.getNode()).getOutputs();

+		for(int i = 0; i < sourceOutputs.size(); i++) {

+			IPinActivation sourcePinActivation = source.getPinActivation(sourceOutputs.get(i));

+			List<IValue> values = new ArrayList<IValue>();

+			for(IToken token : sourcePinActivation.takeTokens()) {

+				values.add(token.getValue());

+			}

+			declaringActionActivation.putTokens(targetOutputs.get(i), values);

+		}

+	}

+

+}

diff --git a/plugins/org.eclipse.papyrus.moka.fuml/src/org/eclipse/papyrus/moka/fuml/commonbehavior/Execution.java b/plugins/org.eclipse.papyrus.moka.fuml/src/org/eclipse/papyrus/moka/fuml/commonbehavior/Execution.java
index 3c20064..9acbc5c 100644
--- a/plugins/org.eclipse.papyrus.moka.fuml/src/org/eclipse/papyrus/moka/fuml/commonbehavior/Execution.java
+++ b/plugins/org.eclipse.papyrus.moka.fuml/src/org/eclipse/papyrus/moka/fuml/commonbehavior/Execution.java
@@ -41,9 +41,23 @@
 	 * is executed.
 	 */
 	public List<IParameterValue> parameterValues = new ArrayList<IParameterValue>();
+	
+	/*
+	 * The exception that implied the execution termination
+	 */
+	public IValue exception;
 
 	public abstract void execute();
 
+	public void propagateException(IValue exception) {
+		this.exception = exception;
+	}
+	
+	@Override
+	public IValue getException() {
+		return exception;
+	}
+	
 	public void terminate() {
 		// Terminate an ongoing execution. By default, do nothing.
 		return;
diff --git a/plugins/org.eclipse.papyrus.moka.fuml/src/org/eclipse/papyrus/moka/fuml/debug/Debug.java b/plugins/org.eclipse.papyrus.moka.fuml/src/org/eclipse/papyrus/moka/fuml/debug/Debug.java
index 3e634b1..1e557a9 100644
--- a/plugins/org.eclipse.papyrus.moka.fuml/src/org/eclipse/papyrus/moka/fuml/debug/Debug.java
+++ b/plugins/org.eclipse.papyrus.moka.fuml/src/org/eclipse/papyrus/moka/fuml/debug/Debug.java
@@ -3,7 +3,7 @@
 public class Debug {
 
 	public static void println(String message) {
-		// System.err.println(message) ;
+		System.out.println(message) ;
 		// FIXME Bug 404555: [Moka] Pollution of the console with debug messages
 		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=404555
 	}
diff --git a/plugins/org.eclipse.papyrus.moka.fuml/src/org/eclipse/papyrus/moka/fuml/loci/ExecutionFactoryL3.java b/plugins/org.eclipse.papyrus.moka.fuml/src/org/eclipse/papyrus/moka/fuml/loci/ExecutionFactoryL3.java
index 32e2760..5898cf4 100644
--- a/plugins/org.eclipse.papyrus.moka.fuml/src/org/eclipse/papyrus/moka/fuml/loci/ExecutionFactoryL3.java
+++ b/plugins/org.eclipse.papyrus.moka.fuml/src/org/eclipse/papyrus/moka/fuml/loci/ExecutionFactoryL3.java
@@ -21,6 +21,7 @@
 import org.eclipse.papyrus.moka.fuml.actions.ExpansionNodeActivation;
 import org.eclipse.papyrus.moka.fuml.actions.ExpansionRegionActivation;
 import org.eclipse.papyrus.moka.fuml.actions.LoopNodeActivation;
+import org.eclipse.papyrus.moka.fuml.actions.RaiseExceptionActionActivation;
 import org.eclipse.papyrus.moka.fuml.actions.ReadExtentActionActivation;
 import org.eclipse.papyrus.moka.fuml.actions.ReadIsClassifiedObjectActionActivation;
 import org.eclipse.papyrus.moka.fuml.actions.ReclassifyObjectActionActivation;
@@ -39,6 +40,7 @@
 import org.eclipse.uml2.uml.ExpansionNode;
 import org.eclipse.uml2.uml.ExpansionRegion;
 import org.eclipse.uml2.uml.LoopNode;
+import org.eclipse.uml2.uml.RaiseExceptionAction;
 import org.eclipse.uml2.uml.ReadExtentAction;
 import org.eclipse.uml2.uml.ReadIsClassifiedObjectAction;
 import org.eclipse.uml2.uml.ReclassifyObjectAction;
@@ -95,6 +97,8 @@
 			visitor = new ReplyActionActivation();
  		} else if (element instanceof ReduceAction) {
 			visitor = new ReduceActionActivation();
+		} else if(element instanceof RaiseExceptionAction) {
+			visitor = new RaiseExceptionActionActivation();
 		} else {
 			visitor = super.instantiateVisitor(element);
 		}