diff --git a/src/main/java/ai/AIStateMachinesAndAttributes.java b/src/main/java/ai/AIStateMachinesAndAttributes.java
new file mode 100644
index 0000000000000000000000000000000000000000..ddbba13976eb4f3ec7b593a913fa6eb8900d7ae6
--- /dev/null
+++ b/src/main/java/ai/AIStateMachinesAndAttributes.java
@@ -0,0 +1,268 @@
+/* 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 ai;
+
+
+import avatartranslator.AvatarBlock;
+import avatartranslator.AvatarSpecification;
+import avatartranslator.tosysmlv2.AVATAR2SysMLV2;
+import myutil.TraceManager;
+import org.apache.batik.anim.timing.Trace;
+
+import java.util.ArrayList;
+
+/**
+ * Class AIStateMachinesAndAttributes
+ * <p>
+ * Creation: 04/08/2023
+ *
+ * @author Ludovic APVRILLE
+ * @version 1.0 04/08/2023
+ */
+
+
+public class AIStateMachinesAndAttributes extends AIInteract implements AISysMLV2DiagramContent, AIAvatarSpecificationRequired {
+    private static String[] SUPPORTED_DIAGRAMS = {"BD"};
+    private static String[] EXCLUSIONS_IN_INPUT = {"state",  "method"};
+
+    public static String KNOWLEDGE_ON_JSON_FOR_STATE_MACHINES = "When you are asked to identify the SysML state machine of a block, " +
+            "return them as a JSON specification " +
+            "formatted as follows:" +
+            "{states: [{ \"name\": \"Name of state\", transitions [{ \"destinationstate\" : \"state name\",  \"guard\": \"boolean condition\", " +
+            "\"after\": \"time " +
+        "value\", \"action\":" +
+            " \"attribute action or signal receiving/sending\"}]}]} .";
+
+    public static String ATTRIBUTES_JSON_FOR_STATE_MACHINES = "Now, give the type of all attributes (and not signals) you have just used using the " +
+            "following JSON " +
+            "format: {attributes: [{\"name\" : \"name of attribute\",  \"type\": \"int or boolean\"";
+
+    public static String[] CONSTRAINTS_ON_JSON_FOR_STATE_MACHINES = {
+            "# Respect: in actions, use only signals already defined in the block.",
+                    "# Respect: at least one state must be called \"Start\", which is the start state.",
+                    "# Respect: if a guard, an action, or an after is empty, use an empty string \"\", do not use \"null\"." ,
+                    "# Respect: an action contains either a variable affectation, e.g. \"x = x + 1\" or a signal send/receive. " ,
+                    "# Respect: if a transition contains several actions, use a \";\" to separate them. " ,
+                    "# Respect: a signal send or receive is signalName(..) with inside the right attributes or values. " ,
+                    "# Respect: the attribute of an action is named by its identifier, do not reference its block. " ,
+                    "# Respect: a state machine can use only the attribute of its block. " ,
+                    "# Respect: A guard cannot contain a reference to a signal. " ,
+                    "# Respect: To reference the attribute \"x\" of block \"B\", use \"x\" and never \"B.x\" nor \"B::x\"" };
+
+
+    private AvatarSpecification specification;
+
+    private String diagramContentInSysMLV2;
+
+    private static String KNOWLEDGE_SYSTEM_SPECIFICATION = "The specification of the system is:";
+    private static String KNOWLEDGE_SYSTEM_BLOCKS = "The specification of the blocks in SysML V2 is:";
+
+    private String[] QUESTION_IDENTIFY_STATE_MACHINE = {"From the  system specification, and from the definition of blocks and" +
+            " their " +
+            "connections, identify the state machine of block: "};
+
+
+    public AIStateMachinesAndAttributes(AIChatData _chatData) {
+        super(_chatData);
+    }
+
+    public void internalRequest() {
+
+        // Add the knowledge, retrieve the block names, attributes, etc.
+
+        /*if (!chatData.knowledgeOnStateMachines) {
+            chatData.aiinterface.addKnowledge(KNOWLEDGE_ON_JSON_FOR_STATE_MACHINES, "ok");
+            chatData.knowledgeOnStateMachines = true;
+        }
+
+        chatData.aiinterface.addKnowledge(KNOWLEDGE_SYSTEM_SPECIFICATION + chatData.lastQuestion, "ok");
+        chatData.aiinterface.addKnowledge(KNOWLEDGE_SYSTEM_BLOCKS + diagramContentInSysMLV2, "ok");*/
+
+        // Getting block names for SysMLV2 spec
+        //TraceManager.addDev("SysML V2 spec: " + diagramContentInSysMLV2);
+        //ArrayList<String> blockNames = AVATAR2SysMLV2.getAllBlockNames(diagramContentInSysMLV2);
+        ArrayList<String> blockNames = specification.getAllBlockNames();
+
+        TraceManager.addDev("Going to handle the following blocks: ");
+        for(String s: blockNames) {
+            TraceManager.addDev("\tblock: " + s);
+        }
+
+
+        boolean done = false;
+        int cpt = 0;
+
+        String questionT;
+
+
+        for(String blockName: blockNames) {
+            TraceManager.addDev("Handling block: " + blockName);
+            done = false; cpt = 0;
+            int max = 3;
+
+
+            initKnowledge();
+
+            AvatarBlock b = specification.getBlockWithName(blockName);
+            questionT = QUESTION_IDENTIFY_STATE_MACHINE[0] + blockName;
+            if (b != null) {
+                questionT += ". This block has the following attributes: " + specification.getStringAttributes(b);
+                questionT += ". This block has the following signals: " + specification.getStringSignals(b);
+            }
+            while (!done && cpt < max) {
+                done = true;
+
+
+                boolean ok1 = makeQuestion(questionT);
+                if (!ok1) {
+                    TraceManager.addDev("Make question #1 failed");
+                }
+                String json1 = extractJSON();
+
+                //chatData.aiinterface.addKnowledge(questionT, chatData.lastAnswer);
+                questionT = ATTRIBUTES_JSON_FOR_STATE_MACHINES;
+                boolean ok2 = makeQuestion(questionT);
+
+                if (!ok2) {
+                    TraceManager.addDev("Make question #2 failed");
+                }
+                String json2 = extractJSON();
+
+                if (ok1 && ok2 && specification != null) {
+                    if (b != null) {
+                        ArrayList<String> errors = new ArrayList<>();
+                        ArrayList<String> ret;
+                        TraceManager.addDev("Adding attributes of the state machine of " + blockName);
+                        ret = b.addAttributesFromJSON(json2);
+                        if (ret != null) {
+                            errors.addAll(ret);
+                        }
+                        TraceManager.addDev("Making the state machine of " + blockName);
+
+                        errors.addAll(b.makeStateMachineFromJSON(json1, true));
+
+                        ret = b.addAttributesFromJSON(json2);
+                        if (ret != null) {
+                            errors.addAll(ret);
+                        }
+
+                        if ((errors != null) && (errors.size() > 0)) {
+                            done = false;
+                            initKnowledge();
+
+                            questionT += "Your specification was: " + json1 + ". But it is not correct because of the following errors:";
+
+                            for (String s : errors) {
+                                TraceManager.addDev("Error in JSON: " + s);
+                                questionT += "\n- " + s;
+                            }
+                            questionT += "\nProvide only the updated state machine using only the already defined attributes";
+                        } else {
+                            TraceManager.addDev("SMD done for Block " + blockName);
+                        }
+                    } else {
+                        TraceManager.addDev("ERROR: no block named " + blockName);
+                    }
+                } else {
+                    TraceManager.addDev("Null specification or false ok");
+                }
+
+                waitIfConditionTrue(!done && cpt < max);
+
+                cpt ++;
+            }
+            // Remove knowledge of previous questions
+            initKnowledge();
+            /*while(cpt > 0) {
+                cpt --;
+                chatData.aiinterface.removePreviousKnowledge();
+            }*/
+        }
+        TraceManager.addDev("Reached end of AIStateMachine internal request cpt=" + cpt);
+
+    }
+
+    private void initKnowledge() {
+        chatData.aiinterface.clearKnowledge();
+
+        chatData.aiinterface.addKnowledge(KNOWLEDGE_SYSTEM_SPECIFICATION + chatData.lastQuestion, "ok");
+        //chatData.aiinterface.addKnowledge(KNOWLEDGE_SYSTEM_BLOCKS + diagramContentInSysMLV2, "ok");
+        chatData.aiinterface.addKnowledge(KNOWLEDGE_ON_JSON_FOR_STATE_MACHINES, "ok");
+
+        for(int i=0; i<CONSTRAINTS_ON_JSON_FOR_STATE_MACHINES.length; i++) {
+            chatData.aiinterface.addKnowledge(CONSTRAINTS_ON_JSON_FOR_STATE_MACHINES[i], "ok");
+        }
+    }
+
+    public Object applyAnswer(Object input) {
+        TraceManager.addDev("Apply answer in AIState Machine");
+        if (specification == null) {
+            TraceManager.addDev("Null spec");
+        } else {
+            TraceManager.addDev("Non null spec");
+        }
+        if (input == null) {
+            return specification;
+        }
+
+        return specification;
+    }
+
+    public void setAvatarSpecification(AvatarSpecification _specification) {
+        specification = _specification;
+    };
+
+    public void setDiagramContentInSysMLV2(String _diagramContentInSysMLV2) {
+        diagramContentInSysMLV2 = _diagramContentInSysMLV2;
+    };
+
+    public String[] getValidDiagrams() {
+        return SUPPORTED_DIAGRAMS;
+    }
+
+    public String[] getDiagramExclusions() {
+        return EXCLUSIONS_IN_INPUT;
+    }
+
+
+
+
+
+}
diff --git a/src/main/java/avatartranslator/AvatarBlock.java b/src/main/java/avatartranslator/AvatarBlock.java
index f1e60c871873281d6814929704477752aa2cf5ef..638b6447d77ffa97b9e4657852a0a0f64b2ae044 100644
--- a/src/main/java/avatartranslator/AvatarBlock.java
+++ b/src/main/java/avatartranslator/AvatarBlock.java
@@ -1183,13 +1183,15 @@ public class AvatarBlock extends AvatarElement implements AvatarStateMachineOwne
 
                                 try {
                                     for (String action : actions) {
+                                        TraceManager.addDev("Handling action:" + action);
                                         // Affectation?
                                         if (action.contains("=")) {
+                                            TraceManager.addDev("Handling affectation:" + action);
                                             int index = action.indexOf('=');
                                             String variableName = action.substring(0, index).trim();
                                             AvatarAttribute aa = getAvatarAttributeWithName(variableName);
                                             if (aa == null) {
-                                                TraceManager.addDev("The following action is not valid: " + action + " because it contains an attribute  " +
+                                                TraceManager.addDev("The following action is not valid: " + action + " because it contains an attribute " +
                                                         variableName + " which is not declared in the block " + getName());
                                                 errors.add("The following action is not valid: " + action + " because it contains an attribute  " +
                                                         variableName + " which is not declared in the block " + getName());
@@ -1250,55 +1252,35 @@ public class AvatarBlock extends AvatarElement implements AvatarStateMachineOwne
 
                                         }
                                         // signal sending / receiving
-                                        else if (action.contains("::")) {
+                                        else if (isASignalAction(action.trim())) {
                                             TraceManager.addDev("Handing communication action: " + action);
 
-                                            int index = action.indexOf("::");
-                                            boolean isIn = action.substring(0, index).trim().compareTo("in") == 0;
-                                            String signalSent = action.substring(index+2);
-
-                                            if (signalSent.length() >0) {
-                                                 int indexLPar = signalSent.indexOf("(");
-                                                 String sigName = signalSent;
-                                                 if (indexLPar > - 1) {
-                                                     sigName = signalSent.substring(0, indexLPar).trim();
-                                                 }
-                                                AvatarSignal atas = getAvatarSignalWithName(sigName);
-                                                 if ((atas == null) && (!forceIfIncorrectExpression)) {
-                                                     TraceManager.addDev("No signal named \"" + action + "\" in block \"" + getName() + "\"");
-                                                     errors.add("No signal named \"" + action + "\" in block \"" + getName() + "\"" );
-                                                 } else {
-                                                     if (atas == null) {
-                                                         // Adding signal to block
-                                                         atas = new AvatarSignal(sigName, isIn?AvatarSignal.IN : AvatarSignal.OUT, null);
-                                                         addSignal(atas);
-                                                     }
-                                                     AvatarActionOnSignal aaos = new AvatarActionOnSignal(
-                                                             sigName + "_aaos", atas, null, asm.getOwner());
-                                                     // Chaining components
-                                                     asm.addElement(aaos);
-                                                     AvatarTransition atBis =
-                                                             new AvatarTransition(this, "name" + "_from_" + sigName, getReferenceObject());
-                                                     asm.addElement(atBis);
-
-                                                     AvatarStateMachineElement asme = at.getNext(0);
-                                                     at.removeAllNexts();
-                                                     at.addNext(aaos);
-                                                     aaos.addNext(atBis);
-                                                     atBis.addNext(asme);
-                                                     at = atBis;
-
-
-                                                 }
+                                            int index = action.indexOf("(");
+                                            String sigName = action.substring(0, index);
+                                            AvatarSignal as = getAvatarSignalWithName(sigName);
 
+                                            if (as == null) {
+                                                errors.add("No signal named \"" + sigName + "\" in block \"" + getName() + "\"" );
                                             } else {
-                                                TraceManager.addDev("No signal provided in the following action: " + action + ".");
-                                                errors.add("No signal provided in the following action: " + action + ".");
-                                            }
+                                                AvatarActionOnSignal aaos = new AvatarActionOnSignal(
+                                                        sigName + "_aaos", as, null, asm.getOwner());
+                                                asm.addElement(aaos);
+                                                AvatarTransition atBis =
+                                                        new AvatarTransition(this, "name" + "_from_" + sigName, getReferenceObject());
+                                                asm.addElement(atBis);
+
+                                                AvatarStateMachineElement asme = at.getNext(0);
+                                                at.removeAllNexts();
+                                                at.addNext(aaos);
+                                                aaos.addNext(atBis);
+                                                atBis.addNext(asme);
+                                                at = atBis;
 
+                                            }
 
 
                                         } else {
+                                            TraceManager.addDev("Other action:" + action);
                                             if (forceIfIncorrectExpression) {
                                                 at.addAction(action);
                                             } else {
@@ -1327,6 +1309,67 @@ public class AvatarBlock extends AvatarElement implements AvatarStateMachineOwne
         TraceManager.addDev("******************** State Machine of block: " + getName() + ":" + getStateMachine().toString());
 
 
+        return errors;
+    }
+
+    public static boolean isASignalAction(String s) {
+        int index = s.indexOf('(');
+        if (index == -1) {
+            return false;
+        }
+
+        String tmp = s.substring(0, index);
+
+        return tmp.trim().matches("[A-Za-z_][A-Za-z0-9_]*");
+    }
+
+    public ArrayList<String> addAttributesFromJSON(String _jsonSpec) {
+        if (_jsonSpec == null) {
+            return null;
+        }
+
+        ArrayList<String> errors = new ArrayList<>();
+        JSONObject mainObject;
+
+        try {
+            mainObject = new JSONObject(_jsonSpec);
+
+            JSONArray statesJSON = mainObject.getJSONArray("attributes");
+
+            for (int i = 0; i < statesJSON.length(); i++) {
+                JSONObject state0 = statesJSON.getJSONObject(i);
+                String name = AvatarSpecification.removeSpaces(state0.getString("name"));
+                String type = AvatarSpecification.removeSpaces(state0.getString("type"));
+
+                if (type == null) {
+                    type = "int";
+                }
+
+                AvatarType at;
+                if (type.compareTo("boolean") == 0) {
+                    at = AvatarType.BOOLEAN;
+                } else if (type.compareTo("int") == 0){
+                    at = AvatarType.INTEGER;
+                } else {
+                    errors.add("The following type is not valid: " + type + " in attribute " + name);
+                    at = AvatarType.INTEGER;
+                }
+
+                AvatarAttribute aa = getAvatarAttributeWithName(name);
+                if (aa != null){
+                    if (aa.getType() != at) {
+                        errors.add("Attribute " + name + " already has type: " + aa.getType().getStringType());
+                    }
+                } else {
+                    aa = new AvatarAttribute(name, at, this, this.getReferenceObject());
+                    addAttribute(aa);
+                }
+
+            }
+        }  catch (org.json.JSONException e) {
+            errors.add("Invalid JSON: " + e.getMessage());
+        }
+
         return errors;
     }
 }
diff --git a/src/main/java/avatartranslator/AvatarSpecification.java b/src/main/java/avatartranslator/AvatarSpecification.java
index c785a3c3c8451d9201a4332f135b353c930cbe4b..db8c8855f0ccf8b192695d10c75ec7862be06970 100644
--- a/src/main/java/avatartranslator/AvatarSpecification.java
+++ b/src/main/java/avatartranslator/AvatarSpecification.java
@@ -825,8 +825,12 @@ public class AvatarSpecification extends AvatarElement implements IBSParamSpec {
                     jsonErrors.add("The declaration of signal " + sigName + " is not valid for block " + blockOName);
                 }
 
-
-                AvatarSignal asD = AvatarSignal.isAValidSignalThenCreate("in " + sigName, blockD);
+                AvatarSignal asD;
+                if (blockO == blockD) {
+                    asD = AvatarSignal.isAValidSignalThenCreate("in " + sigName + "_in", blockD);
+                } else {
+                    asD = AvatarSignal.isAValidSignalThenCreate("in " + sigName, blockD);
+                }
 
                 if (asD == null) {
                     jsonErrors.add("The declaration of signal " + sigName + " is not valid for block " + blockDName);
@@ -1941,4 +1945,38 @@ public class AvatarSpecification extends AvatarElement implements IBSParamSpec {
         return lne;
     }
 
+    public StringBuffer getStringAttributes(AvatarBlock _ab) {
+        StringBuffer sb = new StringBuffer("");
+
+        if (_ab == null) {
+            return sb;
+        }
+
+        for(AvatarAttribute aa: _ab.getAttributes()) {
+            sb.append(aa.toString() + "\n");
+        }
+        return sb;
+    }
+
+    public StringBuffer getStringSignals(AvatarBlock _ab) {
+        StringBuffer sb = new StringBuffer("");
+
+        if (_ab == null) {
+            return sb;
+        }
+
+        for(AvatarSignal as: _ab.getSignals()) {
+            sb.append(as.toString() + "\n");
+        }
+        return sb;
+    }
+
+    public ArrayList<String> getAllBlockNames() {
+        ArrayList<String> ret = new ArrayList<>();
+        for(AvatarBlock block: blocks) {
+            ret.add(block.getName());
+        }
+        return ret;
+    }
+
 }
diff --git a/src/main/java/ui/window/JFrameAI.java b/src/main/java/ui/window/JFrameAI.java
index 26fc187d55fa2fb6196129410c8ad87b937b63b5..bd16e8e1d6c3c9a5919b49c4d06885dba7fc3127 100644
--- a/src/main/java/ui/window/JFrameAI.java
+++ b/src/main/java/ui/window/JFrameAI.java
@@ -51,6 +51,7 @@ import ui.avatarbd.AvatarBDPanel;
 import ui.avatarrd.AvatarRDPanel;
 import ui.avatarrd.AvatarRDRequirement;
 import ui.util.IconManager;
+
 import javax.swing.*;
 import javax.swing.event.ChangeEvent;
 import javax.swing.event.ChangeListener;
@@ -82,22 +83,27 @@ public class JFrameAI extends JFrame implements ActionListener {
             "Identify system blocks (knowledge type #2) - Provide a system specification",
             "Identify software blocks - Provide a system specification", "Identify state" +
             " machines - Select a block diagram. Additionally, you can provide a system specification",
+            "Identify state machines and attributes - Select a block diagram. Additionally, you can provide a system specification",
             "A(I)MULET - Select a block diagram first"};
 
     private static String[] AIInteractClass = {"AIChat", "AIReqIdent", "AIReqClassification", "AIChat", "AIDesignPropertyIdentification", "AIBlock",
-            "AIBlockConnAttrib", "AISoftwareBlock", "AIStateMachine", "AIAmulet"};
+            "AIBlockConnAttrib", "AISoftwareBlock", "AIStateMachine", "AIStateMachinesAndAttributes", "AIAmulet"};
 
     private static String[] INFOS = {"Chat on any topic you like", "Identify requirements from the specification of a system", "Classify " +
             "requirements from a requirement diagram", "Identify use cases and actors from a system specification",
             "Identify the typical properties" +
-            " to be proven " +
-            "from a block" +
-            " diagram", "Identify the system " +
+                    " to be proven " +
+                    "from a block" +
+                    " diagram", "Identify the system " +
             "blocks from a specification", "Identify the system " +
             "blocks from a specification (another kind of knowledge)", "Identify the software blocks from a specification", "Identify the state " +
             "machines from a " +
             "system " +
-            "specification and a block diagram", "Formalize mutations to be performed on a block diagram"};
+            "specification and a block diagram", "Identify the state " +
+            "machines and attributes from a " +
+            "system " +
+            "specification and a block diagram",
+            "Formalize mutations to be performed on a block diagram"};
 
     protected JComboBox<String> listOfPossibleActions;
 
@@ -337,7 +343,7 @@ public class JFrameAI extends JFrame implements ActionListener {
 
             TraceManager.addDev("Selected aiinteract: " + selected.aiInteract.getClass());
 
-            if (selected.aiInteract  instanceof AIAvatarSpecificationRequired) {
+            if (selected.aiInteract instanceof AIAvatarSpecificationRequired) {
                 TraceManager.addDev("****** AIAvatarSpecificationRequired identified *****");
                 TDiagramPanel tdp = mgui.getCurrentMainTDiagramPanel();
                 boolean found = false;
@@ -360,14 +366,14 @@ public class JFrameAI extends JFrame implements ActionListener {
                 }
             }
 
-            if (selected.aiInteract  instanceof AISysMLV2DiagramContent) {
+            if (selected.aiInteract instanceof AISysMLV2DiagramContent) {
                 TraceManager.addDev("****** AISysMLV2DiagramContent identified *****");
                 TDiagramPanel tdp = mgui.getCurrentTDiagramPanel();
-                String[] validDiagrams = ((AISysMLV2DiagramContent)(selected.aiInteract)).getValidDiagrams();
+                String[] validDiagrams = ((AISysMLV2DiagramContent) (selected.aiInteract)).getValidDiagrams();
                 String className = tdp.getClass().getName();
 
                 boolean found = false;
-                for(String s: validDiagrams) {
+                for (String s : validDiagrams) {
                     if (className.contains(s)) {
                         found = true;
                         break;
@@ -376,8 +382,8 @@ public class JFrameAI extends JFrame implements ActionListener {
 
                 if (found) {
                     TraceManager.addDev("The selected diagram is valid");
-                    String[] exclusions = ((AISysMLV2DiagramContent)(selected.aiInteract)).getDiagramExclusions();
-                    StringBuffer sb =  tdp.toSysMLV2Text(exclusions);
+                    String[] exclusions = ((AISysMLV2DiagramContent) (selected.aiInteract)).getDiagramExclusions();
+                    StringBuffer sb = tdp.toSysMLV2Text(exclusions);
                     if (sb == null) {
                         error("The syntax of the selected diagram is incorrect");
                         return;
@@ -399,7 +405,7 @@ public class JFrameAI extends JFrame implements ActionListener {
         ChatData selectedChat = selectedChat();
         if (selectedChat.lastAnswer == null || selectedChat.aiChatData == null) {
             error("No answer to apply");
-            return ;
+            return;
         }
 
         //TraceManager.addDev("Class of answer: " + selectedChat.aiInteract.getClass().getName());
@@ -422,12 +428,12 @@ public class JFrameAI extends JFrame implements ActionListener {
 
 
         currentChatIndex = answerPane.getSelectedIndex();
-        switch(currentChatIndex) {
+        switch (currentChatIndex) {
             case 0:
                 if (selectedChat.aiInteract instanceof ai.AIBlock) {
                     applyIdentifySystemBlocks(selectedChat.aiInteract.applyAnswer(null));
                 } else if (selectedChat.aiInteract instanceof ai.AIBlockConnAttrib) {
-                        applyIdentifySystemBlocks(selectedChat.aiInteract.applyAnswer(null));
+                    applyIdentifySystemBlocks(selectedChat.aiInteract.applyAnswer(null));
                 } else if (selectedChat.aiInteract instanceof ai.AISoftwareBlock) {
                     applyIdentifySystemBlocks(selectedChat.aiInteract.applyAnswer(null));
                 } else if (selectedChat.aiInteract instanceof ai.AIReqIdent) {
@@ -439,13 +445,16 @@ public class JFrameAI extends JFrame implements ActionListener {
                 } else if (selectedChat.aiInteract instanceof ai.AIStateMachine) {
                     TraceManager.addDev("Applying state machines");
                     applyIdentifyStateMachines(selectedChat.aiInteract.applyAnswer(null));
+                } else if (selectedChat.aiInteract instanceof ai.AIStateMachinesAndAttributes) {
+                    TraceManager.addDev("Applying state machines and attributes");
+                    applyIdentifyStateMachines(selectedChat.aiInteract.applyAnswer(null));
                 } else if (selectedChat.aiInteract instanceof ai.AIAmulet) {
                     applyMutations();
                 }
                 break;
-                case 1:
-                    applyRequirementIdentification();
-                    break;
+            case 1:
+                applyRequirementIdentification();
+                break;
             case 2:
                 applyRequirementClassification();
                 break;
@@ -542,7 +551,7 @@ public class JFrameAI extends JFrame implements ActionListener {
         ChatData selected = selectedChat();
         for (TGComponent tgc : rdpanel.getAllRequirements()) {
             AvatarRDRequirement req = (AvatarRDRequirement) tgc;
-            String kind = (String)(selected.aiInteract.applyAnswer(req.getValue()));
+            String kind = (String) (selected.aiInteract.applyAnswer(req.getValue()));
             if (kind != null) {
                 String k = JDialogRequirement.getKindFromString(kind);
                 if (k != null) {
@@ -558,7 +567,7 @@ public class JFrameAI extends JFrame implements ActionListener {
         rdpanel.repaint();
     }
 
-    private void applyMutations(){
+    private void applyMutations() {
         //AvatarSpecification avspec = mgui.gtm.getAvatarSpecification();
         TDiagramPanel tdp = mgui.getCurrentTDiagramPanel();
         if (!(tdp instanceof AvatarBDPanel)) {
@@ -575,13 +584,13 @@ public class JFrameAI extends JFrame implements ActionListener {
 
         AvatarSpecification avspec = mgui.gtm.getAvatarSpecification();
 
-        if (avspec == null){
+        if (avspec == null) {
             error("AVATAR specification not found: aborting.\n");
             return;
         }
 
         inform("Applying mutations to the model, please wait\n");
-        avspec = (AvatarSpecification) (selectedChat().aiInteract.applyAnswer( avspec ));
+        avspec = (AvatarSpecification) (selectedChat().aiInteract.applyAnswer(avspec));
 
         if (avspec != null) {
             mgui.drawAvatarSpecification(avspec);