diff --git a/build.txt b/build.txt
index 4860db97cf1aef7979d88eb319db17334e72e626..ba09e3960b9a4c98b981e3748e5e1b6a8041a6cb 100644
--- a/build.txt
+++ b/build.txt
@@ -1 +1 @@
-12959
\ No newline at end of file
+12962
\ No newline at end of file
diff --git a/libs/com.microsoft.z3.jar b/libs/com.microsoft.z3.jar
new file mode 100644
index 0000000000000000000000000000000000000000..0ee9d9054f7d2a6310bb2fafc87a24ff0442463e
Binary files /dev/null and b/libs/com.microsoft.z3.jar differ
diff --git a/rundse/build.gradle b/rundse/build.gradle
index 49bc159bc6d02c39b3556520f355c6edbd989e84..ed941fa63fb3b40cd263453fbfa77c617034ecf1 100644
--- a/rundse/build.gradle
+++ b/rundse/build.gradle
@@ -24,6 +24,7 @@ dependencies {
     compileOnly name:'batik-dom'
     compileOnly name:'batik-util'
     compile name:'jautomata-core'
+    compile name:'com.microsoft.z3'
 }
 
 jar {
diff --git a/rundse/manifest.txt b/rundse/manifest.txt
index 18e66503cd6d4de0cbbbfb608a66e099d2efef45..7ae7016992ad1704b32de0b058f74780cc53c74a 100755
--- a/rundse/manifest.txt
+++ b/rundse/manifest.txt
@@ -1 +1,2 @@
 Main-Class: RunDSE
+Class-Path: com.microsoft.z3.jar
diff --git a/src/main/java/tmltranslator/dsez3engine/InputInstance.java b/src/main/java/tmltranslator/dsez3engine/InputInstance.java
new file mode 100644
index 0000000000000000000000000000000000000000..d9e5183d5b9217ecda60d9c5a592c3a909aab9f8
--- /dev/null
+++ b/src/main/java/tmltranslator/dsez3engine/InputInstance.java
@@ -0,0 +1,123 @@
+package tmltranslator.dsez3engine;
+
+import tmltranslator.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class InputInstance {
+
+    private TMLArchitecture architecture;
+    private TMLModeling modeling;
+
+    public InputInstance(TMLArchitecture architecture, TMLModeling modeling) {
+        this.architecture = architecture;
+        this.modeling = modeling;
+    }
+
+    //get the list of eligible CPUs for a given task
+    public List<HwExecutionNode> getFeasibleCPUs(TMLTask tmlTask) {
+
+        List<HwExecutionNode> feasibleCPUs = new ArrayList<>();
+
+        for (HwNode hwNode : architecture.getHwNodes()) {
+            if (hwNode instanceof HwExecutionNode) {
+
+                for (String operationType : ((HwExecutionNode) hwNode).getOperationTypes()) {
+                    if (operationType.equals(tmlTask.getOperation())) {
+                        feasibleCPUs.add((HwExecutionNode) hwNode);
+                        break;
+                    }
+                }
+            }
+
+        }
+        return feasibleCPUs;
+    }
+
+    // TODO the location of the implemented methods (better in TMLTask).
+    public int getBufferIn(TMLTask tmlTask) {
+
+        int bin = 0;
+        for (TMLChannel tmlReadChannel : tmlTask.getReadTMLChannels()) { // TODO replace with getReadChannels() once finished integration
+            bin = bin + tmlReadChannel.getNumberOfSamples();
+        }
+
+        return bin;
+    }
+
+    public int getBufferOut(TMLTask tmlTask) {
+        int bout = 0;
+        for (TMLChannel tmlWriteChannel : tmlTask.getWriteTMLChannels()) {
+            bout = bout + tmlWriteChannel.getNumberOfSamples();
+        }
+        return bout;
+    }
+
+    public int getWCET(TMLTask tmlTask, HwExecutionNode hwExecutionNode) {
+        return (tmlTask.getWorstCaseIComplexity() * hwExecutionNode.getExeciTime());
+    }
+
+    //should work for cases where each processing unit is equipped with a unique local memory connected directly through a bus
+    public HwMemory getLocalMemoryOfHwExecutionNode(HwNode hwNode) {
+
+        List<HwLink> firstLinks = new ArrayList<>();
+
+        for (int i = 0; i < architecture.getLinkByHwNode(hwNode).size(); i++) {
+            firstLinks.add(architecture.getLinkByHwNode(hwNode).get(i));
+        }
+
+
+        HwMemory tempMem = new HwMemory("");
+
+        if ((!firstLinks.isEmpty())) {
+            List<HwLink> secondLinks = new ArrayList<>();
+
+            for (int i = 0; i < architecture.getLinkByBus(firstLinks.get(0).bus).size(); i++) {
+                secondLinks.add(architecture.getLinkByBus(firstLinks.get(0).bus).get(i)); // link 1 and 1 cpu side
+            }
+
+
+            for (HwLink secondlink : secondLinks) {
+                if (secondlink.hwnode instanceof HwMemory) {
+                    tempMem = (HwMemory) secondlink.hwnode;
+
+                }
+            }
+        }
+
+
+//TODO
+      /*  if(firstLinks.size() >= 1){
+            for(HwLink recursiveHwLink : firstLinks){
+
+            }
+
+        }*/
+
+        return tempMem;
+    }
+
+    //TODO this supposes that we have one single final task
+
+    public TMLTask getFinalTask(TMLModeling tmlm){
+        TMLTask finalTask = null;
+        for (Object tmlTask :  tmlm.getTasks()){
+            TMLTask taskCast = (TMLTask)tmlTask;
+            if (taskCast.getWriteTMLChannels().isEmpty())
+                finalTask = taskCast;
+        }
+
+        return finalTask;
+    }
+
+
+    public TMLArchitecture getArchitecture() {
+        return architecture;
+    }
+
+    public TMLModeling getModeling() {
+        return modeling;
+    }
+}
diff --git a/src/main/java/tmltranslator/dsez3engine/OptimizationModel.java b/src/main/java/tmltranslator/dsez3engine/OptimizationModel.java
new file mode 100644
index 0000000000000000000000000000000000000000..cb99bb9666c1da906f520f12ca465ca3890a7fac
--- /dev/null
+++ b/src/main/java/tmltranslator/dsez3engine/OptimizationModel.java
@@ -0,0 +1,752 @@
+package tmltranslator.dsez3engine;
+
+import com.microsoft.z3.*;
+import myutil.TraceManager;
+import tmltranslator.*;
+
+import javax.swing.*;
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
+
+
+public class OptimizationModel {
+
+    private Map<String, Integer> optimizedSolutionX = new HashMap<String, Integer>();
+    private Map<String, Integer> optimizedSolutionStart = new HashMap<String, Integer>();
+    private InputInstance inputInstance;
+
+    public OptimizationModel(InputInstance inputInstance) {
+
+        this.inputInstance = inputInstance;
+    }
+
+    public Map<String, Integer> getOptimizedSolutionX() {
+        return optimizedSolutionX;
+    }
+
+    public void setOptimizedSolutionX(Map<String, Integer> optimizedSolutionX) {
+        this.optimizedSolutionX = optimizedSolutionX;
+    }
+
+    public Map<String, Integer> getOptimizedSolutionStart() {
+        return optimizedSolutionStart;
+    }
+
+    public void setOptimizedSolutionStart(Map<String, Integer> optimizedSolutionStart) {
+        this.optimizedSolutionStart = optimizedSolutionStart;
+    }
+
+
+    public void findFeasibleMapping(Context ctx) throws TestFailedException {
+
+        TraceManager.addDev("\nFind feasible Mapping");
+
+        //Decision variables
+
+        //Definition of Xtp as a matrix. Each cell corresponds to a combination of a task and a processor.
+        IntExpr[][] X = new IntExpr[inputInstance.getModeling().getTasks().size()][inputInstance.getArchitecture().getCPUs().size()]; //getCPUs returns only HwCPU elements
+
+        //TODO paths
+
+        //Definition of Ycw as a matrix. Each cell corresponds to a combination of a channel and a path.
+        //  IntExpr[][] Y = new IntExpr[inputInstance.getModeling().getChannels().size()][tmlcpSequenceDiagrams.size()];
+
+        //Definition of start time variable for each task
+        IntExpr[] start = new IntExpr[inputInstance.getModeling().getTasks().size()];
+
+
+        //Mapping Constraints :
+        BoolExpr mapping_constraints = ctx.mkTrue();
+
+        //Matrix of constraints to define the interval of Xtp : 0 <= Xtp <= 1
+        BoolExpr[][] c_bound_x = new BoolExpr[inputInstance.getModeling().getTasks().size()][inputInstance.getArchitecture().getCPUs().size()];
+
+        //TraceManager.addDev("\nDefining the bounds of Xtp (1)");
+
+        for (Object tmlTask : inputInstance.getModeling().getTasks()) {
+
+            int t = inputInstance.getModeling().getTasks().indexOf(tmlTask);
+            TMLTask taskCast = (TMLTask)tmlTask;
+
+            for (HwNode hwNode : inputInstance.getArchitecture().getCPUs()) {
+
+                int p = inputInstance.getArchitecture().getCPUs().indexOf(hwNode);
+
+                X[t][p] = ctx.mkIntConst("X_" + taskCast.getID() + "_" + hwNode.getID());
+
+                // Constraints: 0 <= Xtp <= 1
+                c_bound_x[t][p] = ctx.mkAnd(ctx.mkLe(ctx.mkInt(0), X[t][p]),
+                        ctx.mkLe(X[t][p], ctx.mkInt(1)));
+
+                // TraceManager.addDev(c_bound_x[t][p]);
+            }
+        }
+
+        //Constraint on start >=0
+        BoolExpr[] c_bound_start = new BoolExpr[inputInstance.getModeling().getTasks().size()];
+
+        for (Object tmlTask :  inputInstance.getModeling().getTasks()) {
+            int t = inputInstance.getModeling().getTasks().indexOf(tmlTask);
+            TMLTask taskCast = (TMLTask)tmlTask;
+
+            start[t] = ctx.mkIntConst("start_" + taskCast.getID());
+            c_bound_start[t] = ctx.mkGe(start[t], ctx.mkInt(0));
+            mapping_constraints = ctx.mkAnd(mapping_constraints, c_bound_start[t]);
+        }
+
+        // TODO add the definition interval for Ycw
+
+        //CONSTRAINTS//
+        //Each task must be mapped to exactly 1 processing unit in its eligibility set:
+
+        // ∀t, SUM p (X tp) ≤ 1
+
+        //TraceManager.addDev("\nUnique task-CPU mapping constraints (3)");
+        BoolExpr[] c_unique_x = new BoolExpr[inputInstance.getModeling().getTasks().size()];
+        for (Object tmlTask :  inputInstance.getModeling().getTasks()) {
+            int t = inputInstance.getModeling().getTasks().indexOf(tmlTask);
+
+            ArithExpr sum_X = ctx.mkAdd(X[t]);
+            c_unique_x[t] = ctx.mkLe(sum_X, ctx.mkInt(1));
+            // TraceManager.addDev(c_unique_x[t]);
+
+        }
+
+
+        //Feasible Task map: ∀t, SUM p in F(t) (X tp) = 1
+        //TraceManager.addDev("\nFeasible task-CPU mapping constraints (4)");
+        BoolExpr[] c_feasibleMapX = new BoolExpr[inputInstance.getModeling().getTasks().size()];
+        for (Object tmlTask :  inputInstance.getModeling().getTasks()) {
+            int t = inputInstance.getModeling().getTasks().indexOf(tmlTask);
+            TMLTask taskCast = (TMLTask)tmlTask;
+            ArithExpr sum_X = ctx.mkInt(0);
+
+            for (HwNode hwNode : inputInstance.getFeasibleCPUs(taskCast)) {
+
+                int p = inputInstance.getArchitecture().getCPUs().indexOf(hwNode);
+
+                sum_X = ctx.mkAdd(sum_X, X[t][p]);
+            }
+            c_feasibleMapX[t] = ctx.mkEq(sum_X, ctx.mkInt(1));
+
+            //TraceManager.addDev(c_feasibleMapX[t]);
+
+        }
+
+        //Memory size constraint: ∀p, ∀t, X tp × (bin + bout ) ≤ mem
+
+        //TraceManager.addDev("\nMemory size constraints (5)");
+        BoolExpr[][] c_mem = new BoolExpr[inputInstance.getArchitecture().getNbOfCPU()][inputInstance.getModeling().getTasks().size()];
+
+        for (HwNode hwNode : inputInstance.getArchitecture().getCPUs()) {
+            int p = inputInstance.getArchitecture().getCPUs().indexOf(hwNode);
+
+            IntExpr mem = ctx.mkInt(inputInstance.getLocalMemoryOfHwExecutionNode(hwNode).memorySize);
+
+
+            for (Object tmlTask :  inputInstance.getModeling().getTasks()) {
+                int t = inputInstance.getModeling().getTasks().indexOf(tmlTask);
+                TMLTask taskCast = (TMLTask)tmlTask;
+
+                IntExpr bin_plus_bout = ctx.mkInt(inputInstance.getBufferIn(taskCast) + inputInstance.getBufferOut(taskCast));
+                ArithExpr bin_plus_bout_times_X = ctx.mkMul(bin_plus_bout, X[t][p]);
+
+                c_mem[p][t] = ctx.mkLe(bin_plus_bout_times_X, mem);
+
+                // TraceManager.addDev(c_mem[p][t]);
+
+            }
+        }
+
+/*
+        //At least one route Constraint: ∀c, (t1,t2) in c; X t1p1 + X t2p2 − r p1p2 ≤ 1
+        TraceManager.addDev("\nAt least one route constraints (6)");
+        BoolExpr[] c_route = new BoolExpr[inputInstance.getModeling().getChannels().size()];
+
+        IntExpr[][] r = new IntExpr[inputInstance.getArchitecture().getCPUs().size()][inputInstance.getArchitecture().getCPUs().size()];
+
+        for (TMLChannel channel : (List<TMLChannel>) inputInstance.getModeling().getChannels()) {
+
+            int c = inputInstance.getModeling().getChannels().indexOf(channel);
+            //for each channel get producer and consumer
+            TMLTask producer = channel.getOriginTask();
+            int prodIndex = inputInstance.getModeling().getTasks().indexOf(producer);
+
+            TMLTask consumer = channel.getDestinationTask();
+            int consIndex = inputInstance.getModeling().getTasks().indexOf(consumer);
+
+            for (HwNode source : inputInstance.getArchitecture().getCPUs()) {
+                int src = inputInstance.getArchitecture().getCPUs().indexOf(source);
+
+                for (HwNode destination : inputInstance.getArchitecture().getCPUs()) {
+                    int dst = inputInstance.getArchitecture().getCPUs().indexOf(destination);
+                    //for each couple of processors TODO calculate rp1p2
+                    r[src][dst] = ctx.mkInt(1);
+                    ArithExpr Xp_plus_Xc = ctx.mkAdd(X[prodIndex][src], X[consIndex][dst]);
+                    ArithExpr Xp_plus_Xc_minus_r = ctx.mkSub(Xp_plus_Xc, r[src][dst]);
+
+                    c_route[c] = ctx.mkLe(Xp_plus_Xc_minus_r, ctx.mkInt(1));
+
+                    TraceManager.addDev("Channel(" + channel.toString() + ") " + c_route[c]);
+
+
+                    // mapping_constraints = ctx.mkAnd(c_route[c], mapping_constraints);
+                }
+            }
+        }
+*/
+        //Scheduling: Precedence constraints: ∀c, τs (t cons ) ≥ τe (t prod )
+        // TraceManager.addDev("\nPrecedence constraints (11)");
+        BoolExpr[] c_precedence = new BoolExpr[inputInstance.getModeling().getChannels().size()];
+
+        for (Object channel : inputInstance.getModeling().getChannels()) {
+
+            int c = inputInstance.getModeling().getChannels().indexOf(channel);
+            TMLChannel channelCast = (TMLChannel) channel;
+
+            //for each channel get producer and consumer
+            TMLTask producer = channelCast.getOriginTask();
+            int prodIndex = inputInstance.getModeling().getTasks().indexOf(producer);
+
+            TMLTask consumer = channelCast.getDestinationTask();
+            int consIndex = inputInstance.getModeling().getTasks().indexOf(consumer);
+
+            ArithExpr wcetProducer = ctx.mkInt(0);
+
+            for (HwExecutionNode hwNode : inputInstance.getFeasibleCPUs(producer)) {
+                int p = inputInstance.getArchitecture().getCPUs().indexOf(hwNode);
+
+                wcetProducer = ctx.mkAdd(wcetProducer, ctx.mkMul(X[prodIndex][p], ctx.mkInt(inputInstance.getWCET(producer, hwNode))));
+
+            }
+
+            ArithExpr endProducer = ctx.mkAdd(start[prodIndex], wcetProducer);
+            ArithExpr startC_minus_endP = ctx.mkSub(start[consIndex], endProducer);
+
+            c_precedence[c] = ctx.mkGe(startC_minus_endP, ctx.mkInt(0));
+
+            //  TraceManager.addDev(c_precedence[c]);
+
+            mapping_constraints = ctx.mkAnd(mapping_constraints, c_precedence[c]);
+
+        }
+
+
+        //∀p∀t i ∀t j 6 = t i , ¬((X t i p = 1) ∧ (X t j p = 1)) ∨ ((τ s (t j ) ≥ τ e (t i )) ∨ (τ s (t i ) ≥ τ e (t j )))
+        //Scheduling: One single task running on CPU ∀t
+        //TraceManager.addDev("\n Same resource/no time overlap Constraints (12)");
+        BoolExpr c_monoTask[][][] = new BoolExpr[inputInstance.getArchitecture().getCPUs().size()][inputInstance.getModeling().getTasks().size()][inputInstance.getModeling().getTasks().size()];
+
+        for (HwNode hwNode : inputInstance.getArchitecture().getCPUs()) {
+            int p = inputInstance.getArchitecture().getCPUs().indexOf(hwNode);
+
+            for (Object taski :  inputInstance.getModeling().getTasks()) {
+
+                int ti = inputInstance.getModeling().getTasks().indexOf(taski);
+                TMLTask taskiCast = (TMLTask)taski;
+                //Calculate End times of ti
+                ArithExpr wceti = ctx.mkInt(0);
+
+                for (HwExecutionNode ihwNode : inputInstance.getFeasibleCPUs(taskiCast)) {
+                    int ip = inputInstance.getArchitecture().getCPUs().indexOf(ihwNode);
+
+                    wceti = ctx.mkAdd(wceti, ctx.mkMul(X[ti][ip], ctx.mkInt(inputInstance.getWCET(taskiCast, ihwNode))));
+
+                }
+
+                ArithExpr endti = ctx.mkAdd(start[ti], wceti);
+
+                for (Object taskj : inputInstance.getModeling().getTasks()) {
+
+                    int tj = inputInstance.getModeling().getTasks().indexOf(taskj);
+                    TMLTask taskjCast = (TMLTask)taskj;
+
+
+                    if (tj != ti) {
+                        //Calculate End times of tj
+
+                        ArithExpr wcetj = ctx.mkInt(0);
+
+                        for (HwExecutionNode jhwNode : inputInstance.getFeasibleCPUs(taskjCast)) {
+                            int jp = inputInstance.getArchitecture().getCPUs().indexOf(jhwNode);
+
+                            wcetj = ctx.mkAdd(wcetj, ctx.mkMul(X[tj][jp], ctx.mkInt(inputInstance.getWCET(taskjCast, jhwNode))));
+
+
+                        }
+
+                        ArithExpr endtj = ctx.mkAdd(start[tj], wcetj);
+
+                        BoolExpr alpha = ctx.mkAnd(ctx.mkEq(X[ti][p], ctx.mkInt(1)), ctx.mkEq(X[tj][p], ctx.mkInt(1)));
+
+                        BoolExpr not_alpha = ctx.mkNot(alpha);
+
+                        BoolExpr beta = ctx.mkOr(ctx.mkGe(start[ti], endtj), ctx.mkGe(start[tj], endti));
+
+                        //
+                        c_monoTask[p][ti][tj] = ctx.mkOr(not_alpha, beta);
+                        // TraceManager.addDev("\n" + c_monoTask[p][ti][tj]);
+
+                        mapping_constraints = ctx.mkAnd(mapping_constraints, c_monoTask[p][ti][tj]);
+                    }
+                }
+
+            }
+
+        }
+
+
+        //Grouping remaining constraints of the model
+
+        // TraceManager.addDev("\nAll mapping constraints");
+        for (Object task :  inputInstance.getModeling().getTasks()) {
+
+            int t = inputInstance.getModeling().getTasks().indexOf(task);
+            TMLTask taskCast = (TMLTask)task;
+
+            for (HwNode hwNode : inputInstance.getArchitecture().getCPUs()) {
+                int p = inputInstance.getArchitecture().getCPUs().indexOf(hwNode);
+
+                mapping_constraints = ctx.mkAnd(c_bound_x[t][p], mapping_constraints);
+                mapping_constraints = ctx.mkAnd(c_mem[p][t], mapping_constraints);
+
+            }
+
+            // Constraint: feasible unique mapping of tasks
+            mapping_constraints = ctx.mkAnd(c_unique_x[t], mapping_constraints);
+            mapping_constraints = ctx.mkAnd(c_feasibleMapX[t], mapping_constraints);
+
+        }
+
+        //Creating a solver instance
+        Solver s = ctx.mkSolver();
+        s.add(mapping_constraints);
+
+
+        if (s.check() == Status.SATISFIABLE) {
+            Model m = s.getModel();
+            Expr[][] optimized_result_X = new Expr[inputInstance.getModeling().getTasks().size()][inputInstance.getArchitecture().getCPUs().size()];
+            Expr[] optimized_result_start = new Expr[inputInstance.getModeling().getTasks().size()];
+
+            TraceManager.addDev("Proposed feasible Mapping solution:");
+
+
+            for (Object task : inputInstance.getModeling().getTasks()) {
+                int t = inputInstance.getModeling().getTasks().indexOf(task);
+                TMLTask taskCast = (TMLTask)task;
+
+                for (HwNode hwNode : inputInstance.getArchitecture().getCPUs()) {
+                    int p = inputInstance.getArchitecture().getCPUs().indexOf(hwNode);
+
+
+                    optimized_result_X[t][p] = m.evaluate(X[t][p], false);
+                    TraceManager.addDev("X[" + taskCast.getName() + "][" + hwNode.getName() + "] = " + optimized_result_X[t][p]);
+
+                }
+
+                TraceManager.addDev("\n");
+            }
+
+            for (Object task : inputInstance.getModeling().getTasks()) {
+                int t = inputInstance.getModeling().getTasks().indexOf(task);
+                TMLTask taskCast = (TMLTask)task;
+                optimized_result_start[t] = m.evaluate(start[t], false);
+                TraceManager.addDev("start[" + taskCast.getName() + "] = " + optimized_result_start[t]);
+
+            }
+
+
+        } else {
+            TraceManager.addDev("Failed to solve mapping problem");
+            throw new TestFailedException();
+        }
+
+
+    }//findFeasibleMapping()
+
+
+    public void findOptimizedMapping(Context ctx) throws TestFailedException {
+
+        TraceManager.addDev("\nFind an optimized Mapping");
+
+        //Decision variables
+
+        //Definition of Xtp as a matrix. Each cell corresponds to a combination of a task and a processor.
+        IntExpr[][] X = new IntExpr[inputInstance.getModeling().getTasks().size()][inputInstance.getArchitecture().getCPUs().size()]; //getCPUs returns only HwCPU elements
+
+
+        //Definition of start time variable for each task
+        IntExpr[] start = new IntExpr[inputInstance.getModeling().getTasks().size()];
+
+
+        //Mapping Constraints :
+        BoolExpr mapping_constraints = ctx.mkTrue();
+
+        //Matrix of constraints to define the interval of Xtp : 0 <= Xtp <= 1
+        BoolExpr[][] c_bound_x = new BoolExpr[inputInstance.getModeling().getTasks().size()][inputInstance.getArchitecture().getCPUs().size()];
+
+        //TraceManager.addDev("\nDefining the bounds of Xtp (1)");
+
+        for (Object tmlTask :  inputInstance.getModeling().getTasks()) {
+
+            int t = inputInstance.getModeling().getTasks().indexOf(tmlTask);
+            TMLTask taskCast = (TMLTask)tmlTask;
+
+            for (HwNode hwNode : inputInstance.getArchitecture().getCPUs()) {
+
+                int p = inputInstance.getArchitecture().getCPUs().indexOf(hwNode);
+
+                X[t][p] = ctx.mkIntConst("X_" + taskCast.getID() + "_" + hwNode.getID());
+
+                // Constraints: 0 <= Xtp <= 1
+                c_bound_x[t][p] = ctx.mkAnd(ctx.mkLe(ctx.mkInt(0), X[t][p]),
+                        ctx.mkLe(X[t][p], ctx.mkInt(1)));
+
+                // TraceManager.addDev(c_bound_x[t][p]);
+            }
+        }
+
+        //Constraint on start >=0
+        BoolExpr[] c_bound_start = new BoolExpr[inputInstance.getModeling().getTasks().size()];
+
+        for (Object tmlTask :  inputInstance.getModeling().getTasks()) {
+            int t = inputInstance.getModeling().getTasks().indexOf(tmlTask);
+
+            TMLTask taskCast = (TMLTask)tmlTask;
+            start[t] = ctx.mkIntConst("start_" + taskCast.getID());
+            c_bound_start[t] = ctx.mkGe(start[t], ctx.mkInt(0));
+            mapping_constraints = ctx.mkAnd(mapping_constraints, c_bound_start[t]);
+        }
+
+
+        //CONSTRAINTS//
+        //Each task must be mapped to exactly 1 processing unit in its eligibility set:
+
+        // ∀t, SUM p (X tp) ≤ 1
+
+        //TraceManager.addDev("\nUnique task-CPU mapping constraints (3)");
+        BoolExpr[] c_unique_x = new BoolExpr[inputInstance.getModeling().getTasks().size()];
+        for (Object tmlTask :  inputInstance.getModeling().getTasks()) {
+            int t = inputInstance.getModeling().getTasks().indexOf(tmlTask); // TODO or use the local instance modeling
+
+            ArithExpr sum_X = ctx.mkAdd(X[t]);
+            c_unique_x[t] = ctx.mkLe(sum_X, ctx.mkInt(1));
+            // TraceManager.addDev(c_unique_x[t]);
+
+        }
+
+
+        //Feasible Task map: ∀t, SUM p in F(t) (X tp) = 1
+        //TraceManager.addDev("\nFeasible task-CPU mapping constraints (4)");
+        BoolExpr[] c_feasibleMapX = new BoolExpr[inputInstance.getModeling().getTasks().size()];
+        for (Object tmlTask :  inputInstance.getModeling().getTasks()) {
+            int t = inputInstance.getModeling().getTasks().indexOf(tmlTask);
+            ArithExpr sum_X = ctx.mkInt(0);
+
+            TMLTask taskCast = (TMLTask)tmlTask;
+
+            for (HwNode hwNode : inputInstance.getFeasibleCPUs(taskCast)) {
+
+                int p = inputInstance.getArchitecture().getCPUs().indexOf(hwNode);
+
+                sum_X = ctx.mkAdd(sum_X, X[t][p]);
+            }
+            c_feasibleMapX[t] = ctx.mkEq(sum_X, ctx.mkInt(1));
+
+            //TraceManager.addDev(c_feasibleMapX[t]);
+
+        }
+
+        //Memory size constraint: ∀p, ∀t, X tp × (bin + bout ) ≤ mem
+
+        //TraceManager.addDev("\nMemory size constraints (5)");
+        BoolExpr[][] c_mem = new BoolExpr[inputInstance.getArchitecture().getNbOfCPU()][inputInstance.getModeling().getTasks().size()];
+
+        for (HwNode hwNode : inputInstance.getArchitecture().getCPUs()) {
+            int p = inputInstance.getArchitecture().getCPUs().indexOf(hwNode);
+
+            IntExpr mem = ctx.mkInt(inputInstance.getLocalMemoryOfHwExecutionNode(hwNode).memorySize);
+
+
+            for (Object tmlTask : inputInstance.getModeling().getTasks()) {
+                int t = inputInstance.getModeling().getTasks().indexOf(tmlTask);
+
+                TMLTask taskCast = (TMLTask)tmlTask;
+
+                IntExpr bin_plus_bout = ctx.mkInt(inputInstance.getBufferIn(taskCast) + inputInstance.getBufferOut(taskCast));
+                ArithExpr bin_plus_bout_times_X = ctx.mkMul(bin_plus_bout, X[t][p]);
+
+                c_mem[p][t] = ctx.mkLe(bin_plus_bout_times_X, mem);
+
+                // TraceManager.addDev(c_mem[p][t]);
+
+            }
+        }
+
+/*
+        //At least one route Constraint: ∀c, (t1,t2) in c; X t1p1 + X t2p2 − r p1p2 ≤ 1
+        TraceManager.addDev("\nAt least one route constraints (6)");
+        BoolExpr[] c_route = new BoolExpr[inputInstance.getModeling().getChannels().size()];
+
+        IntExpr[][] r = new IntExpr[inputInstance.getArchitecture().getCPUs().size()][inputInstance.getArchitecture().getCPUs().size()];
+
+        for (TMLChannel channel : (List<TMLChannel>) inputInstance.getModeling().getChannels()) {
+
+            int c = inputInstance.getModeling().getChannels().indexOf(channel);
+            //for each channel get producer and consumer
+            TMLTask producer = channel.getOriginTask();
+            int prodIndex = inputInstance.getModeling().getTasks().indexOf(producer);
+
+            TMLTask consumer = channel.getDestinationTask();
+            int consIndex = inputInstance.getModeling().getTasks().indexOf(consumer);
+
+            for (HwNode source : inputInstance.getArchitecture().getCPUs()) {
+                int src = inputInstance.getArchitecture().getCPUs().indexOf(source);
+
+                for (HwNode destination : inputInstance.getArchitecture().getCPUs()) {
+                    int dst = inputInstance.getArchitecture().getCPUs().indexOf(destination);
+                    //for each couple of processors TODO calculate rp1p2
+                    r[src][dst] = ctx.mkInt(1);
+                    ArithExpr Xp_plus_Xc = ctx.mkAdd(X[prodIndex][src], X[consIndex][dst]);
+                    ArithExpr Xp_plus_Xc_minus_r = ctx.mkSub(Xp_plus_Xc, r[src][dst]);
+
+                    c_route[c] = ctx.mkLe(Xp_plus_Xc_minus_r, ctx.mkInt(1));
+
+                    TraceManager.addDev("Channel(" + channel.toString() + ") " + c_route[c]);
+
+
+                    // mapping_constraints = ctx.mkAnd(c_route[c], mapping_constraints);
+                }
+            }
+        }
+*/
+        //Scheduling: Precedence constraints: ∀c, τs (t cons ) ≥ τe (t prod )
+        // TraceManager.addDev("\nPrecedence constraints (11)");
+        BoolExpr[] c_precedence = new BoolExpr[inputInstance.getModeling().getChannels().size()];
+
+        for (Object channel :  inputInstance.getModeling().getChannels()) {
+
+            int c = inputInstance.getModeling().getChannels().indexOf(channel);
+            //for each channel get producer and consumer
+            TMLChannel channelCast = (TMLChannel)channel;
+            TMLTask producer = channelCast.getOriginTask();
+            int prodIndex = inputInstance.getModeling().getTasks().indexOf(producer);
+
+            TMLTask consumer = channelCast.getDestinationTask();
+            int consIndex = inputInstance.getModeling().getTasks().indexOf(consumer);
+
+            //TraceManager.addDev("\nChannel(" + producer.getId() + "," + consumer.getId() + ")");
+
+            ArithExpr wcetProducer = ctx.mkInt(0);
+
+            for (HwExecutionNode hwNode : inputInstance.getFeasibleCPUs(producer)) {
+                int p = inputInstance.getArchitecture().getCPUs().indexOf(hwNode);
+
+                wcetProducer = ctx.mkAdd(wcetProducer, ctx.mkMul(X[prodIndex][p], ctx.mkInt(inputInstance.getWCET(producer, hwNode))));
+
+            }
+
+            ArithExpr endProducer = ctx.mkAdd(start[prodIndex], wcetProducer);
+            ArithExpr startC_minus_endP = ctx.mkSub(start[consIndex], endProducer);
+
+            c_precedence[c] = ctx.mkGe(startC_minus_endP, ctx.mkInt(0));
+
+            //  TraceManager.addDev(c_precedence[c]);
+
+            mapping_constraints = ctx.mkAnd(mapping_constraints, c_precedence[c]);
+
+        }
+
+
+        //∀p∀t i ∀t j 6 = t i , ¬((X t i p = 1) ∧ (X t j p = 1)) ∨ ((τ s (t j ) ≥ τ e (t i )) ∨ (τ s (t i ) ≥ τ e (t j )))
+        //Scheduling: One single task running on CPU ∀t
+        //TraceManager.addDev("\n Same resource/no time overlap Constraints (12)");
+        BoolExpr c_monoTask[][][] = new BoolExpr[inputInstance.getArchitecture().getCPUs().size()][inputInstance.getModeling().getTasks().size()][inputInstance.getModeling().getTasks().size()];
+
+        for (HwNode hwNode : inputInstance.getArchitecture().getCPUs()) {
+            int p = inputInstance.getArchitecture().getCPUs().indexOf(hwNode);
+
+            for (Object taski :  inputInstance.getModeling().getTasks()) {
+
+                int ti = inputInstance.getModeling().getTasks().indexOf(taski);
+                //Calculate End times of ti
+                ArithExpr wceti = ctx.mkInt(0);
+
+                TMLTask taskiCast = (TMLTask)taski;
+
+                for (HwExecutionNode ihwNode : inputInstance.getFeasibleCPUs(taskiCast)) {
+                    int ip = inputInstance.getArchitecture().getCPUs().indexOf(ihwNode);
+
+                    wceti = ctx.mkAdd(wceti, ctx.mkMul(X[ti][ip], ctx.mkInt(inputInstance.getWCET(taskiCast, ihwNode))));
+
+                }
+
+                ArithExpr endti = ctx.mkAdd(start[ti], wceti);
+
+                for (Object taskj :  inputInstance.getModeling().getTasks()) {
+
+                    int tj = inputInstance.getModeling().getTasks().indexOf(taskj);
+
+
+                    if (tj != ti) {
+                        //Calculate End times of tj
+
+                        ArithExpr wcetj = ctx.mkInt(0);
+
+                        TMLTask taskjCast = (TMLTask)taskj;
+
+
+                        for (HwExecutionNode jhwNode : inputInstance.getFeasibleCPUs(taskjCast)) {
+                            int jp = inputInstance.getArchitecture().getCPUs().indexOf(jhwNode);
+
+                            wcetj = ctx.mkAdd(wcetj, ctx.mkMul(X[tj][jp], ctx.mkInt(inputInstance.getWCET(taskjCast, jhwNode))));
+
+
+                        }
+
+                        ArithExpr endtj = ctx.mkAdd(start[tj], wcetj);
+
+                        BoolExpr alpha = ctx.mkAnd(ctx.mkEq(X[ti][p], ctx.mkInt(1)), ctx.mkEq(X[tj][p], ctx.mkInt(1)));
+
+                        BoolExpr not_alpha = ctx.mkNot(alpha);
+
+                        BoolExpr beta = ctx.mkOr(ctx.mkGe(start[ti], endtj), ctx.mkGe(start[tj], endti));
+
+                        //
+                        c_monoTask[p][ti][tj] = ctx.mkOr(not_alpha, beta);
+                        // TraceManager.addDev("\n" + c_monoTask[p][ti][tj]);
+
+                        mapping_constraints = ctx.mkAnd(mapping_constraints, c_monoTask[p][ti][tj]);
+                    }
+                }
+
+            }
+
+        }
+
+
+        //Grouping remaining constraints of the model
+
+        // TraceManager.addDev("\nAll mapping constraints");
+        for (Object task : inputInstance.getModeling().getTasks()) {
+
+            int t = inputInstance.getModeling().getTasks().indexOf(task);
+
+            for (HwNode hwNode : inputInstance.getArchitecture().getCPUs()) {
+                int p = inputInstance.getArchitecture().getCPUs().indexOf(hwNode);
+
+                mapping_constraints = ctx.mkAnd(c_bound_x[t][p], mapping_constraints);
+                mapping_constraints = ctx.mkAnd(c_mem[p][t], mapping_constraints);
+
+            }
+
+            // Constraint: feasible unique mapping of tasks
+            mapping_constraints = ctx.mkAnd(c_unique_x[t], mapping_constraints);
+            mapping_constraints = ctx.mkAnd(c_feasibleMapX[t], mapping_constraints);
+
+        }
+
+        //OPTIMIZE CONTEXT
+
+        //Create an Optimize context
+        Optimize opt = ctx.mkOptimize();
+
+        //Assert a constraints into the optimize solver
+        opt.Add(mapping_constraints);
+
+
+        // Objective: minimize latency
+
+        //Creating an expression for latency
+
+        //Calculating end time of last task
+        TMLTask finalTask = inputInstance.getFinalTask(inputInstance.getModeling());
+        int finalTaskIndex = inputInstance.getModeling().getTasks().indexOf(inputInstance.getFinalTask(inputInstance.getModeling()));
+        ArithExpr wcet_last = ctx.mkInt(0);
+        int l = 0;
+        for (HwExecutionNode hwNode : inputInstance.getFeasibleCPUs(inputInstance.getFinalTask(inputInstance.getModeling()))) {
+            int p = inputInstance.getArchitecture().getCPUs().indexOf(hwNode);
+            wcet_last = ctx.mkAdd(wcet_last, ctx.mkMul(X[finalTaskIndex][p], ctx.mkInt(inputInstance.getWCET(finalTask, hwNode))));
+            l += 1;
+
+        }
+
+        ArithExpr end_last = ctx.mkAdd(start[finalTaskIndex], wcet_last);
+
+        ArithExpr latency = ctx.mkSub(end_last, ctx.mkInt(0));
+
+
+        // Add minimization objective.
+        Optimize.Handle objective_latency = opt.MkMinimize(latency);
+
+        String outputToDisplay;
+
+        if (opt.Check() == Status.SATISFIABLE) {
+            Model m = opt.getModel();
+            Expr[][] optimized_result_X = new Expr[inputInstance.getModeling().getTasks().size()][inputInstance.getArchitecture().getCPUs().size()];
+            Expr[] optimized_result_start = new Expr[inputInstance.getModeling().getTasks().size()];
+
+            outputToDisplay ="The optimal mapping solution is:\n\n";
+
+            for ( Object task : inputInstance.getModeling().getTasks()) {
+                int t = inputInstance.getModeling().getTasks().indexOf(task);
+
+                for (HwNode hwNode : inputInstance.getArchitecture().getCPUs()) {
+                    int p = inputInstance.getArchitecture().getCPUs().indexOf(hwNode);
+                    //evaluate optimal solution
+                    optimized_result_X[t][p] = m.evaluate(X[t][p], true);
+                    TMLTask taskCast = (TMLTask)task;
+                    optimizedSolutionX.put("X[" + taskCast.getName() + "][" + hwNode.getName() + "] = ", Integer.parseInt
+                            (optimized_result_X[t][p]
+                            .toString()));
+
+                   // TraceManager.addDev("X[" + task.getName() + "][" + hwNode.getName() + "] = " + optimized_result_X[t][p]);
+                }
+
+                TraceManager.addDev("\n");
+            }
+
+            for (Object task :  inputInstance.getModeling().getTasks()) {
+                int t = inputInstance.getModeling().getTasks().indexOf(task);
+
+                optimized_result_start[t] = m.evaluate(start[t], false);
+                TMLTask taskCast = (TMLTask)task;
+
+                optimizedSolutionStart.put("start[" + taskCast.getName() + "] = ", Integer.parseInt(optimized_result_start[t].toString()));
+
+               // TraceManager.addDev("start[" + task.getName() + "] = " + optimized_result_start[t]);
+
+            }
+
+            for(Map.Entry<String, Integer> entry : optimizedSolutionX.entrySet()) {
+                outputToDisplay = outputToDisplay + entry.getKey() + " = " + entry.getValue() + "\n";
+            }
+
+            outputToDisplay += "\n\n";
+
+            for(Map.Entry<String, Integer> entry : optimizedSolutionStart.entrySet()) {
+                outputToDisplay = outputToDisplay + entry.getKey() + " = " + entry.getValue() + "\n";
+            }
+
+            TraceManager.addDev(outputToDisplay);
+
+        } else {
+            outputToDisplay ="Failed to solve mapping problem";
+            TraceManager.addDev(outputToDisplay);
+            throw new TestFailedException();
+        }
+
+    }
+
+
+    class TestFailedException extends Exception {
+        public TestFailedException() {
+            super("Check FAILED");
+        }
+    }
+
+
+}
diff --git a/src/main/java/ui/ActionPerformer.java b/src/main/java/ui/ActionPerformer.java
index 18d5b9846f93578b73756508ff36bfa24be0aa96..28bb9705c00b458e1cc11704bc19044df6d05901 100644
--- a/src/main/java/ui/ActionPerformer.java
+++ b/src/main/java/ui/ActionPerformer.java
@@ -173,6 +173,10 @@ public class ActionPerformer {
             mgui.generateUPPAAL();
         } else if (command.equals(mgui.actions[TGUIAction.ACT_DSE].getActionCommand())) {
             mgui.dse();
+        } else if (command.equals(mgui.actions[TGUIAction.ACT_DSE_Z3].getActionCommand())) {
+            mgui.dseZ3();
+        } else if (command.equals(mgui.actions[TGUIAction.ACT_DSE].getActionCommand())) {
+            mgui.dse();
         } else if (command.equals(mgui.actions[TGUIAction.ACT_AVATAR_MODEL_CHECKER].getActionCommand())) {
             mgui.avatarModelChecker();
         } else if (command.equals(mgui.actions[TGUIAction.ACT_GEN_JAVA].getActionCommand())) {
diff --git a/src/main/java/ui/JToolBarMainTurtle.java b/src/main/java/ui/JToolBarMainTurtle.java
index c926eb9a104cebe3d3c88729ee8dae247eeed35a..69dc3d24ac599c7896ed37580b1ed5e2fe3076c3 100644
--- a/src/main/java/ui/JToolBarMainTurtle.java
+++ b/src/main/java/ui/JToolBarMainTurtle.java
@@ -64,7 +64,7 @@ public  class JToolBarMainTurtle extends JToolBar implements ActionListener
     JButton  avatarSimu, avatarFVUPPAAL, avatarFVProVerif, avatarFVStaticAnalysis, avatarCodeGeneration, avatarMC;
 
     // Other
-    JButton genrtlotos, genlotos, genuppaal, gendesign, dse;
+    JButton genrtlotos, genlotos, genuppaal, gendesign, dse, dseZ3;
     JButton checkcode, simulation, validation;
     JButton oneClickrtlotos, onclicklotos, gensystemc, simusystemc, gentml, genC, genjava, nc,externalSearch, internalSearch;
 
@@ -166,6 +166,11 @@ public  class JToolBarMainTurtle extends JToolBar implements ActionListener
         dse = add(mgui.actions[TGUIAction.ACT_DSE]);
         dse.addMouseListener(mgui.mouseHandler);
 
+        if (MainGUI.experimentalOn) {
+            dseZ3 = add(mgui.actions[TGUIAction.ACT_DSE_Z3]);
+            dseZ3.addMouseListener(mgui.mouseHandler);
+        }
+
         addSeparator();
 
         //if (MainGUI.experimentalOn) {
@@ -318,6 +323,7 @@ public  class JToolBarMainTurtle extends JToolBar implements ActionListener
 
         //TraceManager.addDev("Show avatar options with b = " + b);
         dse.setVisible(!b);
+        dseZ3.setVisible(!b);
 
         avatarSimu.setVisible(b);
         avatarFVUPPAAL.setVisible(b);
@@ -395,6 +401,7 @@ public  class JToolBarMainTurtle extends JToolBar implements ActionListener
         //TraceManager.addDev("Show diplodocus options with b = " + b);
 
         dse.setVisible(b);
+        dseZ3.setVisible(b);
         avatarSimu.setVisible(!b);
         avatarFVUPPAAL.setVisible(!b);
         avatarFVStaticAnalysis.setVisible(!b);
diff --git a/src/main/java/ui/MainGUI.java b/src/main/java/ui/MainGUI.java
index 3f9ff6ba8112d005283a48bfd7955fde4885a315..498d6b496192a7939a5422c30c1bbfd0320b3085 100644
--- a/src/main/java/ui/MainGUI.java
+++ b/src/main/java/ui/MainGUI.java
@@ -4793,6 +4793,15 @@ public class MainGUI implements ActionListener, WindowListener, KeyListener, Per
         dtree.toBeUpdated();
     }
 
+    public void dseZ3() {
+        TraceManager.addDev("Design space exploration with Z3");
+        /*JDialogDSE jdse = new JDialogDSE(frame, this, "Design Space Exploration", SpecConfigTTool.SystemCCodeDirectory, SpecConfigTTool.TMLCodeDirectory);
+        //   jdse.setSize(600,800);
+        GraphicLib.centerOnParent(jdse, 700, 800);
+        jdse.setVisible(true);
+        dtree.toBeUpdated();*/
+    }
+
     public void avatarStaticAnalysis() {
         TraceManager.addDev("Avatar static analysis invariants");
         JDialogInvariantAnalysis jgen = new JDialogInvariantAnalysis(frame, this, "Static analysis: invariants computation");
diff --git a/src/main/java/ui/ModeManager.java b/src/main/java/ui/ModeManager.java
index d771aec8268fe34be460b41fd63a79520aadd676..37712ad69d103a0ecdd2a500864568d96d4df278 100644
--- a/src/main/java/ui/ModeManager.java
+++ b/src/main/java/ui/ModeManager.java
@@ -144,6 +144,7 @@ public class ModeManager {
                 actions[TGUIAction.ACT_GEN_RTLOTOS].setEnabled(true);
                 actions[TGUIAction.ACT_GEN_LOTOS].setEnabled(true);
                 actions[TGUIAction.ACT_DSE].setEnabled(true);
+                actions[TGUIAction.ACT_DSE_Z3].setEnabled(true);
                 if (mgui.getCurrentTURTLEPanel() instanceof TMLComponentDesignPanel) {
                     actions[TGUIAction.ACT_GEN_UPPAAL].setEnabled(true);
                 } else {
@@ -228,6 +229,7 @@ public class ModeManager {
                 actions[TGUIAction.ACT_GEN_RTLOTOS].setEnabled(false);
                 actions[TGUIAction.ACT_GEN_LOTOS].setEnabled(false);
                 actions[TGUIAction.ACT_DSE].setEnabled(false);
+                actions[TGUIAction.ACT_DSE_Z3].setEnabled(false);
                 actions[TGUIAction.ACT_GEN_JAVA].setEnabled(false);
                 actions[TGUIAction.ACT_SIMU_JAVA].setEnabled(false);
                 actions[TGUIAction.ACT_GEN_DESIGN].setEnabled(false);
@@ -252,6 +254,7 @@ public class ModeManager {
                 actions[TGUIAction.ACT_GEN_RTLOTOS].setEnabled(false);
                 actions[TGUIAction.ACT_GEN_LOTOS].setEnabled(false);
                 actions[TGUIAction.ACT_DSE].setEnabled(false);
+                actions[TGUIAction.ACT_DSE_Z3].setEnabled(false);
                 actions[TGUIAction.ACT_CHECKCODE].setEnabled(false);
                 actions[TGUIAction.ACT_SIMULATION].setEnabled(false);
                 actions[TGUIAction.ACT_VALIDATION].setEnabled(false);
@@ -272,6 +275,7 @@ public class ModeManager {
                 actions[TGUIAction.ACT_GEN_RTLOTOS].setEnabled(false);
                 actions[TGUIAction.ACT_GEN_LOTOS].setEnabled(false);
                 actions[TGUIAction.ACT_DSE].setEnabled(false);
+                actions[TGUIAction.ACT_DSE_Z3].setEnabled(false);
                 actions[TGUIAction.ACT_GEN_JAVA].setEnabled(false);
                 actions[TGUIAction.ACT_SIMU_JAVA].setEnabled(false);
                 actions[TGUIAction.ACT_GEN_DESIGN].setEnabled(false);
diff --git a/src/main/java/ui/TGUIAction.java b/src/main/java/ui/TGUIAction.java
index 2b4bfd066bbf84e9c886fbb8562a7ecd1e3249a7..6defdce51bbd17189e592a6bfd472366d62dbde9 100644
--- a/src/main/java/ui/TGUIAction.java
+++ b/src/main/java/ui/TGUIAction.java
@@ -649,6 +649,7 @@ public class TGUIAction extends AbstractAction {
     public static final int ACT_AVATAR_EXECUTABLE_GENERATION = 340;
 
     public static final int ACT_DSE = 434;
+    public static final int ACT_DSE_Z3 = 516;
 
     // Ontologies
     public static final int ACT_GENERATE_ONTOLOGIES_CURRENT_DIAGRAM = 367;
@@ -667,7 +668,7 @@ public class TGUIAction extends AbstractAction {
     public static final int MOVE_ENABLED = 463;
     public static final int FIRST_DIAGRAM = 464;
     
-    public static final int NB_ACTION = 516;
+    public static final int NB_ACTION = 517;
 
     private static final TAction [] actions = new TAction[NB_ACTION];
 
@@ -866,7 +867,9 @@ public class TGUIAction extends AbstractAction {
         actions[ACT_VIEW_PM_AUT] = new TAction("viewpmaut-command", "Power Management Analysis (last AUT graph)", IconManager.imgic28, IconManager.imgic29, "Power Management Analysis (last AUT graph)",  "Power Management Analysis on the last generated reachability graph generated in AUT (Aldebaran) format", 0);
         actions[ACT_VIEW_PM_AUTPROJ] = new TAction("viewpmautproj-command", "Power Management Analysis (last minimized AUT graph)", IconManager.imgic28, IconManager.imgic29, "Power Management Analysis (last minimized AUT graph)",  "Power Management Analysis on the last minimized reachability graph  in AUT (Aldebaran) format", 0);
         actions[ACT_VIEW_PM_SAVED_AUT] = new TAction("viewpmsavedautproj-command", "Power Management Analysis (saved AUT graph)", IconManager.imgic28, IconManager.imgic29, "Power Management Analysis (saved AUT graph)",  "Power Management Analysis on a graph saved in AUT (Aldebaran) format", 0);
-        actions[ACT_DSE] = new TAction("auto-dse", "Automated Design Space Exploration", IconManager.imgic89, IconManager.imgic89, "Automated Design Space Exploration", "Find the optimal mapping and security additions automatically",0);
+        actions[ACT_DSE] = new TAction("auto-dse", "Automated Design Space Exploration", IconManager.imgic89, IconManager.imgic89, "Automated Design Space Exploration", "Find the optimal mapping with brute-force simulations",0);
+        actions[ACT_DSE_Z3] = new TAction("auto-dse-z3", "Automated Design Space Exploration with Z3", IconManager.imgic89_z3, IconManager.imgic89_z3, "Automated Design Space Exploration with Z3", "Find the optimal mapping with Z3",0);
+
         // AVATAR
         actions[ACT_AVATAR_SIM] = new TAction("avatar-simu", "Interactive simulation", IconManager.imgic18, IconManager.imgic18, "Interactive simulation",  "Interactive simulation of the AVATAR design under edition", '2');
         actions[ACT_AVATAR_FV_UPPAAL] = new TAction("avatar-formal-verification-uppaal", "Safety formal verification with UPPAAL (Safety)", IconManager.imgic86, IconManager.imgic86, "Formal verification with UPPAAL (Safety)",  "Formal verification with UPPAAL (Safety) of the AVATAR design under edition", '3');
diff --git a/src/main/java/ui/util/DefaultText.java b/src/main/java/ui/util/DefaultText.java
index ee0e4edb277de676582a85e5735491f3f244fa54..76862b2fd2cd74d4383e0ed308b66b6a36897168 100755
--- a/src/main/java/ui/util/DefaultText.java
+++ b/src/main/java/ui/util/DefaultText.java
@@ -50,8 +50,8 @@ package ui.util;
  */
 public class DefaultText {
 
-    public static String BUILD = "12958";
-    public static String DATE = "2019/02/23 03:02:12 CET";
+    public static String BUILD = "12961";
+    public static String DATE = "2019/02/26 03:02:13 CET";
 
     public static StringBuffer sbAbout = makeAbout();
 
diff --git a/src/main/java/ui/util/IconManager.java b/src/main/java/ui/util/IconManager.java
index d85639588433221e0c71ba60057ee2823edfe669..0a0a2f1a821671528a0f08908514f33f61c9e7bb 100755
--- a/src/main/java/ui/util/IconManager.java
+++ b/src/main/java/ui/util/IconManager.java
@@ -71,7 +71,7 @@ public class IconManager {
     public static ImageIcon imgic50, imgic51, imgic52, imgic53, imgic54, imgic55, imgic56, imgic57, imgic58, imgic59;
     public static ImageIcon imgic60, imgic61, imgic62, imgic63, imgic64, imgic65, imgic66, imgic68;
     public static ImageIcon imgic70, imgic71, imgic72, imgic73, imgic75, imgic76, imgic77, imgic78, imgic79, imgic780;
-    public static ImageIcon imgic80, imgic82, imgic84, imgic86, imgic88, imgic89;
+    public static ImageIcon imgic80, imgic82, imgic84, imgic86, imgic88, imgic89, imgic89_z3;
     public static ImageIcon imgic90, imgic92, imgic94, imgic96, imgic98, imgic99;
 
     public static ImageIcon imgic142;
@@ -295,6 +295,7 @@ public class IconManager {
     private static String icon86 = "avatarfvuppaal.png";
     private static String icon88 = "avatarfvproverif.png";
     private static String icon89 = "dse.png";
+    private static String icon89_z3 = "dse_z3.png";
     private static String icon90 = "genlotos.gif";
     private static String icon92 = "genuppaal.gif";
     private static String icon94 = "avatarcodegeneration.gif";
@@ -837,6 +838,7 @@ public class IconManager {
         imgic86 = getIcon(icon86);
         imgic88 = getIcon(icon88);
         imgic89 = getIcon(icon89);
+        imgic89_z3 = getIcon(icon89_z3);
         imgic90 = getIcon(icon90);
         imgic92 = getIcon(icon92);
         imgic94 = getIcon(icon94);
diff --git a/src/main/resources/ui/util/dse_z3.png b/src/main/resources/ui/util/dse_z3.png
new file mode 100644
index 0000000000000000000000000000000000000000..9a6a70af8532cb69785839876f2f5e114a1e6ea1
Binary files /dev/null and b/src/main/resources/ui/util/dse_z3.png differ
diff --git a/tmltranslator/build.gradle b/tmltranslator/build.gradle
index 4346731a9719460a767df3c62d32662784a8e812..e03e31b7e47fe6f4b00ca9c441ea77a20a66d77a 100644
--- a/tmltranslator/build.gradle
+++ b/tmltranslator/build.gradle
@@ -25,6 +25,7 @@ dependencies {
     compileOnly name:'batik-util'
     compile name: 'commons-math3-3.6.1'
     compile name: 'jautomata-core'
+    compile name: 'com.microsoft.z3'
 }
 
 jar {
diff --git a/tmltranslator/manifest.txt b/tmltranslator/manifest.txt
index 9c6dd6c3cc95d482fbb78a50590ce6ffd97da599..d0d5ac1d610e1fe17c8652d6d91e40dd1043071d 100755
--- a/tmltranslator/manifest.txt
+++ b/tmltranslator/manifest.txt
@@ -1 +1,2 @@
 Main-Class: TMLTranslator
+Class-Path: com.microsoft.z3.jar
diff --git a/ttool-cli/build.gradle b/ttool-cli/build.gradle
index 61e6870757c78d21c9a29378dfcaf30ec37f7806..74cce3de0d81798f340a9ac6c2a9f70b1d5c975f 100644
--- a/ttool-cli/build.gradle
+++ b/ttool-cli/build.gradle
@@ -33,6 +33,7 @@ dependencies {
     compile name: 'batik-dom'
     compile name: 'batik-awt-util'
     compile name: 'jautomata-core'
+    compile name: 'com.microsoft.z3'
 
     // Use JUnit test framework
     testCompile 'junit:junit:4.12'
diff --git a/ttool-cli/manifest.txt b/ttool-cli/manifest.txt
index cac8cac5cbd65fa321d0c6dc2a41fa415bb94f59..f71b884ab16c9a2e4c5597b71b45ab6d115fadd7 100755
--- a/ttool-cli/manifest.txt
+++ b/ttool-cli/manifest.txt
@@ -1,2 +1,2 @@
 Main-Class: TToolCLI
-Class-Path: 
+Class-Path: jsoup-1.8.1.jar commons-codec-1.10.jar gs-core-1.3.jar gs-ui-1.3.jar commons-io-2.5.jar commons-math3-3.6.1.jar batik-awt-util.jar batik-dom.jar batik-svggen.jar batik-util.jar batik-xml.jar jautomata-core.jar com.microsoft.z3.jar
diff --git a/ttool/META-INF/MANIFEST.MF b/ttool/META-INF/MANIFEST.MF
index 69ee18c82fcb07e48b000dd3570b52c519db03ad..c8d960fb4fde248bf284c6f813720ac087406387 100644
--- a/ttool/META-INF/MANIFEST.MF
+++ b/ttool/META-INF/MANIFEST.MF
@@ -1,4 +1,4 @@
 Manifest-Version: 1.0
-Class-Path: jsoup-1.8.1.jar commons-codec-1.10.jar gs-core-1.3.jar gs-ui-1.3.jar commons-io-2.5.jar commons-math3-3.6.1.jar batik-awt-util.jar batik-dom.jar batik-svggen.jar batik-util.jar batik-xml.jar jautomata-core.jar
+Class-Path: jsoup-1.8.1.jar commons-codec-1.10.jar gs-core-1.3.jar gs-ui-1.3.jar commons-io-2.5.jar commons-math3-3.6.1.jar batik-awt-util.jar batik-dom.jar batik-svggen.jar batik-util.jar batik-xml.jar jautomata-core.jar com.microsoft.z3.jar
 Main-Class: Main
 
diff --git a/ttool/build.gradle b/ttool/build.gradle
index da6aff06ccadf740793159657b6ef83a85f219df..a1346c22c42c058ae1695b081416d3febd83370d 100644
--- a/ttool/build.gradle
+++ b/ttool/build.gradle
@@ -33,6 +33,7 @@ dependencies {
     compile name: 'batik-dom'
     compile name: 'batik-awt-util'
     compile name: 'jautomata-core'
+    compile name: 'com.microsoft.z3'
     compile name: 'assertj/assertj-swing/3.8.0/assertj-swing-3.8.0'
     compile name: 'assertj/assertj-swing/3.8.0/assertj-swing-3.8.0-sources'
     compile name: 'assertj/assertj-swing-junit/3.8.0/assertj-swing-junit-3.8.0'
diff --git a/ttool/src/test/java/tmltranslator/dsez3engine/InputInstanceTest.java b/ttool/src/test/java/tmltranslator/dsez3engine/InputInstanceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..0dc2ccf6a8f6f58487fae6eaea92b02e0bc47b1f
--- /dev/null
+++ b/ttool/src/test/java/tmltranslator/dsez3engine/InputInstanceTest.java
@@ -0,0 +1,380 @@
+package tmltranslator.dsez3engine;
+
+import com.microsoft.z3.*;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import tmltranslator.*;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import myutil.TraceManager;
+
+import static org.junit.Assert.*;
+
+public class InputInstanceTest {
+
+    public TMLArchitecture tmla;
+    public TMLModeling tmlm;
+
+    public InputInstance inputInstance;
+
+    public OptimizationModel optimizationModel;
+
+    @Before
+    public void setUpTest() {
+
+        tmla = setUpTMLArchitecture();
+        tmlm = setUpTMLModeling();
+
+        inputInstance = new InputInstance(tmla, tmlm);
+
+        optimizationModel = new OptimizationModel(inputInstance);
+    }
+
+    private TMLModeling setUpTMLModeling() {
+
+        tmlm = new TMLModeling();
+
+
+        TMLTask taskA = new TMLTask("task__A", null, null);
+        TMLTask taskB = new TMLTask("task__B", null, null);
+        TMLTask taskD = new TMLTask("task__D", null, null);
+        TMLTask taskE = new TMLTask("task__E", null, null);
+
+        //filling activity diagrams of tasks
+
+        //taskA
+        TMLActivityElementWithAction firstA = new TMLExecI("execiA", null);
+        firstA.setAction("150");
+        taskA.getActivityDiagram().setFirst(firstA);
+
+        TMLActivityElement AwB = new TMLWriteChannel("AwB", null);
+        taskA.getActivityDiagram().addLinkElement(firstA, AwB);
+        taskA.getActivityDiagram().addElement(AwB);
+
+        TMLActivityElement AwD = new TMLWriteChannel("AwD", null);
+        taskA.getActivityDiagram().addLinkElement(AwB, AwD);
+        taskA.getActivityDiagram().addElement(AwD);
+
+        //taskB
+        TMLActivityElement firstB = new TMLReadChannel("BrA", null);
+        taskB.getActivityDiagram().setFirst(firstB);
+
+        TMLActivityElementWithAction execiB = new TMLExecI("execiB", null);
+        execiB.setAction("100");
+        taskB.getActivityDiagram().addLinkElement(firstB, execiB);
+        taskB.getActivityDiagram().addElement(execiB);
+
+        TMLActivityElement BwE = new TMLWriteChannel("BwE", null);
+        taskB.getActivityDiagram().addLinkElement(execiB, BwE);
+        taskB.getActivityDiagram().addElement(BwE);
+
+        //taskD
+        TMLActivityElement firstD = new TMLReadChannel("DrA", null);
+        taskD.getActivityDiagram().setFirst(firstD);
+
+        TMLActivityElementWithAction execiD = new TMLExecI("execiD", null);
+        execiD.setAction("100");
+        taskD.getActivityDiagram().addLinkElement(firstD, execiD);
+        taskD.getActivityDiagram().addElement(execiD);
+
+        TMLActivityElement DwE = new TMLWriteChannel("DwE", null);
+        taskD.getActivityDiagram().addLinkElement(execiD, DwE);
+        taskD.getActivityDiagram().addElement(DwE);
+
+        //taskE
+        TMLActivityElement firstE = new TMLReadChannel("ErB", null);
+        taskE.getActivityDiagram().setFirst(firstE);
+
+        TMLActivityElement ErD = new TMLReadChannel("ErD", null);
+        taskE.getActivityDiagram().addLinkElement(firstE, ErD);
+        taskE.getActivityDiagram().addElement(ErD);
+
+        TMLActivityElementWithAction execiE = new TMLExecI("execiE", null);
+        execiE.setAction("50");
+        taskE.getActivityDiagram().addLinkElement(ErD, execiE);
+        taskE.getActivityDiagram().addElement(execiE);
+
+
+        taskA.addOperation("generic");
+        taskB.addOperation("fft");
+        taskD.addOperation("fft");
+        taskE.addOperation("generic");
+
+        //creating channels
+        TMLChannel ab = new TMLChannel("ab", null);
+        TMLChannel ad = new TMLChannel("ad", null);
+        TMLChannel be = new TMLChannel("be", null);
+        TMLChannel de = new TMLChannel("de", null);
+
+        taskA.addWriteTMLChannel(ab);
+        taskA.addWriteTMLChannel(ad);
+
+        taskB.addReadTMLChannel(ab);
+        taskB.addWriteTMLChannel(be);
+
+        taskD.addReadTMLChannel(ad);
+        taskD.addWriteTMLChannel(de);
+
+        taskE.addReadTMLChannel(be);
+        taskE.addReadTMLChannel(de);
+
+        ab.setTasks(taskA, taskB);
+        ad.setTasks(taskA, taskD);
+        be.setTasks(taskB, taskE);
+        de.setTasks(taskD, taskE);
+
+        ab.setNumberOfSamples(2);
+        ad.setNumberOfSamples(2);
+        be.setNumberOfSamples(5);
+        de.setNumberOfSamples(5);
+
+        tmlm.addTask(taskA);
+        tmlm.addTask(taskB);
+        tmlm.addTask(taskD);
+        tmlm.addTask(taskE);
+
+        tmlm.addChannel(ab);
+        tmlm.addChannel(ad);
+        tmlm.addChannel(be);
+        tmlm.addChannel(de);
+
+
+        return tmlm;
+    }
+
+
+    private TMLArchitecture setUpTMLArchitecture() {
+
+        HwExecutionNode mainCPU = new HwCPU("MainCPU");
+        HwMemory mainMem = new HwMemory("mainMem");
+
+        HwExecutionNode dsp = new HwCPU("dsp");
+        HwMemory dspMem = new HwMemory("dspMem");
+
+        HwBus bus0 = new HwBus("bus0");
+        HwBus bus1 = new HwBus("bus1");
+
+
+        HwLink maincpu_bus0 = new HwLink("maincpu_bus0");
+        HwLink bus0_cpumem = new HwLink("bus0_cpumem");
+
+        HwLink dsp_bus1 = new HwLink("dsp_bus1");
+        HwLink bus1_dspmem = new HwLink("bus1_dspmem");
+
+        mainCPU.execiTime = 2;
+        dsp.execiTime = 1;
+
+
+        mainCPU.addOperationType("generic");
+        mainCPU.addOperationType("fft");
+
+        mainMem.memorySize = 200;
+
+        dsp.addOperationType("fft");
+        dspMem.memorySize = 100;
+
+        maincpu_bus0.hwnode = mainCPU;
+        maincpu_bus0.bus = bus0;
+
+        bus0_cpumem.bus = bus0;
+        bus0_cpumem.hwnode = mainMem;
+
+        dsp_bus1.hwnode = dsp;
+        dsp_bus1.bus = bus1;
+
+        bus1_dspmem.bus = bus1;
+        bus1_dspmem.hwnode = dspMem;
+
+
+        tmla = new TMLArchitecture();
+
+        tmla.addHwNode(mainCPU);
+        tmla.addHwNode(dsp);
+        tmla.addHwNode(mainMem);
+        tmla.addHwNode(dspMem);
+        tmla.addHwNode(bus0);
+        tmla.addHwNode(bus1);
+        tmla.addHwLink(maincpu_bus0);
+        tmla.addHwLink(bus0_cpumem);
+        tmla.addHwLink(dsp_bus1);
+        tmla.addHwLink(bus1_dspmem);
+
+        return tmla;
+    }
+
+    @Test
+    public void findOptimizedMapping() {
+
+        try {
+
+            // These examples need model generation turned on.
+            HashMap<String, String> cfg = new HashMap<String, String>();
+            cfg.put("model", "true");
+            Context ctx = new Context(cfg);
+
+
+            optimizationModel.findOptimizedMapping(ctx);
+
+            Log.close();
+            if (Log.isOpen())
+                TraceManager.addDev("Log is still open!");
+        } catch (Z3Exception ex) {
+            TraceManager.addDev("Z3 Managed Exception: " + ex.getMessage());
+            TraceManager.addDev("Stack trace: ");
+            ex.printStackTrace(
+                    System.out);
+        } catch (OptimizationModel.TestFailedException ex) {
+            TraceManager.addDev("TEST CASE FAILED: " + ex.getMessage());
+            TraceManager.addDev("Stack trace: ");
+            ex.printStackTrace(System.out);
+        } catch (Exception ex) {
+            TraceManager.addDev("Unknown Exception: " + ex.getMessage());
+            TraceManager.addDev("Stack trace: ");
+            ex.printStackTrace(System.out);
+        }
+
+        assertEquals(1, optimizationModel.getOptimizedSolutionX().get("X[task__A][MainCPU] = ").intValue());
+        assertEquals(0, optimizationModel.getOptimizedSolutionX().get("X[task__A][dsp] = ").intValue());
+        assertEquals(0, optimizationModel.getOptimizedSolutionX().get("X[task__B][MainCPU] = ").intValue());
+        assertEquals(1, optimizationModel.getOptimizedSolutionX().get("X[task__B][dsp] = ").intValue());
+        assertEquals(0, optimizationModel.getOptimizedSolutionX().get("X[task__D][MainCPU] = ").intValue());
+        assertEquals(1, optimizationModel.getOptimizedSolutionX().get("X[task__D][dsp] = ").intValue());
+        assertEquals(1, optimizationModel.getOptimizedSolutionX().get("X[task__E][MainCPU] = ").intValue());
+        assertEquals(0, optimizationModel.getOptimizedSolutionX().get("X[task__E][dsp] = ").intValue());
+
+        assertEquals(0, optimizationModel.getOptimizedSolutionStart().get("start[task__A] = ").intValue());
+        assertEquals(300, optimizationModel.getOptimizedSolutionStart().get("start[task__B] = ").intValue());
+        assertEquals(400, optimizationModel.getOptimizedSolutionStart().get("start[task__D] = ").intValue());
+        assertEquals(500, optimizationModel.getOptimizedSolutionStart().get("start[task__E] = ").intValue());
+
+    }
+
+
+    @Test
+    public void findFeasibleMapping() {
+
+        try {
+
+            // These examples need model generation turned on.
+            HashMap<String, String> cfg = new HashMap<String, String>();
+            cfg.put("model", "true");
+            Context ctx = new Context(cfg);
+
+
+            optimizationModel.findFeasibleMapping(ctx);
+
+            Log.close();
+            if (Log.isOpen())
+                TraceManager.addDev("Log is still open!");
+        } catch (Z3Exception ex) {
+            TraceManager.addDev("Z3 Managed Exception: " + ex.getMessage());
+            TraceManager.addDev("Stack trace: ");
+            ex.printStackTrace(
+                    System.out);
+        } catch (OptimizationModel.TestFailedException ex) {
+            TraceManager.addDev("TEST CASE FAILED: " + ex.getMessage());
+            TraceManager.addDev("Stack trace: ");
+            ex.printStackTrace(System.out);
+        } catch (Exception ex) {
+            TraceManager.addDev("Unknown Exception: " + ex.getMessage());
+            TraceManager.addDev("Stack trace: ");
+            ex.printStackTrace(System.out);
+        }
+
+
+    }
+
+
+    @Test
+    public void getFeasibleCPUs() {
+
+        Boolean test = false;
+        List <HwExecutionNode> expectedList = new ArrayList<>();
+        expectedList.add(inputInstance.getArchitecture().getHwCPUByName("MainCPU"));
+        expectedList.add(inputInstance.getArchitecture().getHwCPUByName("dsp"));
+
+        TMLTask tempTask = (TMLTask) inputInstance.getModeling().getTasks().get(2);
+
+
+        List<HwExecutionNode> actualList = new ArrayList<>();
+
+        for (int i = 0; i < inputInstance.getFeasibleCPUs(tempTask).size(); i++) {
+            actualList.add(inputInstance.getFeasibleCPUs(tempTask).get(i));
+        }
+
+        assertEquals(actualList.size(), expectedList.size());
+
+        for (HwExecutionNode hwExecutionNode : actualList){
+            assertTrue(expectedList.contains(hwExecutionNode));
+        }
+
+    }
+
+    @Test
+    public void getBufferIn() {
+
+        List<TMLTask> tempTasks = new ArrayList<>();
+        for (int i = 0; i < inputInstance.getModeling().getTasks().size(); i++) {
+            tempTasks.add((TMLTask) inputInstance.getModeling().getTasks().get(i));
+        }
+
+        assertEquals(inputInstance.getBufferIn((TMLTask) tempTasks.get(0)), 0);
+        assertEquals(inputInstance.getBufferIn((TMLTask) tempTasks.get(1)), 2);
+        assertEquals(inputInstance.getBufferIn((TMLTask) tempTasks.get(2)), 2);
+        assertEquals(inputInstance.getBufferIn((TMLTask) tempTasks.get(3)), 10);
+
+
+    }
+
+    @Test
+    public void getBufferOut() {
+        List<TMLTask> tempTasks = new ArrayList<>();
+        for (int i = 0; i < inputInstance.getModeling().getTasks().size(); i++) {
+            tempTasks.add((TMLTask) inputInstance.getModeling().getTasks().get(i));
+        }
+
+        assertEquals(inputInstance.getBufferOut((TMLTask) tempTasks.get(0)), 4);
+        assertEquals(inputInstance.getBufferOut((TMLTask) tempTasks.get(1)), 5);
+        assertEquals(inputInstance.getBufferOut((TMLTask) tempTasks.get(2)), 5);
+        assertEquals(inputInstance.getBufferOut((TMLTask) tempTasks.get(3)), 0);
+
+    }
+
+
+    @Test
+    public void getLocalMemoryOfHwExecutionNode() {
+
+        HwNode output1 = inputInstance.getArchitecture().getHwMemoryByName("mainMem");
+        HwNode output2 = inputInstance.getArchitecture().getHwMemoryByName("dspMem");
+
+        assertTrue("comparing between the expected local memory for main_CPU and the memory found", inputInstance.getLocalMemoryOfHwExecutionNode(inputInstance.getArchitecture().getHwNodeByName("MainCPU")) == output1);
+        assertTrue("comparing between the expected local memory for DSP and the memory found", inputInstance.getLocalMemoryOfHwExecutionNode(inputInstance.getArchitecture().getHwNodeByName("dsp")) == output2);
+
+    }
+
+
+    @Test
+    public void getWCET() {
+        //a temporary list of the tasks
+        List<TMLTask> tempTasks = new ArrayList<>();
+        for (int i = 0; i < inputInstance.getModeling().getTasks().size(); i++) {
+            tempTasks.add((TMLTask) inputInstance.getModeling().getTasks().get(i));
+        }
+        int expectedWcetA_CPU = 300;
+        int expectedWcetA_dsp = 150;
+
+        assertEquals("comparing between the expected WCET of task A on main_CPU and the computed value", expectedWcetA_CPU, inputInstance.getWCET(tempTasks.get(0), (HwExecutionNode) inputInstance.getArchitecture().getHwNodeByName("MainCPU")));
+        assertEquals("comparing between the expected WCET of task A on DSP and the computed value", expectedWcetA_dsp, inputInstance.getWCET(tempTasks.get(0), (HwExecutionNode) inputInstance.getArchitecture().getHwNodeByName("dsp")));
+
+    }
+
+
+    @Test
+    public void getFinalTask() {
+        assertEquals("checking the last task", inputInstance.getModeling().getTMLTaskByName("task__E"), inputInstance.getFinalTask(inputInstance.getModeling()));
+
+    }
+}
\ No newline at end of file
diff --git a/ttool/ttool.txt b/ttool/ttool.txt
index 10097015927284921e727b51a256033bd3248606..6def7b20843c61978d1caedc95357eebb43d3759 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-1.3.jar ./gs-ui-1.3.jar ./commons-io-2.5.jar ./batik-awt-util.jar ./batik-dom.jar ./batik-svggen.jar ./batik-util.jar ./batik-xml.jar ./jautomata-core.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-1.3.jar ./gs-ui-1.3.jar ./commons-io-2.5.jar ./batik-awt-util.jar ./batik-dom.jar ./batik-svggen.jar ./batik-util.jar ./batik-xml.jar ./jautomata-core.jar ./com.microsoft.z3.jar