diff --git a/src/main/java/ai/AIUseCaseDiagram.java b/src/main/java/ai/AIUseCaseDiagram.java
index e6cf72d5d9d0a082f29b1455e6a89bbffec07118..ff7c4d2aacf625e48474b0da3fee174d5456c418 100644
--- a/src/main/java/ai/AIUseCaseDiagram.java
+++ b/src/main/java/ai/AIUseCaseDiagram.java
@@ -255,42 +255,13 @@ public class AIUseCaseDiagram extends AIInteract {
     }
 
     private String getUseCaseNames(String _spec, ArrayList<String> _errors) throws org.json.JSONException {
-        if (_spec == null) {
-            _errors.add("No \"usecases\" array in json");
-            return "";
-        }
-        int indexStart = _spec.indexOf('{');
-        int indexStop = _spec.lastIndexOf('}');
-
-        if ((indexStart == -1) || (indexStop == -1) || (indexStart > indexStop)) {
-            throw new org.json.JSONException("Invalid JSON object (start)");
-        }
-
-        _spec = _spec.substring(indexStart, indexStop + 1);
-
-        //TraceManager.addDev("Cut spec: " + _spec);
-
-        JSONObject mainObject = new JSONObject(_spec);
-
-        JSONArray usecases = mainObject.getJSONArray("usecases");
+        AvatarUseCaseDiagram ad = new AvatarUseCaseDiagram("", null);
+        _errors.addAll(ad.makeUseCasesFromJson(_spec));
 
-        if (usecases == null) {
-            TraceManager.addDev("No \"actor\" array in json");
-            _errors.add("No \"actor\" array in json");
-            return "";
-        }
+        return ad.getActorNames();
+    }
 
-        String listOfUseCases = "";
-        for (int i = 0; i < usecases.length(); i++) {
-            JSONObject useCase = usecases.getJSONObject(i);
-            String useCaseName = AvatarSpecification.removeSpaces(useCase.getString("name"));
-            if (useCaseName != null) {
-                listOfUseCases += useCaseName + " ";
-            }
-        }
 
-        return listOfUseCases;
-    }
 
 
 
diff --git a/src/main/java/avatartranslator/avatarucd/AvatarUseCaseDiagram.java b/src/main/java/avatartranslator/avatarucd/AvatarUseCaseDiagram.java
index 84d4a767e54ce53f3258138e8471a02571f0fb0a..3f8b5cd668c9f6ec8df7218f8df088c3a4278108 100644
--- a/src/main/java/avatartranslator/avatarucd/AvatarUseCaseDiagram.java
+++ b/src/main/java/avatartranslator/avatarucd/AvatarUseCaseDiagram.java
@@ -66,6 +66,7 @@ public class AvatarUseCaseDiagram extends AvatarElement {
         super(_name, _name);
         actors = new ArrayList<>();
         useCases = new ArrayList<>();
+        connections = new ArrayList<>();
     }
 
     public ArrayList<String> makeActorsFromJson(String _json) {
@@ -96,7 +97,6 @@ public class AvatarUseCaseDiagram extends AvatarElement {
             return errors;
         }
 
-        String listOfActors = "";
         for (int i = 0; i < actorsJ.length(); i++) {
             JSONObject actor = actorsJ.getJSONObject(i);
             String actorName = actor.getString("name");
@@ -112,6 +112,49 @@ public class AvatarUseCaseDiagram extends AvatarElement {
         return errors;
     }
 
+    public ArrayList<String> makeUseCasesFromJson(String _json) {
+        ArrayList<String> errors = new ArrayList<>();
+
+        if (_json == null) {
+            errors.add("No \"usecases\" array in json");
+            return errors;
+        }
+        int indexStart = _json.indexOf('{');
+        int indexStop = _json.lastIndexOf('}');
+
+        if ((indexStart == -1) || (indexStop == -1) || (indexStart > indexStop)) {
+            errors.add("Invalid JSON object (start or stop)");
+            return errors;
+        }
+
+        _json = _json.substring(indexStart, indexStop + 1);
+
+        //TraceManager.addDev("Cut spec: " + _spec);
+
+        JSONObject mainObject = new JSONObject(_json);
+        JSONArray useCasesJ = mainObject.getJSONArray("usecases");
+
+        if (useCasesJ == null) {
+            TraceManager.addDev("No \"usecase\" array in json");
+            errors.add("No \"usecase\" array in json");
+            return errors;
+        }
+
+        for (int i = 0; i < useCasesJ.length(); i++) {
+            JSONObject useCase = useCasesJ.getJSONObject(i);
+            String useCaseName = useCase.getString("name");
+            if (useCaseName == null) {
+                errors.add("Usecase #" + i + " has no name");
+            } else {
+                useCaseName = Conversion.replaceAllString(useCase.getString("name").trim(), " ", "");
+                actors.add(new AvatarActor(useCaseName, null));
+            }
+        }
+
+
+        return errors;
+    }
+
     public String getActorNames() {
         StringBuffer sb = new StringBuffer();
         for(AvatarActor actor: actors) {
@@ -125,6 +168,111 @@ public class AvatarUseCaseDiagram extends AvatarElement {
         return sb.toString().trim();
     }
 
+    public String getUseCaseNames() {
+        StringBuffer sb = new StringBuffer();
+        for(AvatarUseCase useCase: useCases) {
+            if (sb.length() == 0) {
+                sb.append(useCase.getName());
+            } else {
+                sb.append("" + useCase.getName());
+            }
+        }
+
+        return sb.toString().trim();
+    }
+
+    public AvatarActor getActorByName(String _name) {
+        for(AvatarActor aa: actors) {
+            if (aa.getName().equals(_name)) {
+                return aa;
+            }
+        }
+        return null;
+    }
+
+    public AvatarUseCase getUseCaseByName(String _name) {
+        for(AvatarUseCase auc: useCases) {
+            if (auc.getName().equals(_name)) {
+                return auc;
+            }
+        }
+        return null;
+    }
+
+    public AvatarUCDConnection addConnection(String nameOrigin, String nameDestination, boolean force) throws AvatarUseCaseDiagramException {
+        AvatarActor actor1 = getActorByName(nameOrigin);
+        AvatarActor actor2 = getActorByName(nameDestination);
+
+        if ((actor1 != null) && (actor2 != null)) {
+            throw new AvatarUseCaseDiagramException("Connection between two actors is not supported");
+        }
+
+        if ((actor1 == null) && (actor2 == null)) { // between use cases
+            AvatarUseCase uc1 = getUseCaseByName(nameOrigin);
+            AvatarUseCase uc2 = getUseCaseByName(nameDestination);
+
+            if (!force) {
+                if (uc1 == null) {
+                    throw new AvatarUseCaseDiagramException("Use case \"" + nameOrigin + "\" is invalid");
+                }
+                if (uc2 == null) {
+                    throw new AvatarUseCaseDiagramException("Use case \"" + nameDestination + "\" is invalid");
+                }
+            }
+
+            if (uc1 == null) {
+                uc1 = new AvatarUseCase(nameOrigin, null);
+                useCases.add(uc1);
+            }
+
+            if (uc2 == null) {
+                uc2 = new AvatarUseCase(nameDestination, null);
+                useCases.add(uc2);
+            }
+
+            AvatarUCDConnection connection = new AvatarUCDConnection("con " + uc1.getName() + " - " + uc2.getName(), null);
+            connection.origin = uc1;
+            connection.destination = uc2;
+            connection.type = AvatarUCDConnection.CONNECTION.INCLUDE;
+            connections.add(connection);
+            return connection;
+
+
+        } else { // Between one actor and one use case
+            AvatarUseCase useCase;
+            if (actor1 == null) {
+                useCase = getUseCaseByName(nameOrigin);
+            } else {
+                useCase = getUseCaseByName(nameDestination);
+            }
+
+            if (useCase == null) {
+                if (!force) {
+                    throw new AvatarUseCaseDiagramException("Connection between one actor and an unknown use case is not supported");
+                }
+                if (actor1 == null) {
+                    useCase = new AvatarUseCase(nameOrigin, null);
+                } else {
+                    useCase = new AvatarUseCase(nameDestination, null);
+                }
+                useCases.add(useCase);
+            }
+
+            AvatarActor aa = actor1;
+            if (actor1 == null) {
+                aa = actor2;
+            }
+
+            AvatarUCDConnection connection = new AvatarUCDConnection("con " + aa.getName() + " - " + useCase.getName(), null);
+            connection.origin = aa;
+            connection.destination = useCase;
+            connection.type = AvatarUCDConnection.CONNECTION.WITH_ACTOR;
+            connections.add(connection);
+            return connection;
+
+        }
+    }
+
 
 
 
diff --git a/src/main/java/avatartranslator/avatarucd/AvatarUseCaseDiagramException.java b/src/main/java/avatartranslator/avatarucd/AvatarUseCaseDiagramException.java
new file mode 100644
index 0000000000000000000000000000000000000000..82f003dd1c69ca468e38179c8dc5dcd5acbd1a4c
--- /dev/null
+++ b/src/main/java/avatartranslator/avatarucd/AvatarUseCaseDiagramException.java
@@ -0,0 +1,60 @@
+/* Copyright or (C) or Copr. GET / ENST, Telecom-Paris, Ludovic Apvrille
+ * 
+ * ludovic.apvrille AT enst.fr
+ * 
+ * This software is a computer program whose purpose is to allow the
+ * edition of TURTLE analysis, design and deployment diagrams, to
+ * allow the generation of RT-LOTOS or Java code from this diagram,
+ * and at last to allow the analysis of formal validation traces
+ * obtained from external tools, e.g. RTL from LAAS-CNRS and CADP
+ * from INRIA Rhone-Alpes.
+ * 
+ * This software is governed by the CeCILL  license under French law and
+ * abiding by the rules of distribution of free software.  You can  use,
+ * modify and/ or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ * 
+ * As a counterpart to the access to the source code and  rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty  and the software's author,  the holder of the
+ * economic rights,  and the successive licensors  have only  limited
+ * liability.
+ * 
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading,  using,  modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean  that it is complicated to manipulate,  and  that  also
+ * therefore means  that it is reserved for developers  and  experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and,  more generally, to use and operate it in the
+ * same conditions as regards security.
+ * 
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ */
+
+package avatartranslator.avatarucd;
+
+import avatartranslator.AvatarElement;
+import myutil.NameChecker;
+import myutil.TraceManager;
+
+import java.util.List;
+import java.util.UUID;
+import java.util.Vector;
+
+/**
+   * Class AvatarUseCaseDiagramException
+   * Creation: 11/03/2024
+   * @author Ludovic APVRILLE
+ */
+public class AvatarUseCaseDiagramException extends Exception {
+
+    public AvatarUseCaseDiagramException(String _message) {
+        super(_message);
+    }
+
+}