diff --git a/src/tmltranslator/HwBridge.java b/src/tmltranslator/HwBridge.java
index 9200e2e17816525792534d793e6c5bad43f92195..3a288d4031b402aa0413b1f5792b80493ef0ceb4 100755
--- a/src/tmltranslator/HwBridge.java
+++ b/src/tmltranslator/HwBridge.java
@@ -53,9 +53,10 @@ public class HwBridge extends HwCommunicationNode  {
 	public static final int DEFAULT_BUFFER_BYTE_DATA_SIZE = 4;
 	
     public int bufferByteSize = DEFAULT_BUFFER_BYTE_DATA_SIZE; // In bytes. Should more than 0
- 
+    public boolean isFirewall;
+    public ArrayList<String> firewallRules = new ArrayList<String>();
     public HwBridge(String _name) {
 		super(_name);
     }
  
-}
\ No newline at end of file
+}
diff --git a/src/tmltranslator/TMLActivity.java b/src/tmltranslator/TMLActivity.java
index d26dae23d12e31526ffc0c08ac7155acfc38f388..f513573b43649c8c7a0416010264441d4404645c 100755
--- a/src/tmltranslator/TMLActivity.java
+++ b/src/tmltranslator/TMLActivity.java
@@ -405,7 +405,9 @@ public class TMLActivity extends TMLElement {
         }
 
     }
-
+    public Vector<TMLActivityElement> getElements(){
+	return elements;
+    }
     public void replaceReadChannelWith(TMLChannel oldChan, TMLChannel newChan) {
 	TMLActivityElement ae;
 
diff --git a/src/tmltranslator/TMLMapping.java b/src/tmltranslator/TMLMapping.java
index 356fedbe1194c5cf0c5ff98b094f84e3510b2d12..1ef9211a0e22aaefe2227e55377928dc83e05717 100755
--- a/src/tmltranslator/TMLMapping.java
+++ b/src/tmltranslator/TMLMapping.java
@@ -62,7 +62,7 @@ public List<String> securityPatterns = new ArrayList<String>();
     private ArrayList<TMLTask> mappedtasks;
     private ArrayList<HwCommunicationNode> oncommnodes;
     public ArrayList<TMLElement> mappedcommelts;
-
+    public boolean firewall = false;
     private ArrayList<TMLCP> mappedCPs;
     private ArrayList<TMLElement> commEltsMappedOnCPs;
     public HashMap<SecurityPattern, ArrayList<HwMemory>> mappedSecurity= new HashMap<SecurityPattern, ArrayList<HwMemory>>(); 
diff --git a/src/tmltranslator/TMLModeling.java b/src/tmltranslator/TMLModeling.java
index 051870a33e76a818c6e125902861e650a7445d62..ed834c9471d1cb102b5aa9dcfb2af0795b4da2a4 100755
--- a/src/tmltranslator/TMLModeling.java
+++ b/src/tmltranslator/TMLModeling.java
@@ -181,7 +181,9 @@ public class TMLModeling {
     public boolean checkConsistency() {
         return true;
     }
-
+    public void removeAllChannels(){
+	channels.clear();
+    }
     public TMLTask findTMLTask(TMLActivityElement _elt) {
         TMLTask tmp;
         for(int i=0; i<tasks.size(); i++) {
diff --git a/src/tmltranslator/toavatar/TML2Avatar.java b/src/tmltranslator/toavatar/TML2Avatar.java
index 1cc43f30ec79352b16c5c18360926ab5a27d6f3d..3b2590394c9004251e59c549aa720c3e5fbaa048 100644
--- a/src/tmltranslator/toavatar/TML2Avatar.java
+++ b/src/tmltranslator/toavatar/TML2Avatar.java
@@ -1063,8 +1063,10 @@ public class TML2Avatar {
 		    if (e instanceof AvatarStopState){
 		    }
 		    else if (e.getNexts().size()==0){
-			e.addNext(as);
-			elementList.add(e);
+			if (e instanceof AvatarTransition){
+			    e.addNext(as);
+			    elementList.add(e);
+			}
 		    }
 		    else if (e.getNext(0) instanceof AvatarStopState){
 			//Remove the transition to AvatarStopState
@@ -1251,17 +1253,21 @@ public class TML2Avatar {
 		request.checkAuth = p.checkAuth || request.checkAuth;
 	    }
 	}
+
 	AvatarBlock top = new AvatarBlock("TOP__TOP", avspec, null);
+	if (mc){
 	avspec.addBlock(top);
 	AvatarStateMachine topasm = top.getStateMachine();
 	AvatarStartState topss = new AvatarStartState("start", null);
 	topasm.setStartState(topss);
 	topasm.addElement(topss);
-	
+	}
 	ArrayList<TMLTask> tasks = tmlmap.getTMLModeling().getTasks();
 	for (TMLTask task:tasks){
 	    AvatarBlock block = new AvatarBlock(task.getName(), avspec, task.getReferenceObject());
+	    if (mc){
 	    block.setFather(top);
+	    }
 	    taskBlockMap.put(task, block);
 	    avspec.addBlock(block);
 	}
diff --git a/src/ui/GTMLModeling.java b/src/ui/GTMLModeling.java
index 9b3b1e8183ea8086d046158a5cffc698a013d967..7c759a58ef59fbbaf49f883409c50010249a3cb2 100755
--- a/src/ui/GTMLModeling.java
+++ b/src/ui/GTMLModeling.java
@@ -2314,6 +2314,7 @@ public class GTMLModeling  {
         TMLArchiBridgeNode bridgenode;
         TMLArchiMemoryNode memorynode;
         TMLArchiDMANode dmanode;
+	TMLArchiFirewallNode firewallnode;
         HwCPU cpu;
         HwA hwa;	
 	HwBus bus;
@@ -2468,6 +2469,28 @@ if (tgc instanceof TMLArchiCrossbarNode) {
                 }
             }
 
+            if (tgc instanceof TMLArchiFirewallNode) {
+                firewallnode = (TMLArchiFirewallNode)tgc;
+                if (nameInUse(names, firewallnode.getName())) {
+                    // Node with the same name
+                    CheckingError ce = new CheckingError(CheckingError.STRUCTURE_ERROR, "Two nodes have the same name: " + firewallnode.getName());
+                    ce.setTDiagramPanel(tmlap.tmlap);
+                    ce.setTGComponent(firewallnode);
+                    checkingErrors.add(ce);
+                } else {
+                    names.add(firewallnode.getName());
+                    bridge = new HwBridge(firewallnode.getName());
+		    bridge.isFirewall=true;
+		    bridge.firewallRules = ((TMLArchiFirewallNode) tgc).getRules();
+                    bridge.bufferByteSize = 1;
+                    bridge.clockRatio = 1;
+                    listE.addCor(bridge, firewallnode);
+                    archi.addHwNode(bridge);
+                    TraceManager.addDev("Bridge node added:" + bridge.getName());
+                }
+            }
+
+
             if (tgc instanceof TMLArchiMemoryNode) {
                 memorynode = (TMLArchiMemoryNode)tgc;
                 if (nameInUse(names, memorynode.getName())) {
@@ -3262,9 +3285,12 @@ if (tgc instanceof TMLArchiCrossbarNode) {
 
             // Other nodes (memory, bridge, bus, VGMN, crossbar)
             //}
-            if ((tgc instanceof TMLArchiBUSNode) ||(tgc instanceof TMLArchiVGMNNode) || (tgc instanceof TMLArchiCrossbarNode) ||(tgc instanceof TMLArchiBridgeNode) || (tgc instanceof TMLArchiMemoryNode)|| (tgc instanceof TMLArchiDMANode)) {
+            if ((tgc instanceof TMLArchiBUSNode) ||(tgc instanceof TMLArchiVGMNNode) || (tgc instanceof TMLArchiCrossbarNode) ||(tgc instanceof TMLArchiBridgeNode) || (tgc instanceof TMLArchiMemoryNode)|| (tgc instanceof TMLArchiDMANode) || (tgc instanceof TMLArchiFirewallNode)) {
                 node = archi.getHwNodeByName(tgc.getName());
                 if ((node != null) && (node instanceof HwCommunicationNode)) {
+		    if (tgc instanceof TMLArchiFirewallNode){
+			map.firewall=true;
+		    }
                     artifactscomm = ((TMLArchiCommunicationNode)(tgc)).getChannelArtifactList();
                     for( TMLArchiCommunicationArtifact artifact:artifactscomm ) {
                         TraceManager.addDev("Exploring artifact " + artifact.getValue());
@@ -3339,8 +3365,151 @@ if (tgc instanceof TMLArchiCrossbarNode) {
             }
 
         }
+	if (map.firewall){
+	    TMLTask firewall = new TMLTask("Firewall", null,null);
+	    HashMap<TMLChannel, TMLChannel> inChans = new HashMap<TMLChannel, TMLChannel>();
+	    HashMap<TMLChannel, TMLChannel> outChans = new HashMap<TMLChannel, TMLChannel>();	
+	    ArrayList<TMLChannel> channelsCopy = tmlm.getChannels();
+	    ArrayList<TMLChannel> toAdd = new ArrayList<TMLChannel>();	
+	//tmlm.removeAllChannels();
+	    for (TMLChannel chan: channelsCopy){
+	    	TMLTask orig = chan.getOriginTask();
+	    	TMLTask dest = chan.getDestinationTask();   
+	    	TMLChannel wr = new TMLChannel(chan.getName()+"_firewallIn",chan.getReferenceObject());
+	    	wr.setTasks(orig, firewall);
+	    	TMLChannel rd = new TMLChannel(chan.getName()+"_firewallOut", chan.getReferenceObject());
+	    	rd.setTasks(firewall,dest);
+	    	inChans.put(chan,wr);
+	    	outChans.put(chan,rd);
+	    	toAdd.add(rd);
+	    	toAdd.add(wr);
+	    }
+	    tmlm.removeAllChannels();
+	    for (TMLChannel c:toAdd){
+	    	tmlm.addChannel(c);
+	    }
+	TMLActivity act = firewall.getActivityDiagram();
+	TMLStartState start = new TMLStartState("start", null);
+	act.setFirst(start);
+	tmlm.addTask(firewall);
+	TMLForLoop loop = new TMLForLoop("infiniteloop",null);
+	loop.setInfinite(true);
+	start.addNext(loop);
+	act.addElement(loop);
+	TMLChoice choice = new TMLChoice("chooseChannel", null);
+	act.addElement(choice);
+	loop.addNext(choice);
+	for (TMLChannel chan: inChans.keySet()){
+	    TMLChannel newChan = inChans.get(chan);
+	    TMLReadChannel rd = new TMLReadChannel(newChan.getName(), chan.getReferenceObject());
+	    rd.setNbOfSamples("1");
+	    rd.addChannel(newChan);
+	    choice.addNext(rd);
+	    choice.addGuard("[]");
+	    act.addElement(rd);
+	    if (channelAllowed(chan)){
+	        TMLChannel wrChan = outChans.get(chan);
+	        TMLWriteChannel wr = new TMLWriteChannel(wrChan.getName(), chan.getReferenceObject());
+	        wr.setNbOfSamples("1");
+	        wr.addChannel(wrChan);
+		rd.addNext(wr);
+		act.addElement(wr);
+	    }
+	    for (TMLTask t:tmlm.getTasks()){
+	        TMLActivity actd = t.getActivityDiagram();
+	        actd.replaceWriteChannelWith(chan,newChan);
+		actd.replaceReadChannelWith(chan, outChans.get(chan));
+	    }
+	}
+	}
+/*	for (TMLActivityElement el:act.getElements()){
+	    System.out.println(el);
+	}*/
+	/*
+	TMLCPrimitiveComponent firewall = new TMLCPrimitiveComponent(0, 0, tmlcdp.tmlctdp.getMinX(), tmlcdp.tmlctdp.getMaxX(), tmlcdp.tmlctdp.getMinY(), tmlcdp.tmlctdp.getMaxY(), false, null, tmlcdp.tmlctdp);
+	firewall.setValueWithChange("Firewall");
+	tmlcdp.tmlctdp.addComponent(firewall,0,0,false,true);
+	TMLActivityDiagramPanel firewallAct = tmlcdp.getTMLActivityDiagramPanel("Firewall");
+	ArrayList<TMLChannel> channelsCopy = tmlm.getTMLChannels();
+	ArrayList<TMLChannel> toAdd = new ArrayList<TMLChannel>();	
+	for (TMLChannel chan: channelsCopy){
+	    TMLTask orig = chan.getOriginTask();
+	    TMLTask dest = chan.getDestinationTask();   
+	}
+	TMLADChoice choice = new TMLADChoice(int _x, int _y, int _minX, int _maxX, int _minY, int _maxY, boolean _pos, null, TDiagramPanel _tdp);
+	firewallAct.addComponent(choice, */
     }
 
+
+    public boolean channelAllowed(TMLChannel chan){
+	TMLTask orig = chan.getOriginTask();
+	TMLTask dest = chan.getDestinationTask();
+	List<HwNode> path = getPath(orig, dest);
+	for (HwNode node:path){
+	    if (node instanceof HwBridge){
+		for (String rule:((HwBridge) node).firewallRules){
+		    String t1 = rule.split("->")[0];
+		    String t2 = rule.split("->")[1];
+		    if (t1.equals(orig.getName().replaceAll("__","::")) && t2.equals(dest.getName().replaceAll("__","::"))){
+			return false;
+		    }
+		}
+	    }
+	}
+	return true;
+    }
+    public List<HwNode> getPath(TMLTask t1, TMLTask t2){
+	HwNode node1 = map.getHwNodeOf(t1);
+	HwNode node2 = map.getHwNodeOf(t2);
+	List<HwNode> path = new ArrayList<HwNode>();
+	if (node1==node2){
+	    return path;
+	}
+	if (node1!=node2){
+	    //Navigate architecture for node
+	    List<HwLink> links = map.getTMLArchitecture().getHwLinks();
+	    HwNode last = node1;
+	    List<HwNode> found = new ArrayList<HwNode>();	
+	    List<HwNode> done = new ArrayList<HwNode>();
+	    Map<HwNode, List<HwNode>> pathMap = new HashMap<HwNode, List<HwNode>>();
+	    for (HwLink link: links){
+		if (link.hwnode == node1){
+		    found.add(link.bus);
+		    List<HwNode> tmp = new ArrayList<HwNode>();
+		    tmp.add(link.bus);
+		    pathMap.put(link.bus, tmp);
+		}
+	    }
+	    outerloop:
+	    while (found.size()>0){
+		HwNode curr = found.remove(0);
+		for (HwLink link: links){
+		    if (curr == link.bus){
+		        if (link.hwnode == node2){
+		      	    path = pathMap.get(curr);
+		      	    break outerloop;
+		    	}
+		    	if (!done.contains(link.hwnode) && !found.contains(link.hwnode) && link.hwnode instanceof HwBridge){
+		      	    found.add(link.hwnode);
+		      	    List<HwNode> tmp = new ArrayList<HwNode>(pathMap.get(curr));
+		      	    tmp.add(link.hwnode);
+		      	    pathMap.put(link.hwnode, tmp);
+		    	}
+		    }
+		    else if (curr == link.hwnode){
+		    	if (!done.contains(link.bus) && !found.contains(link.bus)){
+		            found.add(link.bus);
+		            List<HwNode> tmp = new ArrayList<HwNode>(pathMap.get(curr));
+		            tmp.add(link.bus);
+		       	    pathMap.put(link.bus, tmp);
+	      	        }
+	  	    }
+	        }
+	    done.add(curr);
+	    }
+	}
+	return path;
+    }
     public void addToTable(String s1, String s2) {
         //TraceManager.addDev("Adding to Table s1= "+ s1 + " s2=" + s2);
         table.put(s1, s2);
diff --git a/src/ui/GTURTLEModeling.java b/src/ui/GTURTLEModeling.java
index da012c95c8757c2aaa4fcff9acb42f23fba24c7f..89e28f10fdb1a34d09b1060168956e6886f7ebfb 100755
--- a/src/ui/GTURTLEModeling.java
+++ b/src/ui/GTURTLEModeling.java
@@ -7795,6 +7795,7 @@ public class GTURTLEModeling {
 		father = blockMap.get(ab.getFather().getName().split("__")[1]);
 	    }
 	    AvatarBDBlock bl = new AvatarBDBlock(xpos, ypos, xpos, xpos*2, ypos, ypos*2, false, father, abd);
+	    bl.addCryptoElements();
 	    tranSourceMap.clear();
 /*	    if (ab.getName().contains("__")){
 	        bl.setValue(ab.getName().split("__")[1]);
diff --git a/src/ui/tmldd/TMLArchiFirewallNode.java b/src/ui/tmldd/TMLArchiFirewallNode.java
index cd534ab2dfef43b5edf60c0ada7b69372d0a3988..caa741a3cd573512f95f063d431446402bd38db1 100644
--- a/src/ui/tmldd/TMLArchiFirewallNode.java
+++ b/src/ui/tmldd/TMLArchiFirewallNode.java
@@ -64,7 +64,7 @@ public class TMLArchiFirewallNode extends TMLArchiCommunicationNode implements S
     private int derivationx = 2;
     private int derivationy = 3;
     private String stereotype = "FIREWALL";
-	
+    private ArrayList<String> rules = new ArrayList<String>();
 	private int latency = 0;
     
     public TMLArchiFirewallNode(int _x, int _y, int _minX, int _maxX, int _minY, int _maxY, boolean _pos, TGComponent _father, TDiagramPanel _tdp)  {
@@ -193,7 +193,7 @@ public class TMLArchiFirewallNode extends TMLArchiCommunicationNode implements S
 			 }
 		}
 		
-		
+		rules = dialog.getRules();
 		
 		if (error) {
 			JOptionPane.showMessageDialog(frame,
@@ -215,8 +215,12 @@ public class TMLArchiFirewallNode extends TMLArchiCommunicationNode implements S
         StringBuffer sb = new StringBuffer("<extraparam>\n");
         sb.append("<info stereotype=\"" + stereotype + "\" nodeName=\"" + name);
         sb.append("\" />\n");
-		sb.append("<attributes latency=\"" + latency + "\" ");
+	sb.append("<attributes latency=\"" + latency + "\" ");
+        sb.append("/>\n");
+	for (String rule:rules){
+	sb.append("<rule value=\"" + rule + "\" ");
         sb.append("/>\n");
+	}
         sb.append("</extraparam>\n");
         return new String(sb);
     }
@@ -258,6 +262,9 @@ public class TMLArchiFirewallNode extends TMLArchiCommunicationNode implements S
 									clockRatio = Integer.decode(elt.getAttribute("clockRatio")).intValue();
 								}
                             }
+			    if (elt.getTagName().equals("rule")){
+				rules.add(elt.getAttribute("value"));
+			    }
                         }
                     }
                 }
@@ -272,7 +279,10 @@ public class TMLArchiFirewallNode extends TMLArchiCommunicationNode implements S
 	  public int getLatency(){
 		  return latency;
 	  }
-	  
+	public ArrayList<String> getRules(){
+	    System.out.println("FIREWALL rules " + rules);
+	    return rules;
+	}
 	  public String getAttributes() {
 		  String attr = "";
 		  attr += "Latency = " + latency + "\n";
diff --git a/src/ui/window/JDialogFirewallNode.java b/src/ui/window/JDialogFirewallNode.java
index 7b19a6fb1355f0623b82c6badca1102106f6d107..138518a7a462a756990732d44c8a6e65ad22654a 100644
--- a/src/ui/window/JDialogFirewallNode.java
+++ b/src/ui/window/JDialogFirewallNode.java
@@ -137,7 +137,10 @@ public class JDialogFirewallNode extends javax.swing.JDialog implements ActionLi
         c2.weighty = 1.0;
         c2.weightx = 1.0;
         c2.fill = GridBagConstraints.HORIZONTAL;
-	JLabel rulesLabel = new JLabel("Rules");
+	for (String s: node.getRules()){
+	    rules.add(s);
+	}
+	JLabel rulesLabel = new JLabel("Blocking Rules");
 	panel2.add(rulesLabel, c2);
 
 	listRules = new JList<String>(rules);
@@ -145,12 +148,16 @@ public class JDialogFirewallNode extends javax.swing.JDialog implements ActionLi
         listRules.addListSelectionListener(this);
 	JScrollPane scrollPane = new JScrollPane(listRules);
         scrollPane.setSize(500, 250);
-        c2.gridwidth = 1; //end row
+        c2.gridwidth = GridBagConstraints.REMAINDER; //end row
         c2.fill = GridBagConstraints.BOTH;
-        c2.gridheight = 5;
+        c2.gridheight = 10;
         c2.weighty = 10.0;
         c2.weightx = 10.0;
         panel2.add(scrollPane, c2);
+	c2.gridheight=1;
+	c2.gridwidth=1;
+        c2.weighty = 1.0;
+        c2.weightx = 1.0;
 	task1 = new JComboBox();
 	for (String task: node.getTDiagramPanel().getMGUI().getTMLTasks()){
 	    task1.addItem(task);
@@ -258,5 +265,11 @@ public class JDialogFirewallNode extends javax.swing.JDialog implements ActionLi
     public String getLatency() {
         return latency.getText();
     }
-	
+    public ArrayList<String> getRules(){
+	ArrayList<String> r = new ArrayList<String>();
+	for (int i=0; i<rules.size(); i++){
+	    r.add((String) rules.get(i));
+	}
+	return r;
+    }
 }