diff --git a/.idea/libraries/jfreechart_1_6_0.xml b/.idea/libraries/jfreechart_1_6_0.xml
new file mode 100644
index 0000000000000000000000000000000000000000..81658e8f4cb20872e84ae720403f783b6878c836
--- /dev/null
+++ b/.idea/libraries/jfreechart_1_6_0.xml
@@ -0,0 +1,9 @@
+<component name="libraryTable">
+  <library name="jfreechart-1.6.0">
+    <CLASSES>
+      <root url="jar://$PROJECT_DIR$/libs/jfreechart-1.6.0.jar!/" />
+    </CLASSES>
+    <JAVADOC />
+    <SOURCES />
+  </library>
+</component>
\ No newline at end of file
diff --git a/executablecode/Makefile.src b/executablecode/Makefile.src
index 10b9edc5f5c133db845361973a875e085fa48d5f..2b21a39070bcbe168dfc79673113a530049f595d 100755
--- a/executablecode/Makefile.src
+++ b/executablecode/Makefile.src
@@ -1 +1 @@
-SRCS = generated_src/main.c generated_src/Receiver.c generated_src/Forwarder.c generated_src/Sender.c 
\ No newline at end of file
+SRCS = generated_src/main.c generated_src/System.c generated_src/Bob.c generated_src/Alice.c 
\ No newline at end of file
diff --git a/launcher/src/main/launcher.iml b/launcher/src/main/launcher.iml
index 350eeee3b31b2565a828c07d5f8e87856f692dd3..77beed6a0ca8b773555c54f75a8f0f0abae7ba5e 100644
--- a/launcher/src/main/launcher.iml
+++ b/launcher/src/main/launcher.iml
@@ -10,5 +10,6 @@
     <orderEntry type="inheritedJdk" />
     <orderEntry type="sourceFolder" forTests="false" />
     <orderEntry type="module" module-name="shared" />
+    <orderEntry type="library" name="jfreechart-1.6.0" level="project" />
   </component>
 </module>
\ No newline at end of file
diff --git a/libs/jfreechart-1.6.0.jar b/libs/jfreechart-1.6.0.jar
new file mode 100644
index 0000000000000000000000000000000000000000..2878c7168d1bf7b87d4fe01cb48cecea45581641
Binary files /dev/null and b/libs/jfreechart-1.6.0.jar differ
diff --git a/modeling/AVATAR/CoffeeMachine_Avatar.xml b/modeling/AVATAR/CoffeeMachine_Avatar.xml
index ff5c4f080a101d2b6c4824fc743e86b4561b893d..489d7a4c0a2da7fc274317d0074b3877c4adb951 100644
--- a/modeling/AVATAR/CoffeeMachine_Avatar.xml
+++ b/modeling/AVATAR/CoffeeMachine_Avatar.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 
-<TURTLEGMODELING version="1.0beta" ANIMATE_INTERACTIVE_SIMULATION="false" ACTIVATE_PENALTIES="true" UPDATE_INFORMATION_DIPLO_SIM="false" ANIMATE_WITH_INFO_DIPLO_SIM="true" OPEN_DIAG_DIPLO_SIM="false" LAST_SELECTED_MAIN_TAB="1" LAST_SELECTED_SUB_TAB="0">
+<TURTLEGMODELING version="1.0beta" ANIMATE_INTERACTIVE_SIMULATION="false" ACTIVATE_PENALTIES="true" UPDATE_INFORMATION_DIPLO_SIM="false" ANIMATE_WITH_INFO_DIPLO_SIM="true" OPEN_DIAG_DIPLO_SIM="false" LAST_SELECTED_MAIN_TAB="1" LAST_SELECTED_SUB_TAB="1">
 
 <Modeling type="Avatar Requirement" nameTab="AVATAR Requirements" >
 <AvatarRDPanel name="AVATAR RD" minX="10" maxX="1900" minY="10" maxY="1400" zoom="1.0" >
@@ -1279,7 +1279,7 @@
 <MainCode value="}"/>
 <Optimized value="true" />
 <considerTimingOperators value="true" />
-<Validated value="" />
+<Validated value="Wallet;CoffeeMachine;TeaButton;CoffeeButton;" />
 <Ignored value="" />
 
 <CONNECTOR type="5002" id="695" >
diff --git a/src/main/java/avatartranslator/directsimulation/AvatarSimulationRunner.java b/src/main/java/avatartranslator/directsimulation/AvatarSimulationRunner.java
new file mode 100644
index 0000000000000000000000000000000000000000..751aa045633635c7e87641c47b78952401ebaf7a
--- /dev/null
+++ b/src/main/java/avatartranslator/directsimulation/AvatarSimulationRunner.java
@@ -0,0 +1,129 @@
+/* Copyright or (C) or Copr. GET / ENST, Telecom-Paris, Ludovic Apvrille
+ *
+ * ludovic.apvrille AT enst.fr
+ *
+ * This software is a computer program whose purpose is to allow the
+ * edition of TURTLE analysis, design and deployment diagrams, to
+ * allow the generation of RT-LOTOS or Java code from this diagram,
+ * and at last to allow the analysis of formal validation traces
+ * obtained from external tools, e.g. RTL from LAAS-CNRS and CADP
+ * from INRIA Rhone-Alpes.
+ *
+ * This software is governed by the CeCILL  license under French law and
+ * abiding by the rules of distribution of free software.  You can  use,
+ * modify and/ or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and  rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty  and the software's author,  the holder of the
+ * economic rights,  and the successive licensors  have only  limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading,  using,  modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean  that it is complicated to manipulate,  and  that  also
+ * therefore means  that it is reserved for developers  and  experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and,  more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ */
+
+
+package avatartranslator.directsimulation;
+
+import avatartranslator.AvatarBlock;
+import avatartranslator.AvatarSpecification;
+import avatartranslator.AvatarStateMachineElement;
+import myutil.TraceManager;
+
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.LinkedList;
+import java.util.Vector;
+
+/**
+ * Class AvatarSimulationRunner
+ * Executor for multiple simulations
+ * Creation: 08/01/2021
+ *
+ * @author Ludovic APVRILLE
+ * @version 1.0 08/01/2021
+ */
+
+public class AvatarSimulationRunner {
+
+   private AvatarSpecification as;
+
+   public ArrayList<AvatarSpecificationSimulation> listOfSimulations;
+
+    public AvatarSimulationRunner(AvatarSpecification _as) {
+       as = _as;
+    }
+
+    public synchronized void runXSimulation(int nbOfSimulations, AvatarSimulationRunnerListener listener) {
+        if (nbOfSimulations < 1) {
+            return;
+        }
+
+        listOfSimulations = new ArrayList<>(nbOfSimulations);
+
+        for (int simulationIndex=0; simulationIndex<nbOfSimulations; simulationIndex++) {
+            //TraceManager.addDev("Simulation #" + simulationIndex);
+            listener.setSimulationDone(simulationIndex);
+            AvatarSpecificationSimulation ass = new AvatarSpecificationSimulation(as, null);
+            listOfSimulations.add(ass);
+            ass.runSimulationToCompletion();
+        }
+    }
+
+    public synchronized long getMinSimulationTime() {
+        if (listOfSimulations == null) {
+            return -1;
+        }
+        long minSimTime = Long.MAX_VALUE;
+        for(AvatarSpecificationSimulation ass: listOfSimulations) {
+            minSimTime = Math.min(ass.getClockValue(), minSimTime);
+        }
+        return minSimTime;
+    }
+
+    public synchronized long getMaxSimulationTime() {
+        if (listOfSimulations == null) {
+            return -1;
+        }
+        long maxSimTime = -1;
+        for(AvatarSpecificationSimulation ass: listOfSimulations) {
+            maxSimTime = Math.max(ass.getClockValue(), maxSimTime);
+        }
+        return maxSimTime;
+    }
+
+    public synchronized double getAverageSimulationTime() {
+        if (listOfSimulations == null) {
+            return -1;
+        }
+        double averageSimTime = 0;
+        for(AvatarSpecificationSimulation ass: listOfSimulations) {
+            averageSimTime += ass.getClockValue() / listOfSimulations.size();
+        }
+        return averageSimTime;
+    }
+
+    public synchronized double[] getSimulationTimes() {
+        double[] values = new double[listOfSimulations.size()];
+        for(int i=0; i< listOfSimulations.size(); i++) {
+            values[i] = listOfSimulations.get(i).getClockValue();
+        }
+        return values;
+    }
+
+
+}
diff --git a/src/main/java/avatartranslator/directsimulation/AvatarSimulationTransaction.java b/src/main/java/avatartranslator/directsimulation/AvatarSimulationTransaction.java
index 38b52722c0916277adadb4c6c7681a6522f8d94e..83c52358d5bfe3b2e22ecee8c9f1d67a75135429 100644
--- a/src/main/java/avatartranslator/directsimulation/AvatarSimulationTransaction.java
+++ b/src/main/java/avatartranslator/directsimulation/AvatarSimulationTransaction.java
@@ -1,26 +1,26 @@
 /* Copyright or (C) or Copr. GET / ENST, Telecom-Paris, Ludovic Apvrille
- * 
+ *
  * ludovic.apvrille AT enst.fr
- * 
+ *
  * This software is a computer program whose purpose is to allow the
  * edition of TURTLE analysis, design and deployment diagrams, to
  * allow the generation of RT-LOTOS or Java code from this diagram,
  * and at last to allow the analysis of formal validation traces
  * obtained from external tools, e.g. RTL from LAAS-CNRS and CADP
  * from INRIA Rhone-Alpes.
- * 
+ *
  * This software is governed by the CeCILL  license under French law and
  * abiding by the rules of distribution of free software.  You can  use,
  * modify and/ or redistribute the software under the terms of the CeCILL
  * license as circulated by CEA, CNRS and INRIA at the following URL
  * "http://www.cecill.info".
- * 
+ *
  * As a counterpart to the access to the source code and  rights to copy,
  * modify and redistribute granted by the license, users are provided only
  * with a limited warranty  and the software's author,  the holder of the
  * economic rights,  and the successive licensors  have only  limited
  * liability.
- * 
+ *
  * In this respect, the user's attention is drawn to the risks associated
  * with loading,  using,  modifying and/or developing or reproducing the
  * software by the user in light of its specific status of free software,
@@ -31,15 +31,12 @@
  * requirements in conditions enabling the security of their systems and/or
  * data to be ensured and,  more generally, to use and operate it in the
  * same conditions as regards security.
- * 
+ *
  * The fact that you are presently reading this means that you have had
  * knowledge of the CeCILL license and that you accept its terms.
  */
 
 
-
-
-
 package avatartranslator.directsimulation;
 
 import avatartranslator.AvatarBlock;
@@ -50,13 +47,14 @@ import java.util.LinkedList;
 import java.util.Vector;
 
 /**
-   * Class AvatarSimulationTransaction
-   * Avatar: notion of transaction in simulation
-   * Creation: 14/12/2010
-   * @version 1.0 14/12/2010
-   * @author Ludovic APVRILLE
+ * Class AvatarSimulationTransaction
+ * Avatar: notion of transaction in simulation
+ * Creation: 14/12/2010
+ *
+ * @author Ludovic APVRILLE
+ * @version 1.0 14/12/2010
  */
-public class AvatarSimulationTransaction  {
+public class AvatarSimulationTransaction {
 
     public static long ID;
     public static Hashtable<AvatarStateMachineElement, Integer> hashOfAllElements;
@@ -82,7 +80,7 @@ public class AvatarSimulationTransaction  {
     public Vector<String> attributeValues;
     public Vector<String> actions;
 
-    public int x,y; // for graphical representation only
+    public int x, y; // for graphical representation only
     public long stamp;
 
     public AvatarSimulationAsynchronousTransaction sentMessage;
@@ -113,22 +111,22 @@ public class AvatarSimulationTransaction  {
         if (val == null) {
             hashOfAllElements.put(_asme, new Integer(1));
         } else {
-            hashOfAllElements.put(_asme, new Integer(1+val.intValue()));
+            hashOfAllElements.put(_asme, new Integer(1 + val.intValue()));
         }
 
     }
 
     public static void removeExecutedElement(AvatarStateMachineElement _asme) {
         if (!allExecutedElements.contains(_asme)) {
-            return ;
+            return;
         }
 
         Integer val = hashOfAllElements.get(_asme);
         if (val == null) {
-            return ;
+            return;
         }
 
-        hashOfAllElements.put(_asme, new Integer(val.intValue()-1));
+        hashOfAllElements.put(_asme, new Integer(val.intValue() - 1));
 
 
     }
@@ -144,7 +142,7 @@ public class AvatarSimulationTransaction  {
     }
 
     public String toString() {
-        String res = "" + id + " bunchid:" + bunchid + " @" + clockValueWhenFinished + "/ " + duration + ": " +executedElement + " in block " + block.getName();
+        String res = "" + id + " bunchid:" + bunchid + " @" + clockValueWhenFinished + "/ " + duration + ": " + executedElement + " in block " + block.getName();
         if (silent) {
             res += " (silent)";
         }
@@ -156,20 +154,45 @@ public class AvatarSimulationTransaction  {
             }
         }
         res += "\nattributes=";
-        for(String s: attributeValues) {
+        for (String s : attributeValues) {
             res += s + " ";
         }
         if (actions != null) {
             int cpt = 0;
-            res+= "\n";
-            for(String action: actions) {
+            res += "\n";
+            for (String action : actions) {
                 res += "action#" + cpt + ": " + action + " ";
-                cpt ++;
+                cpt++;
             }
         }
         return res;
     }
 
+    public String getAttributesString() {
+        String res = "";
+        for (String s : attributeValues) {
+            res += s + " ";
+        }
+        return res;
+    }
+
+    public String getActionsString() {
+        if ((actions == null) || (actions.size() == 0)) {
+            return "null";
+        }
+
+        String res = "";
+
+        int cpt = 0;
+        //res+= "\n";
+        for (String action : actions) {
+            res += "action#" + cpt + ": " + action + " ";
+            cpt++;
+        }
+
+        return res;
+    }
+
     public boolean setAttributeValue(int _index, String _value) {
         if (_index >= attributeValues.size()) {
             return false;
diff --git a/src/main/java/avatartranslator/directsimulation/AvatarSpecificationSimulation.java b/src/main/java/avatartranslator/directsimulation/AvatarSpecificationSimulation.java
index 13bfbedd912055476c1eb7af5c306ea39250d638..ea34e94d50c3e066300e69dd829aef9fef7607a2 100644
--- a/src/main/java/avatartranslator/directsimulation/AvatarSpecificationSimulation.java
+++ b/src/main/java/avatartranslator/directsimulation/AvatarSpecificationSimulation.java
@@ -56,6 +56,9 @@ import java.util.Vector;
  * @version 1.0 13/12/2010
  */
 public class AvatarSpecificationSimulation {
+
+    public final static String COMMA = ", ";
+
     public static int MAX_TRANSACTION_IN_A_ROW = 1000;
 
     public static int MAX_TRANSACTIONS = 100000;
@@ -227,6 +230,25 @@ public class AvatarSpecificationSimulation {
 
     // Control function
 
+    public void runSimulationToCompletion() {
+        Thread t = new Thread() {
+            public void run() {
+                runSimulation();
+            }
+        };
+
+        t.start();
+        goSimulation();
+        try {
+            while(getState() != TERMINATED) {
+                Thread.currentThread().sleep(25);
+                //TraceManager.addDev("Waiting for termination");
+            };
+            killSimulation();
+            t.join();
+        } catch (InterruptedException ie) {}
+    }
+
     public void runSimulation() {
         int index[];
         Vector<AvatarSimulationPendingTransaction> selectedTransactions;
@@ -350,18 +372,18 @@ public class AvatarSpecificationSimulation {
                     break;
 
                 case TERMINATED:
-                    TraceManager.addDev("-> -> TERMINATED");
+                    //TraceManager.addDev("-> -> TERMINATED");
                     waitForResetOrNewState();
                     break;
 
                 case KILLED:
-                    TraceManager.addDev("-> -> KILLED");
-                    TraceManager.addDev("Simulation killed");
+                    //TraceManager.addDev("-> -> KILLED");
+                    //TraceManager.addDev("Simulation killed");
                     return;
 
                 default:
                     TraceManager.addDev("-> -> UNKNOWN");
-                    TraceManager.addDev("Unknown state");
+                    //TraceManager.addDev("Unknown state");
                     setState(KILLED);
             }
 
@@ -1586,4 +1608,64 @@ public class AvatarSpecificationSimulation {
 
         return found;
     }
+
+    public String toCSV() {
+        StringBuffer sb = new StringBuffer();
+
+        sb.append("ID, block, element ID, linked transaction ID, initial clock value, final clock value, duration, attributes, actions\n");
+        for(AvatarSimulationTransaction ast: allTransactions) {
+            append(sb, ast.id);
+            append(sb, ast.block);
+            append(sb, ast.executedElement);
+            append(sb, ast.linkedTransaction);
+            append(sb, ast.initialClockValue);
+            append(sb, ast.clockValueWhenFinished);
+            append(sb, ast.duration);
+            append(sb, ast.getAttributesString());
+            sb.append(ast.getActionsString());
+            sb.append("\n");
+        }
+
+
+        return sb.toString();
+    }
+
+    public void append(StringBuffer sb, String s) {
+        if ((s == null) || (s.length() ==0)) {
+            sb.append("null" + COMMA);
+        } else {
+            sb.append(s + COMMA);
+        }
+    }
+
+    public void append(StringBuffer sb, long s) {
+        sb.append(s + COMMA);
+    }
+
+    public void append(StringBuffer sb, AvatarBlock b) {
+        if (b == null) {
+            sb.append("__Unknown" + COMMA);
+        } else {
+            sb.append(b.getName() + COMMA);
+        }
+    }
+
+    public void append(StringBuffer sb, AvatarStateMachineElement asme) {
+        if (asme == null) {
+            sb.append("-1" + COMMA);
+        } else {
+            sb.append(asme.getID() + COMMA);
+        }
+    }
+
+    public void append(StringBuffer sb, AvatarSimulationTransaction ast) {
+        if (ast == null) {
+            sb.append("-1" + COMMA);
+        } else {
+            sb.append(ast.bunchid + COMMA);
+        }
+    }
+
+
+
 }
diff --git a/src/main/java/cli/Action.java b/src/main/java/cli/Action.java
index c12ae2b97694780b64db497c5e26e4930490944c..b6323645fe5c4c763a4895939e48a8c1a0d99065 100644
--- a/src/main/java/cli/Action.java
+++ b/src/main/java/cli/Action.java
@@ -40,6 +40,7 @@
 package cli;
 
 import avatartranslator.AvatarSpecification;
+import avatartranslator.directsimulation.AvatarSpecificationSimulation;
 import avatartranslator.modelchecker.AvatarModelChecker;
 import avatartranslator.modelchecker.CounterexampleQueryReport;
 import avatartranslator.modelchecker.SpecificationActionLoop;
@@ -97,6 +98,7 @@ public class Action extends Command {
     private final static String DIPLO_UPPAAL = "diplodocus-uppaal";
     private final static String DIPLO_REMOVE_NOC = "diplodocus-remove-noc";
 
+
     private final static String NAVIGATE_PANEL_TO_LEFT = "navigate-panel-to-left";
     private final static String NAVIGATE_PANEL_TO_RIGHT = "navigate-panel-to-right";
 
@@ -106,7 +108,10 @@ public class Action extends Command {
 
     private final static String AVATAR_RG_GENERATION = "avatar-rg";
     private final static String AVATAR_UPPAAL_VALIDATE = "avatar-rg-validate";
+    private final static String AVATAR_SIMULATION_TO_BRK = "avatar-simulation-to-brk";
+
 
+    private AvatarSpecificationSimulation ass;
 
     public Action() {
 
@@ -751,6 +756,12 @@ public class Action extends Command {
             }
         };
 
+
+
+
+
+
+        // PANEL manipulation
         Command selectPanel = new Command() {
             public String getCommand() {
                 return SELECT_PANEL;
@@ -1259,6 +1270,58 @@ public class Action extends Command {
             }
         };
 
+        // AVATAR
+        Command avatarSimulationToBrk = new Command() {
+            public String getCommand() {
+                return AVATAR_SIMULATION_TO_BRK;
+            }
+
+            public String getShortCommand() {
+                return "astb";
+            }
+
+            public String getDescription() {
+                return "Simulate an avatar design until a breakpoint or the end";
+            }
+
+            public String executeCommand(String command, Interpreter interpreter) {
+                if (!interpreter.isTToolStarted()) {
+                    return Interpreter.TTOOL_NOT_STARTED;
+                }
+
+                AvatarSpecification as = interpreter.mgui.gtm.getAvatarSpecification();
+
+                if (as == null) {
+                    return "No model for simulation";
+                }
+
+                ass = new AvatarSpecificationSimulation(as, null);
+                ass.runSimulationToCompletion();
+
+                /*Thread t = new Thread() {
+                    public void run() {
+                        ass.runSimulation();
+                    }
+                };
+
+                t.start();
+                ass.goSimulation();
+                try {
+                    while(ass.getState() != ass.TERMINATED) {
+                        Thread.currentThread().sleep(25);
+                        //TraceManager.addDev("Waiting for termination");
+                    };
+                    ass.killSimulation();
+                    t.join();
+                } catch (InterruptedException ie) {}*/
+
+                TraceManager.addUser("Simulation terminated. End time=" + ass.getClockValue());
+
+
+                return null;
+            }
+        };
+
 
 
         Command generic = new Generic();
@@ -1289,6 +1352,7 @@ public class Action extends Command {
         addAndSortSubcommand(movePanelToTheRightPanel);
         addAndSortSubcommand(selectPanel);
         addAndSortSubcommand(compareUppaal);
+        addAndSortSubcommand(avatarSimulationToBrk);
         addAndSortSubcommand(generic);
 
     }
diff --git a/src/main/java/ui/avatarinteractivesimulation/AvatarInteractiveSimulationActions.java b/src/main/java/ui/avatarinteractivesimulation/AvatarInteractiveSimulationActions.java
index ae9950ed37186e9eb5f037c0e9a73c965886efdb..3e5226420c6cb8b1c27ae1e252501be393950dc9 100755
--- a/src/main/java/ui/avatarinteractivesimulation/AvatarInteractiveSimulationActions.java
+++ b/src/main/java/ui/avatarinteractivesimulation/AvatarInteractiveSimulationActions.java
@@ -76,6 +76,7 @@ public class AvatarInteractiveSimulationActions extends AbstractAction {
     public static final int ACT_SAVE_SD_PNG = 10;
     public static final int ACT_SAVE_SVG = 11;
     public static final int ACT_SAVE_TXT = 12;
+    public static final int ACT_SAVE_CSV = 37;
 
     public static final int ACT_PRINT_BENCHMARK = 26;
     public static final int ACT_SAVE_BENCHMARK = 27;
@@ -104,7 +105,8 @@ public class AvatarInteractiveSimulationActions extends AbstractAction {
     public static final int ACT_DOWN_ASYNC_MSG = 34;
     public static final int ACT_ADD_LATENCY = 35;
     public static final int ACT_REMOVE_ALL_TRANS = 36;
-    public static final int NB_ACTION = 37;
+
+    public static final int NB_ACTION = 38;
 
 
     private static final TAction[] actions = new TAction[NB_ACTION];
@@ -164,6 +166,9 @@ public class AvatarInteractiveSimulationActions extends AbstractAction {
         actions[ACT_SAVE_SD_PNG] = new TAction("save-sd-png", "Save SD trace in PNG format", IconManager.imgic5104, IconManager.imgic5104, "Save SD trace in PNG format", "Save SD trace in PNG format", '0');
         actions[ACT_SAVE_SVG] = new TAction("save-svg", "Save trace in SVG format", IconManager.imgic1328, IconManager.imgic1328, "Save trace in SVG format", "Save trace in SVG format", 'R');
         actions[ACT_SAVE_TXT] = new TAction("save-txt", "Save trace in TXT format", IconManager.imgic1314, IconManager.imgic1314, "Save trace in TXT format", "Save trace in TXT format", 'R');
+        actions[ACT_SAVE_CSV] = new TAction("save-csv", "Save trace in CSV format", IconManager.imgic1334, IconManager.imgic1334, "Save trace in " +
+                "CSV " +
+                "format", "Save trace in CSV format", 'V');
 
         actions[ACT_SAVE_STATE] = new TAction("save-state", "Save simulation state in File", IconManager.imgic341, IconManager.imgic341, "Save simulation state in File", "Save simulation state in File", 'R');
         actions[ACT_RESTORE_STATE] = new TAction("restore-state", "Restore simulation state from File", IconManager.imgic339, IconManager.imgic339, "Restore simulation state from File", "Restore simulation state from File", 'R');
diff --git a/src/main/java/ui/avatarinteractivesimulation/AvatarSaveCommandsToolBar.java b/src/main/java/ui/avatarinteractivesimulation/AvatarSaveCommandsToolBar.java
index de049ddf1473237dc800a146281a58da10f5e8fe..f35ba92a96c847d47aa55b6917e1ec9c49624fd5 100755
--- a/src/main/java/ui/avatarinteractivesimulation/AvatarSaveCommandsToolBar.java
+++ b/src/main/java/ui/avatarinteractivesimulation/AvatarSaveCommandsToolBar.java
@@ -61,6 +61,7 @@ public class AvatarSaveCommandsToolBar extends AvatarInteractiveSimulationBar {
 		jfais.actions[AvatarInteractiveSimulationActions.ACT_SAVE_SD_PNG].setEnabled(b);
 		jfais.actions[AvatarInteractiveSimulationActions.ACT_SAVE_SVG].setEnabled(b);
 		jfais.actions[AvatarInteractiveSimulationActions.ACT_SAVE_TXT].setEnabled(b);
+        jfais.actions[AvatarInteractiveSimulationActions.ACT_SAVE_CSV].setEnabled(b);
     }
     
     protected void setButtons() {
@@ -78,6 +79,11 @@ public class AvatarSaveCommandsToolBar extends AvatarInteractiveSimulationBar {
 		
 		button = this.add(jfais.actions[AvatarInteractiveSimulationActions.ACT_SAVE_TXT]);
         button.addMouseListener(jfais.mouseHandler);
+
+        this.addSeparator();
+
+        button = this.add(jfais.actions[AvatarInteractiveSimulationActions.ACT_SAVE_CSV]);
+        button.addMouseListener(jfais.mouseHandler);
         
     }
 } // Class
diff --git a/src/main/java/ui/avatarinteractivesimulation/AvatarSimulationStatisticsPanel.java b/src/main/java/ui/avatarinteractivesimulation/AvatarSimulationStatisticsPanel.java
new file mode 100644
index 0000000000000000000000000000000000000000..1c6ebff8ca6b8a2e9119aa1dfd751d44442bee39
--- /dev/null
+++ b/src/main/java/ui/avatarinteractivesimulation/AvatarSimulationStatisticsPanel.java
@@ -0,0 +1,267 @@
+/* Copyright or (C) or Copr. GET / ENST, Telecom-Paris, Ludovic Apvrille
+ * 
+ * ludovic.apvrille AT enst.fr
+ * 
+ * This software is a computer program whose purpose is to allow the
+ * edition of TURTLE analysis, design and deployment diagrams, to
+ * allow the generation of RT-LOTOS or Java code from this diagram,
+ * and at last to allow the analysis of formal validation traces
+ * obtained from external tools, e.g. RTL from LAAS-CNRS and CADP
+ * from INRIA Rhone-Alpes.
+ * 
+ * This software is governed by the CeCILL  license under French law and
+ * abiding by the rules of distribution of free software.  You can  use,
+ * modify and/ or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ * 
+ * As a counterpart to the access to the source code and  rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty  and the software's author,  the holder of the
+ * economic rights,  and the successive licensors  have only  limited
+ * liability.
+ * 
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading,  using,  modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean  that it is complicated to manipulate,  and  that  also
+ * therefore means  that it is reserved for developers  and  experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and,  more generally, to use and operate it in the
+ * same conditions as regards security.
+ * 
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ */
+
+
+
+
+
+package ui.avatarinteractivesimulation;
+
+import avatartranslator.*;
+import avatartranslator.directsimulation.*;
+import myutil.GraphicLib;
+import myutil.TraceManager;
+import org.jfree.chart.ChartFactory;
+import org.jfree.chart.ChartPanel;
+import org.jfree.chart.JFreeChart;
+import org.jfree.chart.plot.PlotOrientation;
+import org.jfree.data.statistics.HistogramDataset;
+import org.jfree.data.xy.XYSeries;
+import org.jfree.data.xy.XYSeriesCollection;
+import ui.ColorManager;
+import ui.MainGUI;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseMotionListener;
+import java.awt.image.BufferedImage;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Vector;
+
+/**
+   * Class AvatarSimulationStatisticsPanel
+   * Avatar: panel for performing simulations and displaying statistics
+   * Creation: 08/01/2021
+   * @version 1.0 08/01/2021
+   * @author Ludovic APVRILLE
+ */
+public class AvatarSimulationStatisticsPanel extends JPanel implements ActionListener, AvatarSimulationRunnerListener {
+    private MainGUI mgui;
+
+    // Graphical components
+    private JButton runSimulations;
+    private JTextField nbOfSimulationsText;
+
+
+    private JLabel simulationsDone;
+    private JLabel totalSimulations;
+
+    private JLabel minSimulationTime;
+    private JLabel averageSimulationTime;
+    private JLabel maxSimulationTime;
+
+    private JButton showSimulationTimeHistogram;
+
+
+    // Simulation data structures
+    private int totalNbOfSimulations;
+    private AvatarSimulationRunner sr;
+
+
+
+
+    public AvatarSimulationStatisticsPanel(MainGUI _mgui) {
+      mgui = _mgui;
+      makeComponents();
+    }
+
+    public void makeComponents() {
+
+
+        GridBagLayout gridbag2 = new GridBagLayout();
+        GridBagConstraints c2 = new GridBagConstraints();
+        setLayout(gridbag2);
+        //setBorder(new javax.swing.border.TitledBorder("Managing transactions"));
+
+        // Simulations
+        c2.weighty = 1.0;
+        c2.weightx = 1.0;
+        c2.fill = GridBagConstraints.HORIZONTAL;
+        c2.gridheight = 1;
+        c2.gridwidth = 1;
+        runSimulations = new JButton("Execute");
+        runSimulations.addActionListener(this);
+        add(runSimulations, c2);
+        nbOfSimulationsText = new JTextField("100", 10);
+        add(nbOfSimulationsText, c2);
+        c2.gridwidth = GridBagConstraints.REMAINDER;
+        add(new JLabel("simulations"), c2);
+
+        add(new JLabel(""), c2);
+        add(new JLabel("Simulation progression"), c2);
+        c2.gridwidth = 1;
+        simulationsDone = new JLabel ("-");
+        totalSimulations = new JLabel("-");
+        add(simulationsDone, c2);
+        add(new JLabel("/"), c2);
+        c2.gridwidth = GridBagConstraints.REMAINDER;
+        add(totalSimulations, c2);
+
+        // **** Stats ****
+
+        // Simulation time
+        add(new JLabel("Simulation time (min, max, average)"), c2);
+        c2.gridwidth = 1;
+        minSimulationTime = new JLabel("-");
+        add(minSimulationTime, c2);
+        averageSimulationTime = new JLabel("-");
+        add(averageSimulationTime, c2);
+        c2.gridwidth = GridBagConstraints.REMAINDER;
+        maxSimulationTime = new JLabel("-");
+        add(maxSimulationTime, c2);
+
+        showSimulationTimeHistogram = new JButton("Show simulation time stats");
+        add(showSimulationTimeHistogram, c2);
+        showSimulationTimeHistogram.setEnabled(false);
+        showSimulationTimeHistogram.addActionListener(this);
+
+
+    }
+
+    public void actionPerformed(ActionEvent ae) {
+        if (ae.getSource() == runSimulations) {
+            runSimulations();
+        } else if (ae.getSource() == showSimulationTimeHistogram) {
+            showTimeHistogram();
+        }
+    }
+
+    private void showTimeHistogram() {
+        TraceManager.addDev("Show time histogram");
+        JPanel panel = new JPanel(new BorderLayout());
+
+        /*XYSeries series = new XYSeries("XYGraph");
+        series.add(1, 1);
+        series.add(1, 2);
+        series.add(2, 1);
+        series.add(3, 9);
+        series.add(4, 10);
+
+// Add the series to your data set
+        XYSeriesCollection dataset = new XYSeriesCollection();
+        dataset.addSeries(series);
+
+// Generate the graph
+        JFreeChart chart = ChartFactory.createXYLineChart(
+                "XY Chart", // Title
+                "x-axis", // x-axis Label
+                "y-axis", // y-axis Label
+                dataset, // Dataset
+                PlotOrientation.VERTICAL, // Plot Orientation
+                true, // Show Legend
+                true, // Use tooltips
+                false // Configure chart to generate URLs?
+        );*/
+
+        HistogramDataset dataset = new HistogramDataset();
+        double []values = sr.getSimulationTimes();
+        dataset.addSeries("key", values, 20);
+
+        JFreeChart histogram = ChartFactory.createHistogram("Histogram: Simulation times",
+                "Simulation times", "Frequency", dataset);
+
+        ChartPanel myChart = new ChartPanel(histogram);
+        myChart.setMouseWheelEnabled(true);
+        panel.add(myChart,BorderLayout.CENTER);
+        panel.validate();
+        JFrame frame = new JFrame();
+        frame.setTitle("Simulation times");
+        frame.setSize(500, 500);
+        frame.setContentPane(panel);
+        frame.setVisible(true);
+        TraceManager.addDev("Frame is now visible");
+    }
+
+
+    private void runSimulations() {
+        if (mgui.gtm.getAvatarSpecification() == null) {
+            return;
+        }
+
+        int nbOfsimulations;
+
+        try {
+            nbOfsimulations = new Integer(nbOfSimulationsText.getText()).intValue();
+        } catch (Exception e) {
+            return;
+        }
+
+        if (nbOfsimulations < 1) {
+            return;
+        }
+
+        runSimulations.setEnabled(false);
+        sr = new AvatarSimulationRunner(mgui.gtm.getAvatarSpecification());
+
+        totalNbOfSimulations = nbOfsimulations;
+        totalSimulations.setText(""+nbOfsimulations);
+
+        Thread simuExecutor = new Thread(() -> sr.runXSimulation(nbOfsimulations, this));
+        simuExecutor.start();
+
+
+
+    }
+
+    public void printStats() {
+        long minSimTime = sr.getMinSimulationTime();
+        minSimulationTime.setText(""+minSimTime);
+
+        double averageSimTime = sr.getAverageSimulationTime();
+        averageSimulationTime.setText(""+averageSimTime);
+
+        long maxSimTime = sr.getMaxSimulationTime();
+        maxSimulationTime.setText(""+maxSimTime);
+
+        showSimulationTimeHistogram.setEnabled(true);
+    }
+
+
+    @Override
+    public void setSimulationDone(int nb) {
+        simulationsDone.setText(""+(nb+1));
+        if (nb >= (totalNbOfSimulations-1)) {
+            runSimulations.setEnabled(true);
+            printStats();
+        }
+    }
+}
diff --git a/src/main/java/ui/avatarinteractivesimulation/JFrameAvatarInteractiveSimulation.java b/src/main/java/ui/avatarinteractivesimulation/JFrameAvatarInteractiveSimulation.java
index 060fd547cd80d8c57ae55b58676278637bffd57c..458dc6cd7a5a190cd593a3a0646c2499ebbb2aec 100755
--- a/src/main/java/ui/avatarinteractivesimulation/JFrameAvatarInteractiveSimulation.java
+++ b/src/main/java/ui/avatarinteractivesimulation/JFrameAvatarInteractiveSimulation.java
@@ -542,6 +542,10 @@ public class JFrameAvatarInteractiveSimulation extends JFrame implements AvatarS
 
         jp01.add(jp02, BorderLayout.CENTER);
 
+        AvatarSimulationStatisticsPanel assp = new AvatarSimulationStatisticsPanel(mgui);
+        commandTab.addTab("Statistics", null, assp, "Run x simulations and perform statistics");
+
+
         // Benchmark commands
         /*jp01 = new JPanel(new BorderLayout());
 
@@ -1287,6 +1291,7 @@ public class JFrameAvatarInteractiveSimulation extends JFrame implements AvatarS
         actions[AvatarInteractiveSimulationActions.ACT_SAVE_SD_PNG].setEnabled(b);
         actions[AvatarInteractiveSimulationActions.ACT_SAVE_SVG].setEnabled(b);
         actions[AvatarInteractiveSimulationActions.ACT_SAVE_TXT].setEnabled(b);
+        actions[AvatarInteractiveSimulationActions.ACT_SAVE_CSV].setEnabled(b);
         actions[AvatarInteractiveSimulationActions.ACT_PRINT_BENCHMARK].setEnabled(b);
         actions[AvatarInteractiveSimulationActions.ACT_SAVE_BENCHMARK].setEnabled(b);
         actions[AvatarInteractiveSimulationActions.ACT_ZOOM_IN].setEnabled(b);
@@ -1842,6 +1847,67 @@ public class JFrameAvatarInteractiveSimulation extends JFrame implements AvatarS
         //ass.printExecutedTransactions();
     }
 
+    public void actSaveCSV() {
+        TraceManager.addDev("Saving in CSV format");
+        String fileName = saveFileName.getText().trim();
+
+        if (fileName.length() == 0) {
+            fileName += "simulationtrace_fromttool.csv";
+        }
+
+        if (ConfigurationTTool.isConfigured(ConfigurationTTool.IMGPath)) {
+            fileName = ConfigurationTTool.IMGPath + System.getProperty("file.separator") + fileName;
+        } else {
+            // Using model directory
+            String path = mgui.getModelFileFullPath();
+            fileName = path.substring(0, path.lastIndexOf(File.separator) + 1) + fileName;
+            TraceManager.addDev("New Filename = " + fileName);
+        }
+
+
+        boolean ok = true;
+
+        try {
+            ok = FileUtils.checkFileForSave(new File(fileName));
+        } catch (Exception e) {
+            TraceManager.addDev("Exception=" + e.getMessage());
+            ok = false;
+        }
+
+        if (!ok) {
+            JOptionPane.showMessageDialog(this,
+                    "The capture could not be performed: the file name or path is not valid",
+                    "Error",
+                    JOptionPane.INFORMATION_MESSAGE);
+            return;
+        }
+
+
+        try {
+            FileUtils.saveFile(fileName, ass.toCSV());
+
+        } catch (Exception e) {
+            JOptionPane.showMessageDialog(this,
+                    "The simulation trace in text format could not be saved: " + e.getMessage(),
+                    "Error",
+                    JOptionPane.INFORMATION_MESSAGE);
+            return;
+        }
+
+        /*JOptionPane.showMessageDialog(this,
+                "Simulation trace was saved in " + fileName,
+                "Error",
+                JOptionPane.INFORMATION_MESSAGE);*/
+
+        String shortFileName;
+        File f = new File(fileName);
+        shortFileName = f.getName();
+        SimulationTrace st = new SimulationTrace(shortFileName, SimulationTrace.TXT_AVATAR, fileName);
+        mgui.addSimulationTrace(st);
+
+        //ass.printExecutedTransactions();
+    }
+
 
     public void actSaveSvg() {
         TraceManager.addDev("Saving in svg format");
@@ -2119,6 +2185,10 @@ public class JFrameAvatarInteractiveSimulation extends JFrame implements AvatarS
             actSaveTxt();
             return;
 
+        } else if (command.equals(actions[AvatarInteractiveSimulationActions.ACT_SAVE_CSV].getActionCommand())) {
+            actSaveCSV();
+            return;
+
         } else if (command.equals(actions[AvatarInteractiveSimulationActions.ACT_SAVE_SD_PNG].getActionCommand())) {
             actSaveSDPNG();
             return;
diff --git a/src/main/java/ui/util/IconManager.java b/src/main/java/ui/util/IconManager.java
index 6675fdbff283e35db60e15788d2169a6aab52752..68b8a5bdf74286beab79d4535fd70b514f6c9bdd 100755
--- a/src/main/java/ui/util/IconManager.java
+++ b/src/main/java/ui/util/IconManager.java
@@ -136,7 +136,7 @@ public class IconManager {
     public static ImageIcon imgic1300, imgic1302, imgic1304, imgic1306, imgic1308;
     public static ImageIcon imgic1310, imgic1312, imgic1314, imgic1316, imgic1318;
     public static ImageIcon imgic1320, imgic1322, imgic1324, imgic1326, imgic1328;
-    public static ImageIcon imgic1330, imgic1332;
+    public static ImageIcon imgic1330, imgic1332, imgic1334;
 
 
     // SMD diagram
@@ -572,6 +572,7 @@ public class IconManager {
     private static String icon1328 = "savesvg24.gif";
     private static String icon1330 = "stepforwardx24.gif";
     private static String icon1332 = "savexml24.gif";
+    private static String icon1334 = "savecsv24.gif";
 
     // SMD diagrams
     private static String icon2000 = "prosmdsendmsg.gif";
@@ -1108,6 +1109,7 @@ public class IconManager {
         imgic1328 = getIcon(icon1328);
         imgic1330 = getIcon(icon1330);
         imgic1332 = getIcon(icon1332);
+        imgic1334 = getIcon(icon1334);
 
         imgic2000 = getIcon(icon2000);
         imgic2002 = getIcon(icon2002);
diff --git a/src/main/resources/ui/util/savecsv24.gif b/src/main/resources/ui/util/savecsv24.gif
new file mode 100644
index 0000000000000000000000000000000000000000..eb025b9264d643a37b4f71248e1e528a94c645a6
Binary files /dev/null and b/src/main/resources/ui/util/savecsv24.gif differ
diff --git a/ttool-cli/ttool-cli.iml b/ttool-cli/ttool-cli.iml
index 9f33527513989b508cf5b042246ea37a9e28df99..a3dbeaba4633013bf288bd3693a6abc62b37c923 100644
--- a/ttool-cli/ttool-cli.iml
+++ b/ttool-cli/ttool-cli.iml
@@ -12,5 +12,6 @@
     <orderEntry type="module" module-name="shared" />
     <orderEntry type="library" name="Gradle: json-java" level="project" />
     <orderEntry type="library" name="libs" level="project" />
+    <orderEntry type="library" name="jfreechart-1.6.0" level="project" />
   </component>
 </module>
\ No newline at end of file
diff --git a/ttool/build.gradle b/ttool/build.gradle
index ec9c987a0cd69501ea1105a70e7c0b5a4fa7e197..9884471a976d8866a9adc59adff9d201ed5883c7 100644
--- a/ttool/build.gradle
+++ b/ttool/build.gradle
@@ -52,6 +52,7 @@ dependencies {
     compile name: 'jgrapht-ext-1.3.0'
     compile name: 'jgrapht-io-1.3.0'
     compile name: 'jgraphx-3.4.1.3'
+    compile name: 'jfreechart-1.6.0'
 
 
     // Use JUnit test framework
diff --git a/ttool/src/main/ttool.iml b/ttool/src/main/ttool.iml
index 20494ba032313760324154edee0713b4b7b0c3c4..251a16403910e1bcc980f539886e9d952bb4ec6c 100644
--- a/ttool/src/main/ttool.iml
+++ b/ttool/src/main/ttool.iml
@@ -34,5 +34,6 @@
     </orderEntry>
     <orderEntry type="library" name="Gradle: json-java" level="project" />
     <orderEntry type="library" name="libs" level="project" />
+    <orderEntry type="library" name="jfreechart-1.6.0" level="project" />
   </component>
 </module>
\ No newline at end of file
diff --git a/ttool/ttool.txt b/ttool/ttool.txt
index 9582490f79cee1c66410a17aeabd7ae22e5af437..8950236ff453ae83fe7ce2edec6c8dc215e42f11 100755
--- a/ttool/ttool.txt
+++ b/ttool/ttool.txt
@@ -1,2 +1,2 @@
 Main-Class: Main
-Class-Path:  ./opencloud.jar ./JavaPlot.jar ./derbynet.jar ./commons-math3-3.6.1.jar ./jsoup-1.8.1.jar ./commons-codec-1.10.jar ./gs-core-2.0.jar ./gs-core-2.0.jar ./gs-ui-swing-2.0.jar ./commons-io-2.5.jar ./batik-codec.jar ./batik-constants.jar ./batik-xml.jar ./batik-ext.jar ./batik-extensions.jar  ./batik-util.jar ./batik-svggen.jar ./batik-dom.jar ./batik-awt-util.jar xml-apis.jar  ./jautomata-core.jar ./com.microsoft.z3.jar ./jgrapht-core-1.3.0.jar ./jgrapht-ext-1.3.0.jar ./jgrapht-io-1.3.0.jar ./jgraphx-3.4.1.3.jar  ./json-java.jar
+Class-Path:  ./opencloud.jar ./JavaPlot.jar ./derbynet.jar ./commons-math3-3.6.1.jar ./jsoup-1.8.1.jar ./commons-codec-1.10.jar ./gs-core-2.0.jar ./gs-core-2.0.jar ./gs-ui-swing-2.0.jar ./commons-io-2.5.jar ./batik-codec.jar ./batik-constants.jar ./batik-xml.jar ./batik-ext.jar ./batik-extensions.jar  ./batik-util.jar ./batik-svggen.jar ./batik-dom.jar ./batik-awt-util.jar xml-apis.jar  ./jautomata-core.jar ./com.microsoft.z3.jar ./jgrapht-core-1.3.0.jar ./jgrapht-ext-1.3.0.jar ./jgrapht-io-1.3.0.jar ./jgraphx-3.4.1.3.jar  ./json-java.jar ./jfreechart-1.6.0.jar