From d91552fe740be4d76631c7a4692f10615e03ce23 Mon Sep 17 00:00:00 2001
From: jerray <jawher.jerray@eurecom.fr>
Date: Tue, 24 Oct 2023 20:04:42 +0200
Subject: [PATCH] add auto mapping of tasks and channels for patterns + update
 tml2avatar

---
 .../patternhandling/PatternIntegration.java   | 493 +++++++++++++++++-
 .../SecurityGenerationForTMAP.java            | 292 ++++++-----
 .../tmltranslator/toavatarsec/TML2Avatar.java |  23 +-
 3 files changed, 687 insertions(+), 121 deletions(-)

diff --git a/src/main/java/tmltranslator/patternhandling/PatternIntegration.java b/src/main/java/tmltranslator/patternhandling/PatternIntegration.java
index 2a017d2cdd..fcd6731f29 100644
--- a/src/main/java/tmltranslator/patternhandling/PatternIntegration.java
+++ b/src/main/java/tmltranslator/patternhandling/PatternIntegration.java
@@ -185,7 +185,9 @@ public class PatternIntegration implements Runnable {
         tmapModel = makeConnectionBetweenPatternAndModel(tmapModel, tmapPattern, patternConfiguration.getPortsConnection(), patternTasks);        
         tmapModel = configDisconnectedChannels(tmapModel, patternConfiguration.getPortsConfig(), renamedChannels);
         tmapModel = mapTasksInArch(tmapModel, patternConfiguration.getTasksMapping());
+        tmapModel = mapTasksInArchAuto(tmapModel, tmapPattern, patternConfiguration.getTasksMapping().keySet(), patternConfiguration, patternTasks);
         tmapModel = mapChannelsInArch(tmapModel, patternConfiguration.getChannelsMapping());
+        tmapModel = mapChannelsInArchAuto(tmapModel, tmapPattern, patternConfiguration.getTasksMapping().keySet(), patternConfiguration, patternTasks);
 
         TraceManager.addDev("Model elems result :");
 
@@ -1321,11 +1323,267 @@ public class PatternIntegration implements Runnable {
         return _tmapModel;
     }
 
-    public TMLMapping<?> mapTasksInArchAuto(TMLMapping<?> _tmapModel, LinkedHashMap<String, Entry<String, String>> _taskMapping) {
-        
+    public TMLMapping<?> mapTasksInArchAuto(TMLMapping<?> _tmapModel, TMLMapping<?> _tmapPattern, Set<String> mappedTasks, PatternConfiguration _patternConfiguration, LinkedHashMap<String, TaskPattern> _patternTasks) {
+        TMLModeling<?> tmlmModel = _tmapModel.getTMLModeling();
+        TMLModeling<?> tmlmPattern = _tmapPattern.getTMLModeling();
+        Map<TMLTask, TMLTask> correspTasks = correspondenceForTasks(_tmapModel, _tmapPattern, _patternConfiguration, _patternTasks);
+        Map<TMLTask, TMLTask> correspondenceForClonedTasks = correspondenceForClonedTasks(_tmapModel, _tmapPattern, mappedTasks, _patternConfiguration, _patternTasks);
+        LinkedHashMap<String, TaskPattern> _patternTasksSorted = new LinkedHashMap<String, TaskPattern>();
+        LinkedHashMap<String, TaskPattern> _patternTasksInEnd = new LinkedHashMap<String, TaskPattern>();
+        for (String taskName : _patternTasks.keySet()) {
+            if (_patternTasks.get(taskName).getExternalPorts().size() == 0) {
+                _patternTasksInEnd.put(taskName, _patternTasks.get(taskName));
+            } else {
+                _patternTasksSorted.put(taskName, _patternTasks.get(taskName));
+            }
+        }
+        _patternTasksSorted.putAll(_patternTasksInEnd);
+        outerloop:
+        for (String taskName : _patternTasksSorted.keySet()) {
+            TMLTask task = tmlmPattern.getTMLTaskByName(taskName);
+            if (task != null && !mappedTasks.contains(taskName)) {
+                HwExecutionNode hwMapTask = _tmapPattern.getHwNodeOf(task);
+                HashSet<TMLTask> tasksInThisCPU = _tmapPattern.getLisMappedTasks(hwMapTask);
+                for (TMLTask taskInCPU : tasksInThisCPU) {
+                    if (_patternTasks.containsKey(taskInCPU.getName())) {
+                        TMLTask taskInModel = tmlmModel.getTMLTaskByName(taskInCPU.getName());
+                        HwExecutionNode hwMapTaskInModel = _tmapModel.getHwNodeOf(taskInModel);
+                        if (hwMapTaskInModel != null) {
+                            TMLTask taskToMap = tmlmModel.getTMLTaskByName(taskName);
+                            _tmapModel.addTaskToHwExecutionNode(taskToMap, hwMapTaskInModel);
+                            break outerloop;
+                        }
+                    } else if (correspTasks.containsKey(taskInCPU)) {
+                        TMLTask taskInModel = tmlmModel.getTMLTaskByName((correspTasks.get(taskInCPU)).getName());
+                        HwExecutionNode hwMapTaskInModel = _tmapModel.getHwNodeOf(taskInModel);
+                        if (hwMapTaskInModel != null) {
+                            TMLTask taskToMap = tmlmModel.getTMLTaskByName(taskName);
+                            _tmapModel.addTaskToHwExecutionNode(taskToMap, hwMapTaskInModel);
+                            break outerloop;
+                        }
+                    }
+                }
+                String nameNewCPU = hwMapTask.getName();
+                HwExecutionNode newCPU = _tmapModel.getHwExecutionNodeByName(nameNewCPU);
+                int ind = 0;
+                while (newCPU != null) {
+                    nameNewCPU = hwMapTask.getName() + ind;
+                    newCPU = _tmapModel.getHwExecutionNodeByName(nameNewCPU);
+                    ind += 1;
+                }
+                HwCPU _newCpu = new HwCPU(nameNewCPU);
+                TMLTask taskToMap = tmlmModel.getTMLTaskByName(taskName);
+                _tmapModel.addTaskToHwExecutionNode(taskToMap, _newCpu);
+                _tmapModel.getArch().addHwNode(_newCpu);
+                HwBus bus = null;
+                for (TMLChannel ch : tmlmModel.getChannelsFromMe(taskToMap)) {
+                    TMLTask taskInConn = ch.getDestinationTask();
+                    HwExecutionNode hwOfTaskInConn = _tmapModel.getHwNodeOf(taskInConn);
+                    if (hwOfTaskInConn != null) {
+                        for (HwLink link : _tmapModel.getArch().getHwLinks()) {
+                            if (link.hwnode == hwOfTaskInConn) {
+                                bus = link.bus;
+                            }
+                        }
+                    }
+                }
+                for (TMLChannel ch : tmlmModel.getChannelsToMe(taskToMap)) {
+                    TMLTask taskInConn = ch.getOriginTask();
+                    HwExecutionNode hwOfTaskInConn = _tmapModel.getHwNodeOf(taskInConn);
+                    if (hwOfTaskInConn != null) {
+                        for (HwLink link : _tmapModel.getArch().getHwLinks()) {
+                            if (link.hwnode == hwOfTaskInConn) {
+                                bus = link.bus;
+                            }
+                        }
+                    }
+                }
+                if (bus == null) {
+                    int nbConnections = 0 ; 
+                    for (HwNode busModel : _tmapModel.getArch().getBUSs()) {
+                        if (busModel instanceof HwBus) {
+                            int curNbConnections = 0 ;
+                            for (HwLink link : _tmapModel.getArch().getHwLinks()) {
+                                if (link.bus == busModel) {
+                                    nbConnections += 1;
+                                }
+                            }
+                            if (curNbConnections > nbConnections) {
+                                bus = (HwBus) busModel;
+                                nbConnections = curNbConnections;
+                            }
+                        }
+                    }
+                    
+                }
+                
+                HwLink linkNewCPUWithBus = new HwLink("link_" + _newCpu.getName() + "_to_" + bus.getName());
+                linkNewCPUWithBus.bus = bus;
+                linkNewCPUWithBus.hwnode = _newCpu;
+                _tmapModel.getArch().addHwLink(linkNewCPUWithBus);
+            }
+        }
+        outerloop1:
+        for (String taskName : _patternConfiguration.getClonedTasks().keySet()) {
+            TMLTask task = tmlmModel.getTMLTaskByName(taskName);
+            if (task != null && !mappedTasks.contains(taskName)) {
+                TMLTask taskInPattern = correspondenceForClonedTasks.get(task);
+
+                HwExecutionNode hwMapTask = _tmapPattern.getHwNodeOf(taskInPattern);
+                HashSet<TMLTask> tasksInThisCPU = _tmapPattern.getLisMappedTasks(hwMapTask);
+                for (TMLTask taskInCPU : tasksInThisCPU) {
+                    if (_patternTasks.containsKey(taskInCPU.getName())) {
+                        TMLTask taskInModel = tmlmModel.getTMLTaskByName(taskInCPU.getName());
+                        HwExecutionNode hwMapTaskInModel = _tmapModel.getHwNodeOf(taskInModel);
+                        if (hwMapTaskInModel != null) {
+                            _tmapModel.addTaskToHwExecutionNode(task, hwMapTaskInModel);
+                            break outerloop1;
+                        }
+                    } else if (correspTasks.containsKey(taskInCPU)) {
+                        TMLTask taskInModel = tmlmModel.getTMLTaskByName((correspTasks.get(taskInCPU)).getName());
+                        HwExecutionNode hwMapTaskInModel = _tmapModel.getHwNodeOf(taskInModel);
+                        if (hwMapTaskInModel != null) {
+                            _tmapModel.addTaskToHwExecutionNode(task, hwMapTaskInModel);
+                            break outerloop1;
+                        }
+                    }
+                }
+                String nameNewCPU = hwMapTask.getName();
+                HwExecutionNode newCPU = _tmapModel.getHwExecutionNodeByName(nameNewCPU);
+                int ind = 0;
+                while (newCPU != null) {
+                    nameNewCPU = hwMapTask.getName() + ind;
+                    newCPU = _tmapModel.getHwExecutionNodeByName(nameNewCPU);
+                    ind += 1;
+                }
+                HwCPU _newCpu = new HwCPU(nameNewCPU);
+                TMLTask taskToMap = tmlmModel.getTMLTaskByName(taskName);
+                _tmapModel.addTaskToHwExecutionNode(taskToMap, _newCpu);
+                _tmapModel.getArch().addHwNode(_newCpu);
+
+                HwBus bus = null;
+                for (TMLChannel ch : tmlmModel.getChannelsFromMe(taskToMap)) {
+                    TMLTask taskInConn = ch.getDestinationTask();
+                    HwExecutionNode hwOfTaskInConn = _tmapModel.getHwNodeOf(taskInConn);
+                    if (hwOfTaskInConn != null) {
+                        for (HwLink link : _tmapModel.getArch().getHwLinks()) {
+                            if (link.hwnode == hwOfTaskInConn) {
+                                bus = link.bus;
+                            }
+                        }
+                    }
+                }
+                for (TMLChannel ch : tmlmModel.getChannelsToMe(taskToMap)) {
+                    TMLTask taskInConn = ch.getOriginTask();
+                    HwExecutionNode hwOfTaskInConn = _tmapModel.getHwNodeOf(taskInConn);
+                    if (hwOfTaskInConn != null) {
+                        for (HwLink link : _tmapModel.getArch().getHwLinks()) {
+                            if (link.hwnode == hwOfTaskInConn) {
+                                bus = link.bus;
+                            }
+                        }
+                    }
+                }
+                if (bus == null) {
+                    int nbConnections = 0 ; 
+                    for (HwNode busModel : _tmapModel.getArch().getBUSs()) {
+                        if (busModel instanceof HwBus) {
+                            int curNbConnections = 0 ;
+                            for (HwLink link : _tmapModel.getArch().getHwLinks()) {
+                                if (link.bus == busModel) {
+                                    nbConnections += 1;
+                                }
+                            }
+                            if (curNbConnections > nbConnections) {
+                                bus = (HwBus) busModel;
+                                nbConnections = curNbConnections;
+                            }
+                        }
+                    }
+                }
+                HwLink linkNewCPUWithBus = new HwLink("link_" + _newCpu.getName() + "_to_" + bus.getName());
+                linkNewCPUWithBus.bus = bus;
+                linkNewCPUWithBus.hwnode = _newCpu;
+                _tmapModel.getArch().addHwLink(linkNewCPUWithBus);
+
+            }
+        }
+
         return _tmapModel;
     }
 
+    // Find correspondence between Tasks of the pattern model and the cloned tasks of current Model 
+    public Map<TMLTask, TMLTask> correspondenceForClonedTasks(TMLMapping<?> _tmapModel, TMLMapping<?> _tmapPattern, Set<String> mappedTasks, PatternConfiguration _patternConfiguration, LinkedHashMap<String, TaskPattern> _patternTasks) {
+        TMLModeling<?> tmlmModel = _tmapModel.getTMLModeling();
+        TMLModeling<?> tmlmPattern = _tmapPattern.getTMLModeling();
+        List <String> clonedTasksToMap = new ArrayList<String>();
+        // List <TMLTask> patternTasksToMap = new ArrayList<TMLTask>();
+        for (String taskName : _patternConfiguration.getClonedTasks().keySet()) {
+            TMLTask task = tmlmModel.getTMLTaskByName(taskName);
+            if (task != null && !mappedTasks.contains(taskName)) {
+                clonedTasksToMap.add(task.getName());
+            }
+        }
+        /* for (String taskName : _patternTasks.keySet()) {
+            TMLTask task = tmlmModel.getTMLTaskByName(taskName);
+            if (task != null && !mappedTasks.contains(taskName)) {
+                patternTasksToMap.add(task);
+            }
+        } */
+        Map<TMLTask, TMLTask> correspTasks = new HashMap<TMLTask, TMLTask>();
+        for (String taskPatternName : _patternConfiguration.getPortsConnection().keySet()) {
+            for (String[] pc : _patternConfiguration.getPortsConnection().get(taskPatternName)) {
+                if (clonedTasksToMap.contains(pc[1])) {
+                    TMLChannel chInPattern = tmlmPattern.getChannelByName(pc[0]);
+                    String modeChInPattern = "";
+                    for (PortTaskJsonFile pt : _patternTasks.get(taskPatternName).getExternalPorts()) {
+                        if (pt.getName().equals(pc[0])) {
+                            modeChInPattern = pt.getMode();
+                            break;
+                        }
+                    }
+                    if (chInPattern != null) {
+                        if (modeChInPattern.equals(PatternCreation.MODE_INPUT)) {
+                            correspTasks.put(tmlmModel.getTMLTaskByName(pc[1]), chInPattern.getOriginTask());
+                        } else if (modeChInPattern.equals(PatternCreation.MODE_OUTPUT)) {
+                            correspTasks.put(tmlmModel.getTMLTaskByName(pc[1]), chInPattern.getDestinationTask());
+                        }
+                        
+                    }
+                }
+            }
+        }
+        return correspTasks;
+    }
+
+    // Find correspondence between Tasks of the pattern model and the tasks of current Model 
+    public Map<TMLTask, TMLTask> correspondenceForTasks(TMLMapping<?> _tmapModel, TMLMapping<?> _tmapPattern, PatternConfiguration _patternConfiguration, LinkedHashMap<String, TaskPattern> _patternTasks) {
+        TMLModeling<?> tmlmModel = _tmapModel.getTMLModeling();
+        TMLModeling<?> tmlmPattern = _tmapPattern.getTMLModeling();
+        Map<TMLTask, TMLTask> correspTasks = new HashMap<TMLTask, TMLTask>();
+        for (String taskPatternName : _patternConfiguration.getPortsConnection().keySet()) {
+            for (String[] pc : _patternConfiguration.getPortsConnection().get(taskPatternName)) {
+                TMLChannel chInPattern = tmlmPattern.getChannelByName(pc[0]);
+                String modeChInPattern = "";
+                for (PortTaskJsonFile pt : _patternTasks.get(taskPatternName).getExternalPorts()) {
+                    if (pt.getName().equals(pc[0])) {
+                        modeChInPattern = pt.getMode();
+                        break;
+                    }
+                }
+                if (chInPattern != null) {
+                    if (modeChInPattern.equals(PatternCreation.MODE_INPUT)) {
+                        correspTasks.put(chInPattern.getOriginTask(), tmlmModel.getTMLTaskByName(pc[1]));
+                    } else if (modeChInPattern.equals(PatternCreation.MODE_OUTPUT)) {
+                        correspTasks.put(chInPattern.getDestinationTask(), tmlmModel.getTMLTaskByName(pc[1]));
+                    }
+                }
+            }
+        }
+        return correspTasks;
+    }
+
+
     public TMLMapping<?> mapChannelsInArch(TMLMapping<?> _tmapModel, LinkedHashMap<String, List<String[]>> _channelMapping) {
         TMLArchitecture _tmlarchModel =  _tmapModel.getArch();
         for (String taskName : _channelMapping.keySet()) {
@@ -1387,6 +1645,237 @@ public class PatternIntegration implements Runnable {
         return _tmapModel;
     }
 
+    public TMLMapping<?> mapChannelsInArchAuto(TMLMapping<?> _tmapModel, TMLMapping<?> _tmapPattern, Set<String> mappedTasks, PatternConfiguration _patternConfiguration, LinkedHashMap<String, TaskPattern> _patternTasks) {
+        TMLModeling<?> tmlmModel = _tmapModel.getTMLModeling();
+        TMLModeling<?> tmlmPattern = _tmapPattern.getTMLModeling();
+        Map<TMLTask, TMLTask> correspTasks = correspondenceForTasks(_tmapModel, _tmapPattern, _patternConfiguration, _patternTasks);
+        Map<TMLTask, TMLTask> correspondenceForClonedTasks = correspondenceForClonedTasks(_tmapModel, _tmapPattern, mappedTasks, _patternConfiguration, _patternTasks);
+        LinkedHashMap<String, TaskPattern> _patternTasksSorted = new LinkedHashMap<String, TaskPattern>();
+        LinkedHashMap<String, TaskPattern> _patternTasksInEnd = new LinkedHashMap<String, TaskPattern>();
+        for (String taskName : _patternTasks.keySet()) {
+            if (_patternTasks.get(taskName).getExternalPorts().size() == 0) {
+                _patternTasksInEnd.put(taskName, _patternTasks.get(taskName));
+            } else {
+                _patternTasksSorted.put(taskName, _patternTasks.get(taskName));
+            }
+        }
+        _patternTasksSorted.putAll(_patternTasksInEnd);
+        outerloop:
+        for (String taskName : _patternTasksSorted.keySet()) {
+            TMLTask task = tmlmPattern.getTMLTaskByName(taskName);
+            if (task != null && !mappedTasks.contains(taskName)) {
+                HwExecutionNode hwMapTask = _tmapPattern.getHwNodeOf(task);
+                HashSet<TMLTask> tasksInThisCPU = _tmapPattern.getLisMappedTasks(hwMapTask);
+                for (TMLTask taskInCPU : tasksInThisCPU) {
+                    if (_patternTasks.containsKey(taskInCPU.getName())) {
+                        TMLTask taskInModel = tmlmModel.getTMLTaskByName(taskInCPU.getName());
+                        HwExecutionNode hwMapTaskInModel = _tmapModel.getHwNodeOf(taskInModel);
+                        if (hwMapTaskInModel != null) {
+                            TMLTask taskToMap = tmlmModel.getTMLTaskByName(taskName);
+                            _tmapModel.addTaskToHwExecutionNode(taskToMap, hwMapTaskInModel);
+                            break outerloop;
+                        }
+                    } else if (correspTasks.containsKey(taskInCPU)) {
+                        TMLTask taskInModel = tmlmModel.getTMLTaskByName((correspTasks.get(taskInCPU)).getName());
+                        HwExecutionNode hwMapTaskInModel = _tmapModel.getHwNodeOf(taskInModel);
+                        if (hwMapTaskInModel != null) {
+                            TMLTask taskToMap = tmlmModel.getTMLTaskByName(taskName);
+                            _tmapModel.addTaskToHwExecutionNode(taskToMap, hwMapTaskInModel);
+                            break outerloop;
+                        }
+                    }
+                }
+                String nameNewCPU = hwMapTask.getName();
+                HwExecutionNode newCPU = _tmapModel.getHwExecutionNodeByName(nameNewCPU);
+                int ind = 0;
+                while (newCPU != null) {
+                    nameNewCPU = hwMapTask.getName() + ind;
+                    newCPU = _tmapModel.getHwExecutionNodeByName(nameNewCPU);
+                    ind += 1;
+                }
+                HwCPU _newCpu = new HwCPU(nameNewCPU);
+                TMLTask taskToMap = tmlmModel.getTMLTaskByName(taskName);
+                _tmapModel.addTaskToHwExecutionNode(taskToMap, _newCpu);
+                _tmapModel.getArch().addHwNode(_newCpu);
+                HwBus bus = null;
+                for (TMLChannel ch : tmlmModel.getChannelsFromMe(taskToMap)) {
+                    TMLTask taskInConn = ch.getDestinationTask();
+                    HwExecutionNode hwOfTaskInConn = _tmapModel.getHwNodeOf(taskInConn);
+                    if (hwOfTaskInConn != null) {
+                        for (HwLink link : _tmapModel.getArch().getHwLinks()) {
+                            if (link.hwnode == hwOfTaskInConn) {
+                                bus = link.bus;
+                            }
+                        }
+                    }
+                }
+                for (TMLChannel ch : tmlmModel.getChannelsToMe(taskToMap)) {
+                    TMLTask taskInConn = ch.getOriginTask();
+                    HwExecutionNode hwOfTaskInConn = _tmapModel.getHwNodeOf(taskInConn);
+                    if (hwOfTaskInConn != null) {
+                        for (HwLink link : _tmapModel.getArch().getHwLinks()) {
+                            if (link.hwnode == hwOfTaskInConn) {
+                                bus = link.bus;
+                            }
+                        }
+                    }
+                }
+                if (bus == null) {
+                    int nbConnections = 0 ; 
+                    for (HwNode busModel : _tmapModel.getArch().getBUSs()) {
+                        if (busModel instanceof HwBus) {
+                            int curNbConnections = 0 ;
+                            for (HwLink link : _tmapModel.getArch().getHwLinks()) {
+                                if (link.bus == busModel) {
+                                    nbConnections += 1;
+                                }
+                            }
+                            if (curNbConnections > nbConnections) {
+                                bus = (HwBus) busModel;
+                                nbConnections = curNbConnections;
+                            }
+                        }
+                    }
+                    
+                }
+                
+                HwLink linkNewCPUWithBus = new HwLink("link_" + _newCpu.getName() + "_to_" + bus.getName());
+                linkNewCPUWithBus.bus = bus;
+                linkNewCPUWithBus.hwnode = _newCpu;
+                _tmapModel.getArch().addHwLink(linkNewCPUWithBus);
+            }
+        }
+        outerloop1:
+        for (String taskName : _patternConfiguration.getClonedTasks().keySet()) {
+            TMLTask task = tmlmModel.getTMLTaskByName(taskName);
+            if (task != null && !mappedTasks.contains(taskName)) {
+                TMLTask taskInPattern = correspondenceForClonedTasks.get(task);
+
+                HwExecutionNode hwMapTask = _tmapPattern.getHwNodeOf(taskInPattern);
+                HashSet<TMLTask> tasksInThisCPU = _tmapPattern.getLisMappedTasks(hwMapTask);
+                for (TMLTask taskInCPU : tasksInThisCPU) {
+                    if (_patternTasks.containsKey(taskInCPU.getName())) {
+                        TMLTask taskInModel = tmlmModel.getTMLTaskByName(taskInCPU.getName());
+                        HwExecutionNode hwMapTaskInModel = _tmapModel.getHwNodeOf(taskInModel);
+                        if (hwMapTaskInModel != null) {
+                            _tmapModel.addTaskToHwExecutionNode(task, hwMapTaskInModel);
+                            break outerloop1;
+                        }
+                    } else if (correspTasks.containsKey(taskInCPU)) {
+                        TMLTask taskInModel = tmlmModel.getTMLTaskByName((correspTasks.get(taskInCPU)).getName());
+                        HwExecutionNode hwMapTaskInModel = _tmapModel.getHwNodeOf(taskInModel);
+                        if (hwMapTaskInModel != null) {
+                            _tmapModel.addTaskToHwExecutionNode(task, hwMapTaskInModel);
+                            break outerloop1;
+                        }
+                    }
+                }
+                String nameNewCPU = hwMapTask.getName();
+                HwExecutionNode newCPU = _tmapModel.getHwExecutionNodeByName(nameNewCPU);
+                int ind = 0;
+                while (newCPU != null) {
+                    nameNewCPU = hwMapTask.getName() + ind;
+                    newCPU = _tmapModel.getHwExecutionNodeByName(nameNewCPU);
+                    ind += 1;
+                }
+                HwCPU _newCpu = new HwCPU(nameNewCPU);
+                TMLTask taskToMap = tmlmModel.getTMLTaskByName(taskName);
+                _tmapModel.addTaskToHwExecutionNode(taskToMap, _newCpu);
+                _tmapModel.getArch().addHwNode(_newCpu);
+
+                HwBus bus = null;
+                for (TMLChannel ch : tmlmModel.getChannelsFromMe(taskToMap)) {
+                    TMLTask taskInConn = ch.getDestinationTask();
+                    HwExecutionNode hwOfTaskInConn = _tmapModel.getHwNodeOf(taskInConn);
+                    if (hwOfTaskInConn != null) {
+                        for (HwLink link : _tmapModel.getArch().getHwLinks()) {
+                            if (link.hwnode == hwOfTaskInConn) {
+                                bus = link.bus;
+                            }
+                        }
+                    }
+                }
+                for (TMLChannel ch : tmlmModel.getChannelsToMe(taskToMap)) {
+                    TMLTask taskInConn = ch.getOriginTask();
+                    HwExecutionNode hwOfTaskInConn = _tmapModel.getHwNodeOf(taskInConn);
+                    if (hwOfTaskInConn != null) {
+                        for (HwLink link : _tmapModel.getArch().getHwLinks()) {
+                            if (link.hwnode == hwOfTaskInConn) {
+                                bus = link.bus;
+                            }
+                        }
+                    }
+                }
+                if (bus == null) {
+                    int nbConnections = 0 ; 
+                    for (HwNode busModel : _tmapModel.getArch().getBUSs()) {
+                        if (busModel instanceof HwBus) {
+                            int curNbConnections = 0 ;
+                            for (HwLink link : _tmapModel.getArch().getHwLinks()) {
+                                if (link.bus == busModel) {
+                                    nbConnections += 1;
+                                }
+                            }
+                            if (curNbConnections > nbConnections) {
+                                bus = (HwBus) busModel;
+                                nbConnections = curNbConnections;
+                            }
+                        }
+                    }
+                }
+                HwLink linkNewCPUWithBus = new HwLink("link_" + _newCpu.getName() + "_to_" + bus.getName());
+                linkNewCPUWithBus.bus = bus;
+                linkNewCPUWithBus.hwnode = _newCpu;
+                _tmapModel.getArch().addHwLink(linkNewCPUWithBus);
+
+            }
+        }
+
+        return _tmapModel;
+    }
+
+    // Find correspondence between Channels of the pattern model and the channels of cloned tasks of current Model 
+    public Map<TMLChannel, TMLChannel> correspondenceForClonedChannels(TMLMapping<?> _tmapModel, TMLMapping<?> _tmapPattern, Set<String> mappedTasks, PatternConfiguration _patternConfiguration, LinkedHashMap<String, TaskPattern> _patternTasks) {
+        TMLModeling<?> tmlmModel = _tmapModel.getTMLModeling();
+        TMLModeling<?> tmlmPattern = _tmapPattern.getTMLModeling();
+        List <String> clonedTasksToMap = new ArrayList<String>();
+        // List <TMLTask> patternTasksToMap = new ArrayList<TMLTask>();
+        for (String taskName : _patternConfiguration.getClonedTasks().keySet()) {
+            TMLTask task = tmlmModel.getTMLTaskByName(taskName);
+            if (task != null && !mappedTasks.contains(taskName)) {
+                clonedTasksToMap.add(task.getName());
+            }
+        }
+        Map<TMLChannel, TMLChannel> correspChannels = new HashMap<TMLChannel, TMLChannel>();
+        for (String taskPatternName : _patternConfiguration.getPortsConnection().keySet()) {
+            for (String[] pc : _patternConfiguration.getPortsConnection().get(taskPatternName)) {
+                if (clonedTasksToMap.contains(pc[1])) {
+                    TMLChannel chInPattern = tmlmPattern.getChannelByName(pc[0]);
+
+                    if (chInPattern != null) {
+                        correspChannels.put(tmlmModel.getChannelByName(pc[2]), chInPattern);
+                    }
+                }
+            }
+        }
+        return correspChannels;
+    }
+
+    // Find correspondence between channels of the pattern model and the channels of current Model 
+    public Map<TMLChannel, TMLChannel> correspondenceForChannels(TMLMapping<?> _tmapModel, TMLMapping<?> _tmapPattern, PatternConfiguration _patternConfiguration, LinkedHashMap<String, TaskPattern> _patternTasks) {
+        TMLModeling<?> tmlmModel = _tmapModel.getTMLModeling();
+        TMLModeling<?> tmlmPattern = _tmapPattern.getTMLModeling();
+        Map<TMLChannel, TMLChannel> correspChannels = new HashMap<TMLChannel, TMLChannel>();
+        for (String taskPatternName : _patternConfiguration.getPortsConnection().keySet()) {
+            for (String[] pc : _patternConfiguration.getPortsConnection().get(taskPatternName)) {
+                TMLChannel chInPattern = tmlmPattern.getChannelByName(pc[0]);
+                if (chInPattern != null) {
+                   correspChannels.put(chInPattern, tmlmModel.getChannelByName(pc[2]));
+                }
+            }
+        }
+        return correspChannels;
+    }
 
     @SuppressWarnings("unchecked")
     public TMLMapping<?> getTMLMappingOfPattern(String _path, String fileName) {
diff --git a/src/main/java/tmltranslator/patternhandling/SecurityGenerationForTMAP.java b/src/main/java/tmltranslator/patternhandling/SecurityGenerationForTMAP.java
index 054dbae858..04f0cbaa9d 100644
--- a/src/main/java/tmltranslator/patternhandling/SecurityGenerationForTMAP.java
+++ b/src/main/java/tmltranslator/patternhandling/SecurityGenerationForTMAP.java
@@ -750,47 +750,44 @@ public class SecurityGenerationForTMAP implements Runnable {
             }
         }*/
 
-        for (String cpuName : selectedCPUTasks.keySet()) {
-
-            for (TMLTask task : toSecureRev.keySet()) {
-                // TraceManager.addDev("Adding nonces to " + task.getName());
-                List<TMLChannel> chans = tmlmodel.getChannelsFromMe(task);
-
-                for (TMLTask task2 : toSecureRev.get(task)) {
-                    boolean addChan = true;
-                    for (TMLChannel chan : chans) {
-                        if (chan.getDestinationTask() == task2) {
-                            addChan = false;
-                        }
+        for (TMLTask task : toSecureRev.keySet()) {
+            // TraceManager.addDev("Adding nonces to " + task.getName());
+            List<TMLChannel> chans = tmlmodel.getChannelsFromMe(task);
+            for (TMLTask task2 : toSecureRev.get(task)) {
+                boolean addChan = true;
+                for (TMLChannel chan : chans) {
+                    if (chan.getDestinationTask() == task2) {
+                        addChan = false;
                     }
+                }
+                if (addChan) {
+                    TMLChannel channel = new TMLChannel("nonceCh" + task.getName().split("__")[1] + "_" + task2.getName().split("__")[1], task.getReferenceObject());
+                    if (tmlmodel.getChannelByName(channel.getName()) == null) {
+                        if (hsmTasks.contains(task.getName().replaceAll(title + "__", ""))) {
+                            channel.setOriginTask(tmap.getTaskByName("HSM_" + taskHSMMap.get(task.getName().replaceAll(title + "__", ""))));
+                            tmap.getTaskByName("HSM_" + taskHSMMap.get(task.getName().replaceAll(title + "__", ""))).addWriteTMLChannel(channel);
+                        } else {
+                            channel.setOriginTask(task);
+                            task.addWriteTMLChannel(channel);
+                        }
 
-                    if (addChan) {
-                        TMLChannel channel = new TMLChannel("nonceCh" + task.getName().split("__")[1] + "_" + task2.getName().split("__")[1], task.getReferenceObject());
-                        if (tmlmodel.getChannelByName(channel.getName()) == null) {
-                            if (hsmTasks.contains(task.getName().replaceAll(title + "__", ""))) {
-                                channel.setOriginTask(tmap.getTaskByName("HSM_" + taskHSMMap.get(task.getName().replaceAll(title + "__", ""))));
-                                tmap.getTaskByName("HSM_" + taskHSMMap.get(task.getName().replaceAll(title + "__", ""))).addWriteTMLChannel(channel);
-                            } else {
-                                channel.setOriginTask(task);
-                                task.addWriteTMLChannel(channel);
-                            }
-
-                            if (hsmTasks.contains(task2.getName().replaceAll(title + "__", ""))) {
-                                channel.setDestinationTask(tmap.getTaskByName("HSM_" + taskHSMMap.get(task2.getName().replaceAll(title + "__", ""))));
-                                tmap.getTaskByName("HSM_" + taskHSMMap.get(task2.getName().replaceAll(title + "__", ""))).addReadTMLChannel(channel);
-                            } else {
-                                channel.setDestinationTask(task2);
-                                task2.addReadTMLChannel(channel);
-                            }
-                            
-                            channel.setPorts(new TMLPort(channel.getName(), channel.getReferenceObject()), new TMLPort(channel.getName(), channel.getReferenceObject()));
-                            tmlmodel.addChannel(channel);
+                        if (hsmTasks.contains(task2.getName().replaceAll(title + "__", ""))) {
+                            channel.setDestinationTask(tmap.getTaskByName("HSM_" + taskHSMMap.get(task2.getName().replaceAll(title + "__", ""))));
+                            tmap.getTaskByName("HSM_" + taskHSMMap.get(task2.getName().replaceAll(title + "__", ""))).addReadTMLChannel(channel);
+                        } else {
+                            channel.setDestinationTask(task2);
+                            task2.addReadTMLChannel(channel);
                         }
                         
+                        channel.setPorts(new TMLPort(channel.getName(), channel.getReferenceObject()), new TMLPort(channel.getName(), channel.getReferenceObject()));
+                        tmlmodel.addChannel(channel);
                     }
+                    
                 }
             }
-            
+        }
+
+        for (String cpuName : selectedCPUTasks.keySet()) {          
             buildHSMActivityDiagram(cpuName);
             //Add a private bus to Hardware Accelerator with the task for hsm
 
@@ -870,7 +867,7 @@ public class SecurityGenerationForTMAP implements Runnable {
             // TraceManager.addDev("Adding nonces to " + task.getName());
 
             for (TMLTask task2 : toSecureRev.get(task)) {
-                TMLChannel channel = tmlmodel.getChannelByShortName("nonceCh" + task.getName().split("__")[1] + "_" + task2.getName().split("__")[1]);
+                TMLChannel channel = tmlmodel.getChannelByName("nonceCh" + task.getName().split("__")[1] + "_" + task2.getName().split("__")[1]);
                 
                 List<TMLChannel> chans, chans2;
                 
@@ -938,7 +935,7 @@ public class SecurityGenerationForTMAP implements Runnable {
                         }
                     }
                 }
-                TraceManager.addDev("Starrt  channel = ");
+                TraceManager.addDev("Starrt  channel = " + channel.getName());
                 for (HwCommunicationNode mappedNode : tmap.getAllCommunicationNodesOfChannel(channel)) {
                     TraceManager.addDev("channel = " + channel.getName() + " mappedNode = " + mappedNode.getName());
                 }
@@ -1005,37 +1002,53 @@ public class SecurityGenerationForTMAP implements Runnable {
                     
                     TMLActivityElement prevElem = taskAD.getPrevious(elem);
                     if (nonceOutChannels.get(task).contains(channel)) {
-                        //Receive any nonces if ensuring authenticity
-                        TMLReadChannel rd = new TMLReadChannel("", taskAD.getReferenceObject());
-                        //System.out.println("tmlc " + tmlc);
-                        //					System.out.println("Checking "+ tmlc.getDestinationTask() + " " + tmlc.getOriginTask());
-                        List<TMLChannel> matches = tmlmodel.getChannels(tmlc.getDestinationTask(), tmlc.getOriginTask());
-
-                        if (matches.size() > 0) {
-                            rd.setName(matches.get(0).getName().replaceAll(title + "__", ""));
-                            if (tmlmodel.getChannelByName(rd.getName()) != null) {
-                                rd.addChannel(tmlmodel.getChannelByName(rd.getName()));
-                            } else if (tmlmodel.getChannelByShortName(rd.getName()) != null) {
-                                rd.addChannel(tmlmodel.getChannelByShortName(rd.getName()));
-                            }
-                        } else {
-                            rd.setName("nonceCh" + tmlc.getDestinationTask().getName().split("__")[1] + "_" + tmlc.getOriginTask().getName().split("__")[1]);
-                            if (tmlmodel.getChannelByName(rd.getName()) != null) {
-                                rd.addChannel(tmlmodel.getChannelByName(rd.getName()));
-                            } else if (tmlmodel.getChannelByShortName(rd.getName()) != null) {
-                                rd.addChannel(tmlmodel.getChannelByShortName(rd.getName()));
-                            }
-                        }
                         SecurityPattern secPatternNonce = new SecurityPattern("nonce_" + tmlc.getDestinationTask().getName().split("__")[1] + "_" + tmlc.getOriginTask().getName().split("__")[1], SecurityPattern.NONCE_PATTERN, overhead, "", encComp, decComp, "", "", "");
-                        secPatternNonce.originTask = rd.getChannel(0).getOriginTask().getName().replaceAll(title + "__", "");
-                        rd.securityPattern = secPatternNonce;  
-                        rd.setNbOfSamples("1");                   
-                        prevElem.setNewNext(elem, rd);
-                        rd.addNext(elem);
-                        taskAD.addElement(rd);
-                        //Move encryption operator after receive nonce component
                         if (tmlc != null) {
-                            encC.securityPattern.nonce = "nonce_" + tmlc.getDestinationTask().getName().split("__")[1] + "_" + tmlc.getOriginTask().getName().split("__")[1];
+                            encC.securityPattern.nonce = secPatternNonce.getName();
+                        }
+                        boolean addNewReadNonce = true;
+                        for (TMLActivityElement elemT : taskAD.getElements()) {
+                            if (elemT instanceof TMLReadChannel) {
+                                TMLReadChannel readElem = (TMLReadChannel) elemT;
+                                if (readElem.securityPattern != null) {
+                                    if(readElem.securityPattern.getName().equals(secPatternNonce.getName())) {
+                                        addNewReadNonce = false;
+                                        break;
+                                    }
+                                }
+                            }
+                        }
+                        if (addNewReadNonce) {
+                            //Receive any nonces if ensuring authenticity
+                            TMLReadChannel rd = new TMLReadChannel("", taskAD.getReferenceObject());
+                            //System.out.println("tmlc " + tmlc);
+                            //					System.out.println("Checking "+ tmlc.getDestinationTask() + " " + tmlc.getOriginTask());
+                            List<TMLChannel> matches = tmlmodel.getChannels(tmlc.getDestinationTask(), tmlc.getOriginTask());
+
+                            if (matches.size() > 0) {
+                                rd.setName(matches.get(0).getName().replaceAll(title + "__", ""));
+                                if (tmlmodel.getChannelByName(rd.getName()) != null) {
+                                    rd.addChannel(tmlmodel.getChannelByName(rd.getName()));
+                                } else if (tmlmodel.getChannelByShortName(rd.getName()) != null) {
+                                    rd.addChannel(tmlmodel.getChannelByShortName(rd.getName()));
+                                }
+                            } else {
+                                rd.setName("nonceCh" + tmlc.getDestinationTask().getName().split("__")[1] + "_" + tmlc.getOriginTask().getName().split("__")[1]);
+                                if (tmlmodel.getChannelByName(rd.getName()) != null) {
+                                    rd.addChannel(tmlmodel.getChannelByName(rd.getName()));
+                                } else if (tmlmodel.getChannelByShortName(rd.getName()) != null) {
+                                    rd.addChannel(tmlmodel.getChannelByShortName(rd.getName()));
+                                }
+                            }
+                            secPatternNonce.originTask = rd.getChannel(0).getOriginTask().getName().replaceAll(title + "__", "");
+                            rd.securityPattern = secPatternNonce;  
+                            rd.setNbOfSamples("1");                   
+                            TMLActivityElement nextFirst = taskAD.getFirst().getNextElement(0);
+                            taskAD.getFirst().setNewNext(nextFirst, rd);
+                            rd.addNext(nextFirst);
+                            taskAD.addElement(rd);
+                            //Move encryption operator after receive nonce component
+                            
                         }
                     }
                     prevElem = taskAD.getPrevious(elem);
@@ -1102,35 +1115,50 @@ public class SecurityGenerationForTMAP implements Runnable {
 
                     TMLActivityElement prevElem = taskAD.getPrevious(elem);
                     if (nonceOutChannels.get(task).contains(channel)) {
-                        //If we need to receive a nonce
-                        TMLReadChannel rd = new TMLReadChannel("", taskAD.getReferenceObject());
-                        //Receive any nonces if ensuring authenticity
-                        List<TMLChannel> matches = tmlmodel.getChannels(tmlc.getDestinationTask(), tmlc.getOriginTask());
-
-                        if (matches.size() > 0) {
-                            rd.setName(matches.get(0).getName().replaceAll(title + "__", ""));
-                            if (tmlmodel.getChannelByName(rd.getName()) != null) {
-                                rd.addChannel(tmlmodel.getChannelByName(rd.getName()));
-                            } else if (tmlmodel.getChannelByShortName(rd.getName()) != null) {
-                                rd.addChannel(tmlmodel.getChannelByShortName(rd.getName()));
-                            }
-                        } else {
-                            rd.setName("nonceCh" + tmlc.getDestinationTask().getName().split("__")[1] + "_" + tmlc.getOriginTask().getName().split("__")[1]);
-                            if (tmlmodel.getChannelByName(rd.getName()) != null) {
-                                rd.addChannel(tmlmodel.getChannelByName(rd.getName()));
-                            } else if (tmlmodel.getChannelByShortName(rd.getName()) != null) {
-                                rd.addChannel(tmlmodel.getChannelByShortName(rd.getName()));
-                            }
-                        }
                         SecurityPattern secPatternNonce = new SecurityPattern("nonce_" + tmlc.getDestinationTask().getName().split("__")[1] + "_" + tmlc.getOriginTask().getName().split("__")[1], SecurityPattern.NONCE_PATTERN, overhead, "", encComp, decComp, "", "", "");
-                        secPatternNonce.originTask = rd.getChannel(0).getOriginTask().getName().replaceAll(title + "__", "");
-                        rd.securityPattern = secPatternNonce;
-                        rd.setNbOfSamples("1"); 
-                        prevElem.setNewNext(elem, rd);
-                        rd.addNext(elem);
-                        taskAD.addElement(rd);
                         if (tmlc != null) {
-                            encC.securityPattern.nonce = "nonce_" + tmlc.getDestinationTask().getName().split("__")[1] + "_" + tmlc.getOriginTask().getName().split("__")[1];
+                            encC.securityPattern.nonce = secPatternNonce.getName();
+                        }
+                        boolean addNewReadNonce = true;
+                        for (TMLActivityElement elemT : taskAD.getElements()) {
+                            if (elemT instanceof TMLReadChannel) {
+                                TMLReadChannel readElem = (TMLReadChannel) elemT;
+                                if (readElem.securityPattern != null) {
+                                    if(readElem.securityPattern.getName().equals(secPatternNonce.getName())) {
+                                        addNewReadNonce = false;
+                                        break;
+                                    }
+                                }
+                            }
+                        }
+                        if (addNewReadNonce) {
+                            //If we need to receive a nonce
+                            TMLReadChannel rd = new TMLReadChannel("", taskAD.getReferenceObject());
+                            //Receive any nonces if ensuring authenticity
+                            List<TMLChannel> matches = tmlmodel.getChannels(tmlc.getDestinationTask(), tmlc.getOriginTask());
+                            if (matches.size() > 0) {
+                                rd.setName(matches.get(0).getName().replaceAll(title + "__", ""));
+                                if (tmlmodel.getChannelByName(rd.getName()) != null) {
+                                    rd.addChannel(tmlmodel.getChannelByName(rd.getName()));
+                                } else if (tmlmodel.getChannelByShortName(rd.getName()) != null) {
+                                    rd.addChannel(tmlmodel.getChannelByShortName(rd.getName()));
+                                }
+                            } else {
+                                rd.setName("nonceCh" + tmlc.getDestinationTask().getName().split("__")[1] + "_" + tmlc.getOriginTask().getName().split("__")[1]);
+                                if (tmlmodel.getChannelByName(rd.getName()) != null) {
+                                    rd.addChannel(tmlmodel.getChannelByName(rd.getName()));
+                                } else if (tmlmodel.getChannelByShortName(rd.getName()) != null) {
+                                    rd.addChannel(tmlmodel.getChannelByShortName(rd.getName()));
+                                }
+                            }
+                            secPatternNonce.originTask = rd.getChannel(0).getOriginTask().getName().replaceAll(title + "__", "");
+                            rd.securityPattern = secPatternNonce;
+                            rd.setNbOfSamples("1");
+                            TMLActivityElement nextFirst = taskAD.getFirst().getNextElement(0);
+                            taskAD.getFirst().setNewNext(nextFirst, rd);
+                            rd.addNext(nextFirst);
+                            taskAD.addElement(rd);
+                            
                         }
                     }
                     //Add encryption operator
@@ -1456,7 +1484,19 @@ public class SecurityGenerationForTMAP implements Runnable {
                         nonce.securityPattern = secNonce;
                         nonce.securityPattern.setProcess(SecurityPattern.ENCRYPTION_PROCESS);
                         nonce.setAction(Integer.toString(secNonce.encTime));
-                        if (!taskAD.getElements().contains(nonce)) {
+                        boolean addNewExecCNonce = true;
+                        for (TMLActivityElement elemT : taskAD.getElements()) {
+                            if (elemT instanceof TMLExecC) {
+                                TMLExecC exeCElem = (TMLExecC) elemT;
+                                if (exeCElem.securityPattern != null) {
+                                    if(exeCElem.securityPattern.getName().equals(secNonce.getName())) {
+                                        addNewExecCNonce = false;
+                                        break;
+                                    }
+                                }
+                            }
+                        }
+                        if (addNewExecCNonce) {
                             //Create a nonce operator and a write channel operator
                             tmlmodel.addSecurityPattern(secNonce);
                             if (tmlmodel.securityTaskMap.containsKey(secNonce)) {
@@ -1569,7 +1609,19 @@ public class SecurityGenerationForTMAP implements Runnable {
                         nonce.securityPattern = secNonce;
                         nonce.securityPattern.setProcess(SecurityPattern.ENCRYPTION_PROCESS);
                         nonce.setAction(Integer.toString(secNonce.encTime));
-                        if (!taskAD.getElements().contains(nonce)) {
+                        boolean addNewExecCNonce = true;
+                        for (TMLActivityElement elemT : taskAD.getElements()) {
+                            if (elemT instanceof TMLExecC) {
+                                TMLExecC exeCElem = (TMLExecC) elemT;
+                                if (exeCElem.securityPattern != null) {
+                                    if(exeCElem.securityPattern.getName().equals(secNonce.getName())) {
+                                        addNewExecCNonce = false;
+                                        break;
+                                    }
+                                }
+                            }
+                        }
+                        if (addNewExecCNonce) {
                             tmlmodel.addSecurityPattern(secNonce);
                             if (tmlmodel.securityTaskMap.containsKey(secNonce)) {
                                 if (!tmlmodel.securityTaskMap.get(secNonce).contains(task)) {
@@ -1697,6 +1749,8 @@ public class SecurityGenerationForTMAP implements Runnable {
         start.addNext(req);
 
         TMLActivityElement lastCurElem = req;
+        List<String> readNonces = new ArrayList<String>();
+        List<String> writeNonces = new ArrayList<String>();
         for (HSMChannel ch : hsmChannelMap.get(cpuName)) {
             if (!ch.nonceName.equals("")) {
                 if (ch.secType == HSMChannel.DEC) {
@@ -1705,7 +1759,7 @@ public class SecurityGenerationForTMAP implements Runnable {
                     nonce.securityPattern = secNonce;
                     nonce.securityPattern.setProcess(SecurityPattern.ENCRYPTION_PROCESS);
                     nonce.setAction(Integer.toString(secNonce.encTime));
-                    if (!taskAD.getElements().contains(nonce)) {
+                    if (!writeNonces.contains(nonce.getName())) {
                         tmlmodel.addSecurityPattern(secNonce);
                         if (tmlmodel.securityTaskMap.containsKey(secNonce)) {
                             if (!tmlmodel.securityTaskMap.get(secNonce).contains(task)) {
@@ -1738,32 +1792,36 @@ public class SecurityGenerationForTMAP implements Runnable {
                         taskAD.addElement(wr);
                         nonce.addNext(wr);
                         lastCurElem = wr;
+                        writeNonces.add(nonce.getName());
                     }
                 } else {
-                    //If we need to receive a nonce
-                    TMLReadChannel rd = new TMLReadChannel("", taskAD.getReferenceObject());
-                    //Receive any nonces if ensuring authenticity
-                    TraceManager.addDev("ch.name==" + ch.name);
-                    for (TMLChannel ch0 : tmlmodel.getChannels()) {
-                        TraceManager.addDev("ch0.name==" + ch0.getName());
-                    }
-                    rd.setName("nonceCh" + tmlmodel.getChannelByShortName(ch.name).getDestinationTask().getName().replaceAll(appName + "__", "") + "_" + ch.task);
-                    if (tmlmodel.getChannelByName(rd.getName()) != null) {
-                        rd.addChannel(tmlmodel.getChannelByName(rd.getName()));
-                    } else if (tmlmodel.getChannelByShortName(rd.getName()) != null) {
-                        rd.addChannel(tmlmodel.getChannelByShortName(rd.getName()));
-                    }
                     SecurityPattern secPatternNonce = new SecurityPattern("nonce_" + tmlmodel.getChannelByShortName(ch.name).getDestinationTask().getName().replaceAll(appName + "__", "") + "_" + ch.task, SecurityPattern.NONCE_PATTERN, overhead, "", encComp, decComp, "", "", "");
-                    secPatternNonce.originTask = rd.getChannel(0).getOriginTask().getName().replaceAll(appName + "__", "");
-                    rd.securityPattern = secPatternNonce;
-                    rd.setNbOfSamples("1");
-                    if (lastCurElem.getNbNext() > 0) {
-                        lastCurElem.setNewNext(lastCurElem.getNextElement(0), rd);
-                    } else {
-                        lastCurElem.addNext(rd);
+                    if (!readNonces.contains(secPatternNonce.getName())) {
+                        //If we need to receive a nonce
+                        TMLReadChannel rd = new TMLReadChannel("", taskAD.getReferenceObject());
+                        //Receive any nonces if ensuring authenticity
+                        TraceManager.addDev("ch.name==" + ch.name);
+                        for (TMLChannel ch0 : tmlmodel.getChannels()) {
+                            TraceManager.addDev("ch0.name==" + ch0.getName());
+                        }
+                        rd.setName("nonceCh" + tmlmodel.getChannelByShortName(ch.name).getDestinationTask().getName().replaceAll(appName + "__", "") + "_" + ch.task);
+                        if (tmlmodel.getChannelByName(rd.getName()) != null) {
+                            rd.addChannel(tmlmodel.getChannelByName(rd.getName()));
+                        } else if (tmlmodel.getChannelByShortName(rd.getName()) != null) {
+                            rd.addChannel(tmlmodel.getChannelByShortName(rd.getName()));
+                        }
+                        secPatternNonce.originTask = rd.getChannel(0).getOriginTask().getName().replaceAll(appName + "__", "");
+                        rd.securityPattern = secPatternNonce;
+                        rd.setNbOfSamples("1");
+                        if (lastCurElem.getNbNext() > 0) {
+                            lastCurElem.setNewNext(lastCurElem.getNextElement(0), rd);
+                        } else {
+                            lastCurElem.addNext(rd);
+                        }
+                        lastCurElem = rd;
+                        taskAD.addElement(rd);
+                        readNonces.add(secPatternNonce.getName());
                     }
-                    lastCurElem = rd;
-                    taskAD.addElement(rd);
                 }
             }
         }
diff --git a/src/main/java/tmltranslator/toavatarsec/TML2Avatar.java b/src/main/java/tmltranslator/toavatarsec/TML2Avatar.java
index f720f5291f..54912cb5ae 100644
--- a/src/main/java/tmltranslator/toavatarsec/TML2Avatar.java
+++ b/src/main/java/tmltranslator/toavatarsec/TML2Avatar.java
@@ -78,6 +78,7 @@ public class TML2Avatar {
     boolean security = false;
     private TMLMapping<?> tmlmap;
     private TMLModeling<?> tmlmodel;
+    private Set<SecurityPattern> keysPublicBus = new HashSet<SecurityPattern>();
     private Map<SecurityPattern, List<AvatarAttribute>> symKeys = new HashMap<SecurityPattern, List<AvatarAttribute>>();
     private Map<SecurityPattern, List<AvatarAttribute>> pubKeys = new HashMap<SecurityPattern, List<AvatarAttribute>>();
     private Map<String, String> nameMap = new HashMap<String, String>();
@@ -104,6 +105,12 @@ public class TML2Avatar {
         for (TMLTask t1 : tmlmodel.getTasks()) {
             List<SecurityPattern> keys = new ArrayList<SecurityPattern>();
             accessKeys.put(t1, keys);
+            for (HwLink link : links) {
+                if (link.bus.privacy == HwBus.BUS_PUBLIC &&  link.hwnode instanceof HwMemory) {
+                    List<SecurityPattern> patterns = tmlmap.getMappedPatterns((HwMemory) link.hwnode);
+                    keysPublicBus.addAll(patterns);
+                }
+            }
 
             HwExecutionNode node1 = tmlmap.getHwNodeOf(t1);
             //Try to find memory using only private buses from origin
@@ -2071,7 +2078,6 @@ public class TML2Avatar {
 
         }
 
-
         // Add authenticity pragmas
         for (String s : signalAuthOriginMap.keySet()) {
             for (AvatarAttributeState attributeStateOrigin : signalAuthOriginMap.get(s)) {
@@ -2469,7 +2475,20 @@ public class TML2Avatar {
                 for (AvatarAttribute key : symKeys.get(sp)) {
                     keys = keys + " " + key.getBlock().getName() + "." + key.getName();
                 }
-                avspec.addPragma(new AvatarPragmaInitialKnowledge("#InitialSessionKnowledge " + keys, null, symKeys.get(sp), true));
+                avspec.addPragma(new AvatarPragmaInitialKnowledge("#InitialSystemKnowledge " + keys, null, symKeys.get(sp), true));
+            }
+        }
+        
+        for (SecurityPattern sp : keysPublicBus) {
+            for (TMLTask taskPattern : tmlmodel.securityTaskMap.get(sp)) {
+                AvatarBlock b = taskBlockMap.get(taskPattern);
+                AvatarAttribute attrib = b.getAvatarAttributeWithName("key_"+sp.getName());
+                if (attrib!=null) {
+                    LinkedList<AvatarAttribute> arguments = new LinkedList<AvatarAttribute>();
+                    arguments.add(attrib);
+                    avspec.addPragma(new AvatarPragmaPublic("#Public " + b.getName() + "." + attrib.getName(), null, arguments));
+                }
+                
             }
         }
         for (SecurityPattern sp : pubKeys.keySet()) {
-- 
GitLab