diff --git a/Makefile b/Makefile
index 9bf877edfdf7350423e4651aed13c4eef20f51f4..12bce183b7147bd7ad041e10cd7f6d5376a395ae 100755
--- a/Makefile
+++ b/Makefile
@@ -53,6 +53,7 @@ TTOOL_MODELING = $(TTOOL_PATH)/modeling
 TTOOL_SIMULATORS = $(TTOOL_PATH)/simulators
 TTOOL_DOC = $(TTOOL_PATH)/doc
 TTOOL_DOC_HTML = $(TTOOL_PATH)/doc/html
+TTOOL_VCD = $(TTOOL_PATH)/vcd
 TTOOL_WORD = $(TTOOL_PATH)/doc/word
 TTOOL_STD_RELEASE = $(TTOOL_PATH)/release/
 JTTOOL = $(TTOOL_PATH)/javacode
@@ -151,6 +152,9 @@ stdrelease:
 # Figure
 	mkdir -p $(TTOOL_TARGET)/figure
 	cp $(TTOOL_DOC)/README_figure $(TTOOL_TARGET)/figure
+# VCD
+	mkdir -p $(TTOOL_TARGET)/vcd
+	cp $(TTOOL_DOC)/README_vcd $(TTOOL_TARGET)/vcd
 # Basic doc
 	mkdir -p $(TTOOL_TARGET)/doc
 	cp $(TTOOL_DOC)/README_doc $(TTOOL_TARGET)/doc
diff --git a/bin/config.xml b/bin/config.xml
index 5530a2d8048ae31020bdd1d2f8b580db445e6d98..cf368c0e086879fcfcefe5ee2243c20b3c4aa2df 100755
--- a/bin/config.xml
+++ b/bin/config.xml
@@ -41,6 +41,7 @@
 <SystemCCodeExecuteCommand data="/Users/ludovicapvrille/TTool/simulators/c++2/run.x -ovcd /Users/ludovicapvrille/TTool/simulators/c++2/vcddump.vcd" />
 <TMLCodeDirectory data="/Users/ludovicapvrille/TTool/tmlcode" />
 <GTKWavePath data="/opt/local/bin/gtkwave" />
+<VCDPath data="/Users/ludovicapvrille/TTool/vcd" />
 <UPPAALCodeDirectory data="/Users/ludovicapvrille/TTool/uppaal/" />
 <UPPAALVerifierPath data="/Applications/uppaal-4.0.7-aca/verifyta" />
 <UPPAALVerifierHost data="localhost" />
diff --git a/src/sddescription/MalformedSDException.java b/src/sddescription/MalformedSDException.java
new file mode 100755
index 0000000000000000000000000000000000000000..d1de45e8f196ec6e0cae65745825cf17e9081e90
--- /dev/null
+++ b/src/sddescription/MalformedSDException.java
@@ -0,0 +1,61 @@
+/**Copyright or (C) or Copr. GET / ENST, Telecom-Paris, Ludovic Apvrille
+
+ludovic.apvrille AT enst.fr
+
+This software is a computer program whose purpose is to allow the 
+edition of TURTLE analysis, design and deployment diagrams, to 
+allow the generation of RT-LOTOS or Java code from this diagram, 
+and at last to allow the analysis of formal validation traces 
+obtained from external tools, e.g. RTL from LAAS-CNRS and CADP 
+from INRIA Rhone-Alpes.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+
+/**
+ * Class MalformedSDException
+ * Creation: 17/07/2009
+ * version 1.0 17/07/2009
+ * @author Ludovic APVRILLE
+ * @see 
+ */
+
+package sddescription;
+
+
+public	class MalformedSDException extends Exception {
+	
+	public MalformedSDException() {
+		super("SD Exception");
+	}
+	
+	public MalformedSDException(String msg) {
+		super("SD Exception: " + msg);
+	}
+    
+} // Class 
+
+	
\ No newline at end of file
diff --git a/src/sddescription/SDExchange.java b/src/sddescription/SDExchange.java
new file mode 100755
index 0000000000000000000000000000000000000000..61ebe90684236a49327cb28451f1e7f09bde289b
--- /dev/null
+++ b/src/sddescription/SDExchange.java
@@ -0,0 +1,610 @@
+/**Copyright or (C) or Copr. GET / ENST, Telecom-Paris, Ludovic Apvrille
+*
+* ludovic.apvrille AT enst.fr
+*
+* This software is a computer program whose purpose is to allow the
+* edition of TURTLE analysis, design and deployment diagrams, to
+* allow the generation of RT-LOTOS or Java code from this diagram,
+* and at last to allow the analysis of formal validation traces
+* obtained from external tools, e.g. RTL from LAAS-CNRS and CADP
+* from INRIA Rhone-Alpes.
+*
+* This software is governed by the CeCILL  license under French law and
+* abiding by the rules of distribution of free software.  You can  use,
+* modify and/ or redistribute the software under the terms of the CeCILL
+* license as circulated by CEA, CNRS and INRIA at the following URL
+* "http://www.cecill.info".
+*
+* As a counterpart to the access to the source code and  rights to copy,
+* modify and redistribute granted by the license, users are provided only
+* with a limited warranty  and the software's author,  the holder of the
+* economic rights,  and the successive licensors  have only  limited
+* liability.
+*
+* In this respect, the user's attention is drawn to the risks associated
+* with loading,  using,  modifying and/or developing or reproducing the
+* software by the user in light of its specific status of free software,
+* that may mean  that it is complicated to manipulate,  and  that  also
+* therefore means  that it is reserved for developers  and  experienced
+* professionals having in-depth computer knowledge. Users are therefore
+* encouraged to load and test the software's suitability as regards their
+* requirements in conditions enabling the security of their systems and/or
+* data to be ensured and,  more generally, to use and operate it in the
+* same conditions as regards security.
+*
+* The fact that you are presently reading this means that you have had
+* knowledge of the CeCILL license and that you accept its terms.
+*
+* /**
+* Class SDExchange
+* Creation: 17/07/2009
+* @version 1.0 17/07/2009
+* @author Ludovic APVRILLE
+* @see
+*/
+
+package sddescription;
+
+import java.io.*;
+import java.util.*;
+import org.w3c.dom.*;
+import org.xml.sax.*;
+import javax.xml.parsers.*;
+
+import myutil.*;
+
+public class SDExchange {
+	private MSC msc;
+	
+	private String XML_SD_HEADER = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>";
+	private String XML_SD_TOP = "MSC";
+	private String XML_SD_INSTANCE = "INSTANCE";
+	private String XML_SD_EVENT = "EVENT";
+	private String XML_SD_EVENT_LINK = "EVENT_LINK";
+	private String XML_SD_NL = "\n";
+	
+	
+	public void SDExchange() {
+	}
+	
+	
+	public MSC getMSC() {
+		return msc;
+	}
+	
+	/*public String saveInXMLSD() {
+		if (tm == null) {
+			return "";
+		}
+		
+		StringBuffer sb = new StringBuffer(XML_TIF_HEADER + XML_TIF_NL + XML_TIF_NL);
+		sb.append("<" + XML_TIF_TOP + ">" + XML_TIF_NL);
+		sb.append(saveClassesInXMLTIF());
+		sb.append(saveRelationsInXMLTIF());
+		sb.append("</" + XML_TIF_TOP + ">" + XML_TIF_NL);
+		return sb.toString();
+	}*/
+	
+	public boolean loadFromXMLSD(String xml) throws MalformedSDException{
+		DocumentBuilderFactory dbf;
+		DocumentBuilder db;
+		
+		try {
+			dbf = DocumentBuilderFactory.newInstance();
+			db = dbf.newDocumentBuilder();
+		} catch (ParserConfigurationException e) {
+			dbf = null;
+			db = null;
+		}
+		
+		if ((dbf == null) || (db == null)) {
+			throw new MalformedSDException();
+		}
+		
+		ByteArrayInputStream bais = new ByteArrayInputStream(decodeString(xml).getBytes());
+		int i;
+		msc = new MSC("msc");
+		
+		/*try {
+			// building nodes from xml String
+			Document doc = db.parse(bais);
+			NodeList nl;
+			Node node;
+			
+			nl = doc.getElementsByTagName(XML_TIF_CLASS);
+			
+			if (nl == null) {
+				return false;
+			}
+			
+			for(i=0; i<nl.getLength(); i++) {
+				node = nl.item(i);
+				//System.out.println("Node = " + dnd);
+				if (node.getNodeType() == Node.ELEMENT_NODE) {
+					// create design, and get an index for it
+					loadTClass(node);
+				}
+			}
+			
+			nl = doc.getElementsByTagName(XML_TIF_RELATION);
+			
+			for(i=0; i<nl.getLength(); i++) {
+				node = nl.item(i);
+				//System.out.println("Node = " + dnd);
+				if (node.getNodeType() == Node.ELEMENT_NODE) {
+					// create design, and get an index for it
+					loadRelation(node);
+				}
+			}
+			
+		} catch (IOException e) {
+			System.out.println("500 ");
+			throw new MalformedTIFException();
+		} catch (SAXException saxe) {
+			System.out.println("501 " + saxe.getMessage());
+			throw new MalformedTIFException();
+		}*/
+		return true;
+	}
+
+	/*public String saveClassesInXMLTIF() {
+		StringBuffer sb = new StringBuffer("");
+		for(int i=0; i<tm.classNb(); i++ ){
+			sb.append(saveClassInXMLTIF(tm.getTClassAtIndex(i)));
+		}
+		return sb.toString();
+	}
+	
+	public String saveClassInXMLTIF(TClass t) {
+		int i;
+		Param p;
+		Gate g;
+		StringBuffer sb = new StringBuffer("");
+		
+		sb.append("<" + XML_TIF_CLASS + ">" + XML_TIF_NL);
+		
+		sb.append("<name data=\"" + t.getName() + "\" />" + XML_TIF_NL);
+		sb.append("<active data=\"" + t.isActive() + "\" />" + XML_TIF_NL);
+		sb.append("<type data=\"" + t.getClass().getCanonicalName() + "\" />" + XML_TIF_NL);
+		
+		// Params
+		for(i=0; i<t.paramNb(); i++) {
+			p = (Param)(t.getParamList().get(i));
+			sb.append(saveParamInXMLTIF(p));
+		}
+		
+		// Gates
+		for(i=0; i<t.gateNb(); i++) {
+			g = (Gate)(t.getGateList().get(i));
+			sb.append(saveGateInXMLTIF(g));
+		}
+		
+		// Activity Diagram
+		sb.append(saveActivityDiagramInTIF(t.getActivityDiagram()));
+		
+		sb.append("</" + XML_TIF_CLASS + ">" + XML_TIF_NL);
+		return sb.toString();
+	}*/
+	
+	/*public void loadTClass(Node node1) throws MalformedTIFException{
+		NodeList diagramNl = node1.getChildNodes();
+		Element elt;
+		Node node;
+		
+		String name="", classname="";
+		String tmp;
+		boolean active = false;
+		String attname, attvalue, atttype, attaccess;
+		String gname, gtype, ginternal, gprotocoljava, glocalportjava, gdestportjava, gdesthostjava, glocalhostjava;
+		boolean gbinternal;
+		int gitype;
+		Param p;
+		Gate g;
+		
+		ArrayList<Param> params = new ArrayList<Param>();
+		ArrayList<Gate> gates = new ArrayList<Gate>();
+		
+		try {
+			// Gather all informations
+			for(int j=0; j<diagramNl.getLength(); j++) {
+				//System.out.println("Ndes: " + j);
+				node = diagramNl.item(j);
+				if (node.getNodeType() == Node.ELEMENT_NODE) {
+					elt = (Element)node;
+					if (elt.getTagName().compareTo("name") == 0) {
+						name = elt.getAttribute("data");
+					} else if (elt.getTagName().compareTo("active") == 0) { 
+						tmp = elt.getAttribute("data");
+						active = false;
+						if (tmp.compareTo("true") == 0) {
+							active = true;
+						} 
+					} else if (elt.getTagName().compareTo("type") == 0) { 
+						classname = elt.getAttribute("data");
+						
+					// Attributes	
+					} else if (elt.getTagName().compareTo("attribute") == 0) { 
+						attname = elt.getAttribute("name");
+						atttype = elt.getAttribute("type");
+						attvalue = elt.getAttribute("value");
+						attaccess = elt.getAttribute("access");
+						p = new Param(attname, atttype, attvalue);
+						p.setAccess(attaccess);
+						params.add(p);
+						
+					// Gates	
+					} else if (elt.getTagName().compareTo("gate") == 0) { 
+						gname = elt.getAttribute("name");
+						gtype = elt.getAttribute("type");
+						ginternal = elt.getAttribute("internal");
+						gprotocoljava = elt.getAttribute("protocoljava");
+						glocalportjava = elt.getAttribute("localportjava");
+						gdestportjava = elt.getAttribute("destportjava");
+						gdesthostjava = elt.getAttribute("desthostjava");
+						glocalhostjava = elt.getAttribute("localhostjava");
+						
+						if (ginternal.compareTo("true") == 0) {
+							gbinternal = true;
+						} else {
+							gbinternal = false;
+						}
+						
+						gitype = Integer.decode(gtype).intValue();
+						g = new Gate(gname, gitype, gbinternal);
+						g.setProtocolJava(Integer.decode(gprotocoljava).intValue());
+						g.setLocalPortJava(Integer.decode(glocalportjava).intValue());
+						g.setDestPortJava(Integer.decode(gdestportjava).intValue());
+						g.setDestHostJava(gdesthostjava);
+						g.setLocalHostJava(glocalhostjava);
+						gates.add(g);
+						
+					} 
+				}
+			}
+		} catch (Exception e) {
+			System.out.println("Exception " + e.getMessage());
+			throw new MalformedTIFException();
+		}
+		
+		// Create the tclass
+		//System.out.println("TClass name=" + name);
+		
+		// WARNING: must handle special TClasses
+		TClass t = new TClass(name, active);
+		ActivityDiagram ad = new ActivityDiagram();
+		t.setActivityDiagram(ad);
+		
+		for(Param pa: params) {
+			t.addParameter(pa);
+		}
+		for(Gate ga: gates) {
+			//System.out.println("adding gate:" + ga.getName());
+			t.addGate(ga);
+		}
+		
+		makeADComponents(t, node1);
+		
+		//t.printParams();
+		tm.addTClass(t);
+		
+	}*/
+	
+	/*public void makeADComponents(TClass t, Node node) throws MalformedTIFException {
+		NodeList diagramNl = node.getChildNodes();
+		Element elt;
+		
+		int i, j;
+		
+		ADComponent adc, tmp;
+		ADActionStateWithGate adag;
+		ADActionStateWithMultipleParam admp;
+		ADActionStateWithParam adpa;
+		ADChoice adch;
+		ADDelay addelay;
+		ADLatency adlatency;
+		ADParallel adp;
+		ADTimeInterval adti;
+		ADTLO adtlo;
+		
+		ArrayList<ADComponent> adcomponents = new ArrayList<ADComponent>();
+		ArrayList<String> ids = new ArrayList<String>();
+		
+		//System.out.println("Node1 = " + node);
+		ActivityDiagram ad = t.getActivityDiagram();
+		
+		try {
+			// Create all components
+			for(j=0; j<diagramNl.getLength(); j++) {
+				node = diagramNl.item(j);
+				//System.out.println("Node=" + node);
+				if (node.getNodeType() == Node.ELEMENT_NODE) {
+					elt = (Element)node;
+					if (elt.getTagName().compareTo("adcomponent") == 0) {
+						makeADComponent(t, adcomponents, ids, node);
+					}
+				}
+			}
+			
+			// Make links between components
+			//System.out.println("Making links");
+			for(i=0; i<ad.size(); i++) {
+				adc = ad.getADComponent(i);
+				//System.out.println("ADC=" + adc + " i=" + i + " size= " + ad.size());
+				for(j=0; j<adc.getNbNext(); j++) {
+					//System.out.println("nb next=" + adc.getNbNext() + " j=" + j);
+					tmp = findRealComponent(adc.getNext(j), adcomponents, ids);
+					if (tmp == null) {
+						throw new MalformedTIFException("NULL next: " + adc);
+					}
+					adc.setNextAtIndex(tmp, j);
+				}
+			}
+			
+		} catch (Exception e) {
+			System.out.println("Exception " + e.getMessage());
+			throw new MalformedTIFException();
+		}
+	}
+	
+	public ADComponent findRealComponent(ADComponent adc, ArrayList<ADComponent> adcomponents, ArrayList<String> ids) {
+		if (!(adc instanceof ADEmpty)) {
+			return null;
+		}
+		
+		ADEmpty ade = (ADEmpty)adc;
+		String id;
+		
+		for(int i=0; i<ids.size(); i++) {
+			id = ids.get(i);
+			if (id.equals(ade.id)) {
+				return adcomponents.get(i);
+			}
+		}
+		return null;
+	}
+	
+	public void makeADComponent(TClass t, ArrayList<ADComponent> adcomponents, ArrayList<String> ids, Node node) throws MalformedTIFException {
+		NodeList diagramNl = node.getChildNodes();
+		Element elt;
+		
+		ADComponent adc = null, tmp;
+		ADActionStateWithGate adag;
+		ADActionStateWithMultipleParam admp;
+		ADActionStateWithParam adpa;
+		ADChoice adch;
+		ADDelay addelay;
+		ADLatency adlatency;
+		ADParallel adp;
+		ADTimeInterval adti;
+		ADTLO adtlo;
+		ADEmpty ade;
+		
+		String type, id = null;
+		String nextid, gate, action, limit, param, guard, minvalue, maxvalue;
+		Gate g;
+		Param p;
+		
+		ActivityDiagram ad = t.getActivityDiagram();
+		
+		//System.out.println("Making adcomponents");
+		
+		try {
+			for(int j=0; j<diagramNl.getLength(); j++) {
+				node = diagramNl.item(j);
+				if (node.getNodeType() == Node.ELEMENT_NODE) {
+					elt = (Element)node;
+					if (elt.getTagName().compareTo("common") == 0) {
+						type = elt.getAttribute("type");
+						//System.out.println("Found a component type = " + type);
+						id = elt.getAttribute("id");
+						adc = newADComponent(type);
+						ad.add(adc);
+					} else if (elt.getTagName().compareTo("next") == 0) {
+						if (adc != null) {
+							ade = new ADEmpty();
+							ade.id = elt.getAttribute("id");
+							adc.addNext(ade);
+						} else {
+							throw new MalformedTIFException("NULL ADC");
+						}
+					} else if (elt.getTagName().compareTo("specific") == 0) {
+						if (adc == null) {
+							throw new MalformedTIFException("NULL ADC");
+						}
+						
+						if (adc instanceof ADActionStateWithGate) {
+							gate = elt.getAttribute("gate");
+							action = elt.getAttribute("actionvalue");
+							limit = elt.getAttribute("limitongate");
+							adag = (ADActionStateWithGate)adc;
+							adag.setActionValue(action);
+							adag.setLimitOnGate(limit);
+							g = t.getGateByName(gate);
+							if (g == null) {
+								throw new MalformedTIFException("NULL Gate: " + gate);
+							}
+							adag.setGate(g);
+							
+						} else if (adc instanceof ADActionStateWithMultipleParam) {
+							admp = (ADActionStateWithMultipleParam)adc;
+							action = elt.getAttribute("actionvalue");
+							admp.setActionValue(action);
+							
+						} else if (adc instanceof ADActionStateWithParam) {
+							action = elt.getAttribute("actionvalue");
+							param = elt.getAttribute("param");
+							adpa = (ADActionStateWithParam)adc;
+							p = t.getParamByName(param);
+							if (p == null) {
+								throw new MalformedTIFException("NULL Param: " + param);
+							}
+							adpa.setParam(p);
+							adpa.setActionValue(action);
+							
+						} else if (adc instanceof ADChoice) {
+							adch = (ADChoice)adc;
+							guard = elt.getAttribute("guard");
+							adch.addGuard(guard);
+							
+						} else if (adc instanceof ADDelay) {
+							addelay = (ADDelay)adc;
+							action = elt.getAttribute("actionvalue");
+							addelay.setValue(action);
+							
+						} else if (adc instanceof ADLatency) {
+							adlatency = (ADLatency)adc;
+							action = elt.getAttribute("actionvalue");
+							adlatency.setValue(action);
+							
+						} else if (adc instanceof ADParallel) {
+							adp = (ADParallel)adc;
+							action = elt.getAttribute("valuegate");
+							adp.setValueGate(action);
+							
+						} else if (adc instanceof ADStart) {
+							ad.setStartState((ADStart)adc);
+							
+						} else if (adc instanceof ADTimeInterval) {
+							adti = (ADTimeInterval)adc;
+							minvalue = elt.getAttribute("minvalue");
+							maxvalue = elt.getAttribute("maxvalue");
+							adti.setValue(minvalue, maxvalue);
+							
+						} else if (adc instanceof ADTLO) {
+							adtlo = (ADTLO)adc;
+							action = elt.getAttribute("action");
+							minvalue = elt.getAttribute("latency");
+							maxvalue = elt.getAttribute("delay");
+							gate = elt.getAttribute("gate");
+							
+							g = t.getGateByName(gate);
+							if (g == null) {
+								throw new MalformedTIFException("NULL Gate");
+							}
+							adtlo.setGate(g);
+							adtlo.setLatency(minvalue);
+							adtlo.setDelay(maxvalue);
+							adtlo.setAction(action);
+							
+						}
+					}
+					
+				}
+			}
+			
+		} catch (Exception e) {
+			System.out.println("Exception " + e.getMessage());
+			throw new MalformedTIFException();
+		}
+		
+		if ((adc != null) && (id != null)) {
+			adcomponents.add(adc);
+			ids.add(id);
+		}
+	}
+	
+	public ADComponent newADComponent(String type) {
+		//System.out.println("New ADComponent. Type= " + type);
+		try {
+			ClassLoader cl = ClassLoader.getSystemClassLoader();
+			//System.out.println("1");
+			Class c = cl.loadClass(type);
+			//System.out.println("2");
+			return (ADComponent)(c.newInstance());
+		} catch (Exception e) {
+			System.out.println("Could not create an instance if " + type + " because " + e.getMessage()); 
+		}
+		return null;
+	}
+	
+	
+	public void loadRelation(Node node1) throws MalformedTIFException {
+		NodeList diagramNl = node1.getChildNodes();
+		Element elt;
+		Node node;
+		
+		String t1name, t2name, navigation;
+		boolean nav;
+		int type;
+		String name1, name2;
+		Gate g1, g2;
+		TClass t1=null, t2=null;
+		Relation r=null;
+		
+		try {
+			// Gather all informations
+			for(int j=0; j<diagramNl.getLength(); j++) {
+				node = diagramNl.item(j);
+				if (node.getNodeType() == Node.ELEMENT_NODE) {
+					elt = (Element)node;
+					if (elt.getTagName().compareTo("info") == 0) {
+						type = Integer.decode(elt.getAttribute("type")).intValue();
+						t1name = elt.getAttribute("t1name");  
+						t2name = elt.getAttribute("t2name");
+						navigation = elt.getAttribute("navigation");
+						
+						t1 = tm.getTClassWithName(t1name);
+						t2 = tm.getTClassWithName(t2name);
+						
+						if (t1 == null) {
+							throw new MalformedTIFException("NULL class: " + t1name);
+						}
+						
+						if (t2 == null) {
+							throw new MalformedTIFException("NULL class: " + t2name);
+						}
+						
+						nav = navigation.equals("true");
+						r = new Relation(type, t1, t2, nav);
+						tm.addRelation(r);
+						
+					} else if (elt.getTagName().compareTo("gates") == 0) {
+						name1 = elt.getAttribute("name1");  
+						name2 = elt.getAttribute("name2");
+						g1 = t1.getGateByName(name1);
+						g2 = t2.getGateByName(name2);
+						
+						if (g1 == null) {
+							throw new MalformedTIFException("NULL gate: " + name1);
+						}
+						
+						if (g2 == null) {
+							throw new MalformedTIFException("NULL gate: " + name2);
+						}
+						
+						r.addGates(g1, g2);
+					}
+				}
+			}
+		} catch (Exception e) {
+			System.out.println("Exception " + e.getMessage());
+			throw new MalformedTIFException();
+		}
+	}*/
+	
+	public static String transformString(String s) {
+		if (s != null) {
+			s = Conversion.replaceAllChar(s, '&', "&amp;");
+			s = Conversion.replaceAllChar(s, '<', "&lt;");
+			s = Conversion.replaceAllChar(s, '>', "&gt;");
+			s = Conversion.replaceAllChar(s, '"', "&quot;");
+			s = Conversion.replaceAllChar(s, '\'', "&apos;");
+		}
+		return s;
+	}
+	
+	public static String decodeString(String s) throws MalformedSDException {
+		if (s == null)
+			return s;
+		byte b[] = null;
+		try {
+			b = s.getBytes("ISO-8859-1");
+			return new String(b);
+		} catch (Exception e) {
+			throw new MalformedSDException();
+		}
+	}
+	
+	
+  
+}
diff --git a/src/ui/GTURTLEModeling.java b/src/ui/GTURTLEModeling.java
index 5d4c7222511120c528e998d642f35c95808e80ce..0550919542393451d4cd7be62b284d56f7f01caa 100755
--- a/src/ui/GTURTLEModeling.java
+++ b/src/ui/GTURTLEModeling.java
@@ -137,6 +137,7 @@ public class GTURTLEModeling {
 
 	private int nbRTLOTOS;
 	private int nbSuggestedDesign;
+	private int nbSuggestedAnalysis;
 	private int nbTPN;
 
 	private ValidationDataTree vdt;
@@ -235,6 +236,24 @@ public class GTURTLEModeling {
 		return ret;
 	}
 	
+	public boolean openSD(String s) {
+		SDExchange sde = new SDExchange();
+		boolean ret = false;
+		
+		try {
+			ret = sde.loadFromXMLSD(s);
+			if (ret) {
+				//tm = tif.getTURTLEModeling();
+				//tmState = 0;
+				System.out.println("Got SD");
+				generateIOD(sde.getMSC());
+			}
+		} catch (Exception e) {
+			System.out.println("Exception on SD: " + e.getMessage());
+		}
+		return ret;
+	}
+	
 	public void mergeChoices(boolean nonDeterministic) {
 		if (tm != null) {
 			tm.mergeChoices(nonDeterministic);
@@ -4268,6 +4287,14 @@ public class GTURTLEModeling {
 		mgui.changeMade(null, -1);
 	}
 	
+	public void generateIOD(MSC _msc) {
+		MSCDrawer mscd = new MSCDrawer(mgui);
+		mscd.setMSC(_msc);
+		mscd.draw(nbSuggestedDesign);
+		nbSuggestedDesign ++;
+		mgui.changeMade(null, -1);
+	}
+	
 
 	public boolean translateDeployment(DeploymentPanel dp) {
 		// Builds a TURTLE modeling from a deployment diagram
diff --git a/src/ui/JMenuBarTurtle.java b/src/ui/JMenuBarTurtle.java
index ab0c497d92bde5e9de98a5bac8cd1776531783e6..7a5883430c52485116513f9d8ccb272a54a8e586 100755
--- a/src/ui/JMenuBarTurtle.java
+++ b/src/ui/JMenuBarTurtle.java
@@ -113,6 +113,11 @@ public	class JMenuBarTurtle extends JMenuBar	{
         menuItem.addMouseListener(mgui.mouseHandler);
 		
 		file.addSeparator();
+		
+		menuItem = file.add(mgui.actions[TGUIAction.ACT_OPEN_SD]);
+        menuItem.addMouseListener(mgui.mouseHandler);
+		
+		file.addSeparator();
         
         menuItem = file.add(mgui.actions[TGUIAction.ACT_SAVE_LOTOS]);
         menuItem.addMouseListener(mgui.mouseHandler);
diff --git a/src/ui/MSCDrawer.java b/src/ui/MSCDrawer.java
new file mode 100755
index 0000000000000000000000000000000000000000..2eedc82f9e34602afb052ececdfe893a28022f55
--- /dev/null
+++ b/src/ui/MSCDrawer.java
@@ -0,0 +1,720 @@
+/**Copyright or (C) or Copr. GET / ENST, Telecom-Paris, Ludovic Apvrille
+ *
+ * ludovic.apvrille AT enst.fr
+ *
+ * This software is a computer program whose purpose is to allow the
+ * edition of TURTLE analysis, design and deployment diagrams, to
+ * allow the generation of RT-LOTOS or Java code from this diagram,
+ * and at last to allow the analysis of formal validation traces
+ * obtained from external tools, e.g. RTL from LAAS-CNRS and CADP
+ * from INRIA Rhone-Alpes.
+ *
+ * This software is governed by the CeCILL  license under French law and
+ * abiding by the rules of distribution of free software.  You can  use,
+ * modify and/ or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and  rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty  and the software's author,  the holder of the
+ * economic rights,  and the successive licensors  have only  limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading,  using,  modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean  that it is complicated to manipulate,  and  that  also
+ * therefore means  that it is reserved for developers  and  experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and,  more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ *
+ * /**
+ * Class MSCDrawer
+ * Draw textual SD modeling
+ * Creation: 17/07/2009
+ * @version 1.0 17/07/2009
+ * @author Ludovic APVRILLE
+ * @see MainGUI
+ */
+
+package ui;
+
+import java.util.*;
+
+import sddescription.*;
+import ui.sd.*;
+import ui.iod.*;
+
+public class MSCDrawer {
+    private MainGUI mgui;
+    private MSC msc;
+    //private int indexDesign;
+    private AnalysisPanel ap;
+    //private Vector telements;
+    //private Vector gelements;
+    
+    //private double radius;
+    //private double centerX;
+    //private double centerY;
+
+    public MSCDrawer(MainGUI _mgui) {
+        mgui = _mgui;
+    }
+    
+    public void setMSC(MSC _msc) {
+        msc = _msc;
+        //tm.simplify(true, false);
+        //tm.countJunctions();
+    }
+    
+    public boolean draw(int analysisNb) {
+        /*telements = new Vector();
+        gelements = new Vector();
+        try {
+            makeDrawable();
+            //System.out.println("design");
+            addDesign(designNb);
+            //System.out.println("classes");
+            drawTClasses();
+            //System.out.println("ad");
+            drawActivityDiagrams();
+            //System.out.println("relations");
+            drawRelations();
+            //System.out.println("all done");
+        } catch (MalformedTURTLEModelingException mtm) {
+        	System.out.println(mtm.getMessage());
+            return false;
+        }*/
+        
+        return true;
+    }
+    
+    /*private void addDesign(int designNb) throws MalformedTURTLEModelingException {
+        indexDesign = mgui.createDesign("Generated Design " + designNb);
+        //System.out.println("indexDesign=" + indexDesign);
+        if (indexDesign < 0) {
+            throw new MalformedTURTLEModelingException("bad index");
+        }
+        try {
+            dp = (DesignPanel)(mgui.tabs.elementAt(indexDesign));
+        } catch (Exception e) {
+            throw new MalformedTURTLEModelingException("design panel not found");
+        }
+        
+        dp.tcdp.setMinX(10);
+        dp.tcdp.setMaxX(1900);
+        dp.tcdp.setMinY(10);
+        dp.tcdp.setMaxY(900);
+        //dp.tcdp.updateSize();
+    }
+    
+    private void drawTClasses() throws MalformedTURTLEModelingException {
+        TClass t;
+        int total = tm.classNb();
+        radius = 200 + 30 * total;
+        centerX = radius + 50;
+        centerY = radius + 50;
+        
+        int maxX = 1900;
+        int maxY = 900;
+        while(maxX < (radius *2 + 200)) {
+            maxX = maxX + 500;
+            dp.tcdp.setMaxX(maxX);
+        }
+        while(maxY < (radius *2 + 200)) {
+            maxY = maxY + 500;
+            dp.tcdp.setMaxY(maxY);
+        }
+        dp.tcdp.updateSize();
+        
+        for(int i=0; i<total; i++) {
+            drawTClass(tm.getTClassAtIndex(i), i, total);
+        }
+    }
+    
+    private void drawTClass(TClass t, int index, int total) throws MalformedTURTLEModelingException {
+        // Calculate where the class should be added
+        // We use a circle to dipose classes
+        double angle = 2*Math.PI*index/total;
+        int myX = (int)(Math.cos(angle)*radius + centerX);
+        int myY = (int)(Math.sin(angle)*radius + centerY);
+        
+        // Creating tclass
+        TGComponent tgc = TGComponentManager.addComponent(myX, myY, TGComponentManager.TCD_TCLASS, dp.tcdp);
+        TCDTClass tcd = (TCDTClass)tgc;
+        
+        telements.add(t);
+        gelements.add(tgc);
+        
+        // setting tclass properties
+        tgc.setValue(t.getName());
+        tgc.setValueWithChange(t.getName());
+        tcd.setStart(t.isActive());
+        
+        // Adding tclass to the diagram
+        dp.tcdp.addBuiltComponent(tgc);
+        tcd.recalculateSize();
+        
+        // Managing gates
+        addAttributes(t, tcd);
+        addGates(t, tcd);
+        tcd.checkSizeOfSons();
+    }
+    
+    public void addAttributes(TClass t, TCDTClass tcd) throws MalformedTURTLEModelingException {
+        Vector params = t.getParamList();
+        Vector attributes = new Vector();
+        Param p;
+        TAttribute ta;
+        
+        for(int i=0; i<params.size(); i++) {
+            p = (Param)(params.elementAt(i));
+            ta = null;
+            if (p.getType().compareTo(Param.NAT) ==0) {
+                ta = new TAttribute(TAttribute.PRIVATE, p.getName(), p.getValue(), TAttribute.NATURAL);
+            } else if (p.getType().compareTo(Param.BOOL) ==0) {
+                ta = new TAttribute(TAttribute.PRIVATE, p.getName(), p.getValue(), TAttribute.BOOLEAN);
+            } else if (p.getType().compareTo(Param.QUEUE_NAT) ==0) {
+                ta = new TAttribute(TAttribute.PRIVATE, p.getName(), p.getValue(), TAttribute.QUEUE_NAT);
+            } else {
+                throw new MalformedTURTLEModelingException("attribute of an unknown type");
+            }
+            if (ta != null) {
+                attributes.add(ta);
+            }
+        }
+        
+        tcd.setAttributes(attributes);
+    }
+    
+    public void addGates(TClass t, TCDTClass tcd) throws MalformedTURTLEModelingException {
+        Vector tmgates = t.getGateList();
+        Vector gates = new Vector();
+        Gate g;
+        TAttribute ta;
+        
+        for(int i=0; i<tmgates.size(); i++) {
+            g = (Gate)(tmgates.elementAt(i));
+            ta = new TAttribute(TAttribute.PUBLIC, g.getName(), "", g.getType()+1);
+            gates.add(ta);
+        }
+        
+        tcd.setGates(gates);
+    }
+    
+    private void drawActivityDiagrams()  throws MalformedTURTLEModelingException {
+        int total = tm.classNb();
+        for(int i=0; i<total; i++) {
+            drawActivityDiagram(tm.getTClassAtIndex(i));
+        }
+    }
+    
+    private void drawActivityDiagram(TClass t) throws MalformedTURTLEModelingException {
+        ActivityDiagram ad = t.getActivityDiagram();
+        ADStart ads = ad.getStartState();
+        int index = mgui.tabs.indexOf(dp);
+        TActivityDiagramPanel tadp = mgui.getActivityDiagramPanel(index, t.getName());
+        tadp.removeAll();
+        makeADOf(ads, tadp, null, 0, 0);
+        tadp.makeGraphicalOptimizations();
+    }
+    
+    private void makeADOf(ADComponent adc, TActivityDiagramPanel tadp, TGComponent previous, int indexNext, int totalNext) throws MalformedTURTLEModelingException {
+        // Check if component has already been computed
+        if (telements.contains(adc)) {
+            int index = telements.indexOf(adc);
+            TGComponent tgcc = (TGComponent)(gelements.elementAt(index));
+            // make link if required
+            if (!(tgcc instanceof TADStartState)) {
+                TGConnector tgco = connectAD(tgcc, previous, tadp, false, indexNext, totalNext);
+                tadp.addBuiltConnector(tgco);
+            }
+            return;
+        }
+        
+        // make component from adc
+        //System.out.println("Make component");
+        TGComponent tgc = addToAD(adc, tadp);
+        if (tgc ==null) {
+            System.out.println("null component");
+            throw new MalformedTURTLEModelingException("null component");
+        }
+        
+        // Adding component
+        tadp.addBuiltComponent(tgc);
+        telements.add(adc);
+        gelements.add(tgc);
+        
+        // Linking component to the previous one
+        if (!(tgc instanceof TADStartState)) {
+            TGConnector tgco = connectAD(tgc, previous, tadp, true, indexNext, totalNext);
+            tadp.addBuiltConnector(tgco);
+        }
+        
+        // Managing nexts of this component
+        ADComponent nextAdc;
+        for(int i=0; i<adc.getNbNext(); i++) {
+            makeADOf(adc.getNext(i), tadp, tgc, i, adc.getNbNext());
+        }
+    }
+    
+    public TGComponent addToAD(ADComponent adc, TDiagramPanel tadp) throws MalformedTURTLEModelingException {
+        int i;
+        
+        if (adc instanceof ADActionStateWithGate) {
+            ADActionStateWithGate adasw = (ADActionStateWithGate)adc;
+            TADActionState tadas = (TADActionState)(TGComponentManager.addComponent(10, 10, TGComponentManager.TAD_ACTION_STATE, tadp));
+			//System.out.println("action = " + adasw.getActionValue()
+			try {
+				tadas.setValue(adasw.getGate().getName() + adasw.getLimitOnGate() + adasw.getActionValue());
+			} catch (Exception e) {
+				tadas.setValue("Unknown gate");
+			}
+            return tadas;
+        } else if(adc instanceof ADActionStateWithMultipleParam) {
+            ADActionStateWithMultipleParam adawp = ((ADActionStateWithMultipleParam)adc);
+            TADActionState tadas = (TADActionState)(TGComponentManager.addComponent(10, 10, TGComponentManager.TAD_ACTION_STATE, tadp));
+            tadas.setValue(adawp.getActionValue());
+            return tadas;
+        } else if(adc instanceof ADActionStateWithParam) {
+            ADActionStateWithParam adawp = ((ADActionStateWithParam)adc);
+            TADActionState tadas = (TADActionState)(TGComponentManager.addComponent(10, 10, TGComponentManager.TAD_ACTION_STATE, tadp));
+			try {
+				//System.out.println("name = " + adawp.getParam().getName());
+				//System.out.println("action=" + adawp.getActionValue());
+				tadas.setValue(adawp.getParam().getName() + " = " + adawp.getActionValue());
+			} catch (Exception e) {
+				tadas.setValue("unknown = unknown");
+			}
+            return tadas;
+        } else if (adc instanceof ADChoice) {
+            TADChoice tadc = (TADChoice)(TGComponentManager.addComponent(10, 10, TGComponentManager.TAD_CHOICE, tadp));
+            /*if (adc.getNbNext() > 3) {
+               System.out.println("Malformed choice... : TOO MANY next");
+            }*/
+            /*for(i=0; i<3; i++) {
+                if (((ADChoice)(adc)).isGuarded(i)) {
+                    tadc.setGuard(((ADChoice)adc).getGuard(i), i);
+                }
+            }
+            return tadc;
+        } else if (adc instanceof ADDelay) {
+            TADDeterministicDelay tadd = (TADDeterministicDelay)(TGComponentManager.addComponent(10, 10, TGComponentManager.TAD_DETERMINISTIC_DELAY, tadp));
+            tadd.setDelayValue(((ADDelay)adc).getValue());
+            return tadd;
+        } else if (adc instanceof ADJunction) {
+            return TGComponentManager.addComponent(10, 10, TGComponentManager.TAD_JUNCTION, tadp);
+        } else if (adc instanceof ADLatency) {
+            TADNonDeterministicDelay tadnd = (TADNonDeterministicDelay)(TGComponentManager.addComponent(10, 10, TGComponentManager.TAD_NON_DETERMINISTIC_DELAY, tadp));
+            tadnd.setLatencyValue(((ADLatency)adc).getValue());
+            return tadnd;
+        } else if (adc instanceof ADParallel) {
+            TADParallel tadpl = (TADParallel)(TGComponentManager.addComponent(10, 10, TGComponentManager.TAD_PARALLEL, tadp));
+            //System.out.println("Value gate = " + ((ADParallel)adc).getValueGate());
+            tadpl.setValueGate(((ADParallel)adc).getValueGate());
+            return tadpl;
+        } else if (adc instanceof ADPreempt) {
+            TADPreemption tadpr = (TADPreemption)(TGComponentManager.addComponent(10, 10, TGComponentManager.TAD_PREEMPTION, tadp));
+            return tadpr;
+        } else if (adc instanceof ADSequence) {
+            TADSequence tadseq = (TADSequence)(TGComponentManager.addComponent(10, 10, TGComponentManager.TAD_SEQUENCE, tadp));
+            return tadseq;
+        } else if (adc instanceof ADStart) {
+            TADStartState tadstart = (TADStartState)(TGComponentManager.addComponent(600, 75, TGComponentManager.TAD_START_STATE, tadp));
+            return tadstart;
+        } else if (adc instanceof ADStop) {
+            TADStopState tadstop = (TADStopState)(TGComponentManager.addComponent(10, 10, TGComponentManager.TAD_STOP_STATE, tadp));
+            return tadstop;
+        } else if (adc instanceof ADTLO) {
+            TADTimeLimitedOfferWithLatency tadtlo = (TADTimeLimitedOfferWithLatency)(TGComponentManager.addComponent(10, 10, TGComponentManager.TAD_TIME_LIMITED_OFFER_WITH_LATENCY, tadp));
+            tadtlo.setAction(((ADTLO)adc).getGate().getName() + ((ADTLO)adc).getAction());
+            tadtlo.setDelay(((ADTLO)adc).getDelay());
+            tadtlo.setLatency(((ADTLO)adc).getLatency());
+            return tadtlo;
+        } else if (adc instanceof ADTimeInterval) {
+            TADTimeInterval adti = (TADTimeInterval)(TGComponentManager.addComponent(10, 10, TGComponentManager.TAD_DELAY_NON_DETERMINISTIC_DELAY, tadp));
+            adti.setMinValue(((ADTimeInterval)adc).getMinValue());
+            adti.setMaxValue(((ADTimeInterval)adc).getMaxValue());
+            return adti;
+        }
+        
+        System.out.println("adc = " + adc);
+        throw new MalformedTURTLEModelingException("unknown component ->"+adc);
+    }
+    
+    public TGConnector connectAD(TGComponent tgc, TGComponent previous, TActivityDiagramPanel tadp, boolean move, int indexNext, int totalNext) throws MalformedTURTLEModelingException {
+        boolean makeSquare = true;
+        int index = -1;
+        
+        // Find TGconnectingPoints
+        
+        //P1
+        TGConnectingPoint p1 = null;
+        
+        if ((previous instanceof TADParallel) || (previous instanceof TADPreemption) || (previous instanceof TADSequence)) {
+            switch(totalNext) {
+                case 1:
+                    index=7;
+                    break;
+                case 2:
+                    switch(indexNext) {
+                        case 0:
+                            index = 6;
+                            break;
+                        default:
+                            index = 8;
+                            break;
+                    }
+                    break;
+                case 3:
+                    switch(indexNext) {
+                        case 0:
+                            index = 5;
+                            break;
+                        case 1:
+                            index = 7;
+                            break;
+                        default:
+                            index = 9;
+                            break;
+                    }
+                    break;
+                default:
+            }
+        }
+        
+        if ((index != -1) && ((previous instanceof TADPreemption) || (previous instanceof TADSequence))) {
+            index = index - 4;
+        }
+        
+        if (index > -1 ) {
+            p1 = previous.tgconnectingPointAtIndex(index);
+        } else {
+            p1 = previous.findFirstFreeTGConnectingPoint(true, false);
+        }
+        
+        if (p1 == null) {
+            throw new MalformedTURTLEModelingException("p1 connecting point not found");
+        }
+        
+        TGConnectingPoint p2 = null;
+        if (tgc instanceof TADJunction) {
+            if (tgc.tgconnectingPointAtIndex(0).isFree()) {
+                p2 = tgc.findFirstFreeTGConnectingPoint(false, true);
+            } else {
+                p2 = tgc.closerFreeTGConnectingPoint(p1.getX(), p1.getY(), true);
+            }
+        } else {
+            p2 = tgc.findFirstFreeTGConnectingPoint(false, true);
+        }
+        
+        
+        if (p2 == null) {
+            throw new MalformedTURTLEModelingException("p2 connecting point not found on component:" + tgc);
+        }
+        
+        // Move tgc component according to points
+        if (move) {
+            int decX = 0;
+            int decY = 5;
+            if (previous instanceof TADChoice) {
+                makeSquare = false;
+                if (p1 == previous.tgconnectingPointAtIndex(1)) {
+                    decX = -90;
+                }
+                if (p1 == previous.tgconnectingPointAtIndex(2)) {
+                    decX = 90;
+                }
+                decY = 20;
+            }
+            
+            if (previous instanceof TADTimeLimitedOfferWithLatency) {
+                if (p1 == previous.tgconnectingPointAtIndex(2)) {
+                    decX = 50;
+                }
+            }
+            
+            if ((previous instanceof TADSequence) || (previous instanceof TADPreemption)) {
+                makeSquare = false;
+                if (p1 == previous.tgconnectingPointAtIndex(1)) {
+                    decX = -80;
+                }
+                if (p1 == previous.tgconnectingPointAtIndex(2)) {
+                    decX = -40;
+                }
+                if (p1 == previous.tgconnectingPointAtIndex(4)) {
+                    decX = +40;
+                }
+                if (p1 == previous.tgconnectingPointAtIndex(5)) {
+                    decX = +80;
+                }
+                decY = 20;
+            }
+            
+            if (previous instanceof TADParallel) {
+                makeSquare = false;
+                if (p1 == previous.tgconnectingPointAtIndex(5)) {
+                    decX = -100;
+                }
+                if (p1 == previous.tgconnectingPointAtIndex(6)) {
+                    decX = -50;
+                }
+                if (p1 == previous.tgconnectingPointAtIndex(8)) {
+                    decX = +50;
+                }
+                if (p1 == previous.tgconnectingPointAtIndex(9)) {
+                    decX = +100;
+                }
+                decY = 20;
+            }
+            
+            decX = Math.max(p1.getX() - p2.getX() + tgc.getX() + decX, tadp.getMinX());
+            decY = Math.max(p1.getY() - p2.getY() + tgc.getY() + decY, tadp.getMinY());
+            
+            if (decX > tadp.getMaxX()) {
+                tadp.setMaxX(tadp.getMaxX() + 500);
+                tadp.updateSize();
+            }
+            
+            if (decY > tadp.getMaxY()) {
+                //System.out.println("Increasing vertical size");
+                tadp.setMaxY(tadp.getMaxY() + 500);
+                tadp.updateSize();
+            }
+            
+            tgc.setMoveCd(decX, decY);
+        }
+        
+        // Connect both points
+        p1.setFree(false);
+        p2.setFree(false);
+        
+        TGConnector tgco = TGComponentManager.addConnector(p1.x, p1.y, TGComponentManager.CONNECTOR_AD_DIAGRAM, tadp, p1, p2, new Vector());
+        
+        if (makeSquare) {
+            tgco.makeSquareWithoutMovingTGComponents();
+        }
+        
+        return tgco;
+    }
+    
+    private void drawRelations()  throws MalformedTURTLEModelingException {
+        Relation r;
+        for(int i = 0; i < tm.relationNb(); i++) {
+            r = tm.getRelationAtIndex(i);
+            drawRelation(r);
+        }
+    }
+    
+    private void drawRelation(Relation r) throws MalformedTURTLEModelingException {
+        // Identify invloved TClasses
+        int index1 = telements.indexOf(r.t1);
+        int index2 = telements.indexOf(r.t2);
+        
+        if ((index1 <0) ||(index2 <0)) {
+            throw new MalformedTURTLEModelingException("relation with no tclasses");
+        }
+        
+        try {
+            TCDTClass t1 = (TCDTClass)(gelements.elementAt(index1));
+            TCDTClass t2 = (TCDTClass)(gelements.elementAt(index2));
+            
+            // Make connector
+            //System.out.println("Make association between " + t1.getValue() + " and " + t2.getValue());
+            TGConnector tgco = makeAssociation(r, t1, t2);
+            tgco.makeSquareWithoutMovingTGComponents();
+            dp.tcdp.addBuiltConnector(tgco);
+            
+            // Add relation semantics to connector (and gates if necessary)
+            TGComponent operator = makeSemantics(r, tgco, t1, t2);
+            if ((r.type == Relation.SYN) || (r.type == Relation.INV)) {
+                makeGates(operator, r, t1, t2);
+            }
+        } catch (Exception e) {
+            throw new MalformedTURTLEModelingException("error happened when making a relation");
+        }
+        
+    }
+    
+    private TGConnector makeAssociation(Relation r, TCDTClass t1, TCDTClass t2) throws MalformedTURTLEModelingException {
+        TGConnectingPoint p1 = t1.closerFreeTGConnectingPoint(t2.getX(), t2.getY());
+        TGConnectingPoint p2 = t2.closerFreeTGConnectingPoint(t1.getX(), t1.getY());
+        
+        if ((p1 != null) && (p2 != null)) {
+            p1.setFree(false);
+            p2.setFree(false);
+            if ((r.type == Relation.PRE) || (r.type == Relation.SEQ) ||(r.type == Relation.INV)) {
+                return TGComponentManager.addConnector(p1.x, p1.y, TGComponentManager.CONNECTOR_ASSOCIATION_NAVIGATION, dp.tcdp, p1, p2, new Vector());
+            } else {
+                return TGComponentManager.addConnector(p1.x, p1.y, TGComponentManager.CONNECTOR_ASSOCIATION, dp.tcdp, p1, p2, new Vector());
+            }
+        }
+        
+        return null;
+    }
+    
+    
+    private TGComponent makeSemantics(Relation r, TGConnector tgco, TCDTClass t1, TCDTClass t2) throws MalformedTURTLEModelingException {
+        // has at leat 3 tgconnecting points -> take the one in thne middle
+        TGConnectingPoint pt;
+        if (tgco.getNbConnectingPoint() < 1) {
+            throw new MalformedTURTLEModelingException("No connecting point");
+        }
+        
+        pt = tgco.getTGConnectingPointAtIndex(Math.min(1, tgco.getNbConnectingPoint()-1));
+        
+        TGComponent operator = null;
+        int type = 0;
+        // Add a operator corresponding to the relation semantics
+        switch(r.type) {
+            case   Relation.PAR:
+                type = TGComponentManager.TCD_PARALLEL_OPERATOR;
+                break;
+            case Relation.SYN:
+                type = TGComponentManager.TCD_SYNCHRO_OPERATOR;
+                break;
+            case Relation.INV:
+                type = TGComponentManager.TCD_INVOCATION_OPERATOR;
+                break;
+            case Relation.SEQ:
+                type = TGComponentManager.TCD_SEQUENCE_OPERATOR;
+                break;
+            case Relation.PRE:
+                type = TGComponentManager.TCD_PREEMPTION_OPERATOR;
+                break;
+            default:
+                type = -1;
+        }
+        
+        // Add operator if non null
+        if (type == -1) {
+            throw new MalformedTURTLEModelingException("Unknown relation type");
+        }
+        
+        // Is the line horizontal or vertical?
+        boolean vertical = true ;
+        if (tgco.isPtOnVerticalSegment(pt)) {
+            vertical = false;
+        }
+        
+        int myX, myY;
+        
+        if (vertical) {
+            myX = pt.getX() - 50;
+            myY = pt.getY() - 100;
+        } else {
+            myX = pt.getX() + 75;
+            myY = pt.getY() - 12;
+        }
+        
+        operator = TGComponentManager.addComponent(myX, myY, type, dp.tcdp);
+        telements.add(r);
+        gelements.add(operator);
+        dp.tcdp.addBuiltComponent(operator);
+        
+        TGConnectingPoint pop;
+        if (vertical) {
+            pop = operator.getTGConnectingPointAtIndex(2);
+        } else {
+            pop = operator.getTGConnectingPointAtIndex(0);
+        }
+        
+        // Connects the connector to the operator
+        pt.setFree(false);
+        pop.setFree(false);
+        TGConnector dashco = TGComponentManager.addConnector(pt.x, pt.y, TGComponentManager.CONNECTOR_ATTRIBUTE, dp.tcdp, pt, pop, new Vector());
+        //dashco.makeSquareWithoutMovingTGComponents();
+        dp.tcdp.addBuiltConnector(dashco);
+        
+        if (operator instanceof TCDCompositionOperatorWithSynchro) {
+            ((TCDCompositionOperatorWithSynchro)(operator)).structureChanged();
+        }
+        
+        return operator;
+        
+    }
+    
+    // If invocation / synchro -> set synchronization gates
+    public void makeGates(TGComponent operator, Relation r, TCDTClass t1, TCDTClass t2)  throws MalformedTURTLEModelingException {
+        Vector gates = null;
+        TTwoAttributes tt;
+        TAttribute ta1, ta2;
+        Gate g1, g2;
+        try {
+            gates = ((TCDCompositionOperatorWithSynchro)operator).getGates();
+            
+        } catch (Exception e){
+            throw new MalformedTURTLEModelingException("Gates of synchro relation may not be set");
+        }
+        
+        for(int i=0; i<r.gatesOfT1.size(); i++) {
+            g1 = (Gate)(r.gatesOfT1.elementAt(i));
+            g2 = (Gate)(r.gatesOfT2.elementAt(i));
+            ta1 = t1.getGateById(g1.getName());
+            ta2 = t2.getGateById(g2.getName());
+            tt = new TTwoAttributes(t1, t2, ta1, ta2);
+            gates.add(tt);
+        }
+        
+        ((TCDCompositionOperatorWithSynchro)operator).getSynchroGateList().makeValue();
+        
+    }
+    
+    public void makeDrawable() {
+        tm.unmergeChoices();
+		
+        TClass t;
+        for(int i=0; i<tm.classNb(); i++) {
+            t = tm.getTClassAtIndex(i);
+            makeDrawable(t.getActivityDiagram(), false);
+        }
+    }
+    
+    public int makeDrawable(ActivityDiagram ad, boolean debug) {
+        ADComponent adc, adc1;
+        ADJunction adj1, adj2 = null;
+        int i=0;
+        
+        while(i<ad.size()) {
+            adc = (ADComponent)(ad.elementAt(i));
+            
+            // Ensure that at most 3 elements lead to a junction -> if more, remove one
+            if (adc instanceof ADJunction) {
+                adj1 = (ADJunction)adc;
+                if (ad.getNbComponentLeadingTo(adj1) > 3) {
+                    // Find an appropriate new junction
+                    if (adj1.getNext(0) instanceof ADJunction) {
+                        adj2 = (ADJunction)(adj1.getNext(0));
+                        if (ad.getNbComponentLeadingTo(adj1) > 2) {
+                            // No space left on that junction ...
+                            // Create a new junction
+                            adj2 = new ADJunction();
+                            ad.add(adj2);
+                            adj2.addNext(adj1.getNext(0));
+                            adj1.removeAllNext();
+                            adj1.addNext(adj2);
+                        }
+                    } else {
+                        adj2 = new ADJunction();
+                        ad.add(adj2);
+                        adj2.addNext(adj1.getNext(0));
+                        adj1.removeAllNext();
+                        adj1.addNext(adj2);
+                    }
+                    adc1 = ad.getFirstComponentLeadingTo(adc);
+                    adc1.updateNext(adj1, adj2);
+                    return makeDrawable(ad, debug);
+                }
+            }      
+            i++;
+        }   
+        return 0;
+    }*/
+}
\ No newline at end of file
diff --git a/src/ui/MainGUI.java b/src/ui/MainGUI.java
index 815beef7419d99e7ff4a665e24165a814d0ffacc..259d662aedb0c6c30c55379b19c083f05cc5685d 100755
--- a/src/ui/MainGUI.java
+++ b/src/ui/MainGUI.java
@@ -480,6 +480,7 @@ public	class MainGUI implements ActionListener, WindowListener, KeyListener {
 			actions[TGUIAction.ACT_NEW].setEnabled(true);
 			actions[TGUIAction.ACT_OPEN].setEnabled(true);
 			actions[TGUIAction.ACT_OPEN_TIF].setEnabled(true);
+			actions[TGUIAction.ACT_OPEN_SD].setEnabled(true);
 			actions[TGUIAction.ACT_OPEN_LAST].setEnabled(true);
 			actions[TGUIAction.ACT_QUIT].setEnabled(true);
 			actions[TGUIAction.ACT_ABOUT].setEnabled(true);
@@ -1901,6 +1902,40 @@ public	class MainGUI implements ActionListener, WindowListener, KeyListener {
 		return gtm.openTIF(s);
 		
 	}
+	
+	public boolean openSD() {
+		//jfc.setApproveButtonText("Open");
+        int returnVal = jfctif.showOpenDialog(frame);
+        
+        if (returnVal == JFileChooser.APPROVE_OPTION) {
+            file = jfctif.getSelectedFile();
+        }
+        
+        String s = null;
+        if(checkFileForOpen(file)) {
+            try {
+                FileInputStream fis = new FileInputStream(file);
+                int nb = fis.available();
+                
+                byte [] ba = new byte[nb];
+                fis.read(ba);
+                fis.close();
+                s = new String(ba);
+            } catch(Exception e) {
+                JOptionPane.showMessageDialog(frame, "File could not be opened because " + e.getMessage(), "File Error", JOptionPane.INFORMATION_MESSAGE);
+                return false;
+            }
+		}
+		if (s == null) {
+			return false;
+		}
+		System.out.println("Open SD =" + s);
+		if (gtm == null) {
+			newTurtleModeling();
+		}
+		return gtm.openSD(s);
+		
+	}
     
     public boolean saveProject() {
         if (file == null) {
@@ -5188,6 +5223,8 @@ public	class MainGUI implements ActionListener, WindowListener, KeyListener {
             saveTIF();
         } else if (command.equals(actions[TGUIAction.ACT_OPEN_TIF].getActionCommand())) {
             openTIF();
+        } else if (command.equals(actions[TGUIAction.ACT_OPEN_SD].getActionCommand())) {
+            openSD();
         } else if (command.equals(actions[TGUIAction.ACT_SAVE_LOTOS].getActionCommand())) {
             saveLastLotos();
         } else if (command.equals(actions[TGUIAction.ACT_SAVE_DTA].getActionCommand())) {
diff --git a/src/ui/TGUIAction.java b/src/ui/TGUIAction.java
index 74da5d303b1425284632d9e05db60a63705f37f6..81f4b534b94ad83f5abd04a6009940502e7e45b0 100755
--- a/src/ui/TGUIAction.java
+++ b/src/ui/TGUIAction.java
@@ -68,6 +68,7 @@ public class TGUIAction extends AbstractAction {
     public static final int ACT_SAVE_AS = 31;
 	public static final int ACT_SAVE_TIF = 213;
 	public static final int ACT_OPEN_TIF = 214;
+	public static final int ACT_OPEN_SD = 268;
     public static final int ACT_QUIT = 3;
     
     public static final int ACT_SAVE_LOTOS = 64;
@@ -378,9 +379,7 @@ public class TGUIAction extends AbstractAction {
     //Action for the help button created by Solange
     public static final int PRUEBA_1 = 205;
 
-    
-    public static final int NB_ACTION = 268;
-
+    public static final int NB_ACTION = 269;
 
     private  static final TAction [] actions = new TAction[NB_ACTION];