diff --git a/src/main/java/avatartranslator/AvatarExpressionSolver.java b/src/main/java/avatartranslator/AvatarExpressionSolver.java
new file mode 100644
index 0000000000000000000000000000000000000000..bc7ee7060e894a6c7696e72abc02d999a72573e1
--- /dev/null
+++ b/src/main/java/avatartranslator/AvatarExpressionSolver.java
@@ -0,0 +1,666 @@
+/* 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;
+
+import avatartranslator.modelchecker.SpecificationBlock;
+import avatartranslator.modelchecker.SpecificationState;
+
+/**
+ * Class AvatarExpressionSolver
+ * Avatar Expression Solver
+ * Creation: 17/04/2020
+ *
+ * @author Alessandro TEMPIA CALVINO
+ * @version 1.0 17/04/2020
+ */
+public class AvatarExpressionSolver {
+    private static final int IMMEDIATE_NO = 0;
+    private static final int IMMEDIATE_INT = 1;
+    
+    private AvatarExpressionSolver left, right;
+    private char operator;
+    private String expression;
+    private boolean isLeaf; //variable
+    private boolean isNot;
+    private boolean isNegated;
+    private int isImmediateValue; //0: No; 1: Boolean; 2: Int
+    private int intValue;
+    private AvatarExpressionAttribute leaf;
+    
+    
+    public AvatarExpressionSolver() {
+        left = null;
+        right = null;
+        isLeaf = true;
+        isImmediateValue = IMMEDIATE_NO;
+        intValue = 0;
+    }
+    
+    public AvatarExpressionSolver(String expression) {
+        this.expression = expression.trim();
+        replaceOperators();
+        left = null;
+        right = null;
+        isLeaf = true;
+        isImmediateValue = IMMEDIATE_NO;
+        intValue = 0;
+        isNot = false;
+        isNegated = false;
+    }
+    
+    
+    public void setExpression(String expression) {
+        this.expression = expression;
+        replaceOperators();
+    }
+    
+    public boolean buildExpression(AvatarSpecification spec) {
+        boolean returnVal;
+        
+        removeUselessBrackets();
+        
+        if (!expression.matches("^.+[\\+\\-<>=:;\\$&\\|\\*/].*$")) {
+            // leaf
+            isLeaf = true;
+            checkNot();
+            checkNegated();
+            checkNegatedNoBrackets();
+            if (expression.equals("true")) {
+                intValue = 1;
+                isImmediateValue = IMMEDIATE_INT;
+                returnVal = true;
+            } else if (expression.equals("false")) {
+                intValue = 0;
+                isImmediateValue = IMMEDIATE_INT;
+                returnVal = true;
+            } else if (expression.matches("-?\\d+")) {
+                intValue = Integer.parseInt(expression);
+                isImmediateValue = IMMEDIATE_INT;
+                returnVal = true;
+            } else {
+                leaf = new AvatarExpressionAttribute(spec, expression);
+                returnVal = !leaf.hasError();
+            }
+            //System.out.println("Variable " + expression + "\n");
+            return returnVal;
+        }
+        
+        isLeaf = false;
+        
+        returnVal = checkNot();
+        returnVal &= checkNegated();
+        
+        if (!returnVal) {
+            return false;
+        }
+        
+        int index = getOperatorIndex();
+        
+        if (index == -1) {
+            return false;
+        }
+        
+        operator = expression.charAt(index);
+        
+        //split and recur
+        String leftExpression = expression.substring(0, index).trim();
+        String rightExpression = expression.substring(index + 1, expression.length()).trim();
+        
+        left = new AvatarExpressionSolver(leftExpression);
+        right = new AvatarExpressionSolver(rightExpression);
+        //System.out.println("Expression " + expression + " ; " + leftExpression + " ; " + rightExpression + "\n");  
+        returnVal = left.buildExpression(spec);
+        returnVal &= right.buildExpression(spec);   
+        
+        return returnVal;
+    }
+    
+    public boolean buildExpression(AvatarBlock block) {
+        boolean returnVal;
+        
+        removeUselessBrackets();
+
+        if (!expression.matches("^.+[\\+\\-<>=:;\\$&\\|\\*/].*$")) {
+            // leaf
+            isLeaf = true;
+            checkNot();
+            checkNegated();
+            checkNegatedNoBrackets();
+            if (expression.equals("true")) {
+                intValue = 1;
+                isImmediateValue = IMMEDIATE_INT;
+                returnVal = true;
+            } else if (expression.equals("false")) {
+                intValue = 0;
+                isImmediateValue = IMMEDIATE_INT;
+                returnVal = true;
+            } else if (expression.matches("-?\\d+")) {
+                intValue = Integer.parseInt(expression);
+                isImmediateValue = IMMEDIATE_INT;
+                returnVal = true;
+            } else {
+                leaf = new AvatarExpressionAttribute(block, expression);
+                returnVal = !leaf.hasError();
+            }
+            //System.out.println("Variable " + expression + "\n");
+            return returnVal;
+        }
+        
+        isLeaf = false;
+        
+        returnVal = checkNot();
+        returnVal &= checkNegated();
+        
+        if (!returnVal) {
+            return false;
+        }
+        
+        int index = getOperatorIndex();
+        
+        if (index == -1) {
+            return false;
+        }
+        
+        operator = expression.charAt(index);
+        
+        //split and recur
+        String leftExpression = expression.substring(0, index).trim();
+        String rightExpression = expression.substring(index + 1, expression.length()).trim();
+        
+        left = new AvatarExpressionSolver(leftExpression);
+        right = new AvatarExpressionSolver(rightExpression);
+        //System.out.println("Expression " + expression + " ; " + leftExpression + " ; " + rightExpression + "\n");  
+        returnVal = left.buildExpression(block);
+        returnVal &= right.buildExpression(block);
+        
+        return returnVal;
+    }
+    
+    public boolean builExpression(AvatarExpressionAttribute attribute) {
+        this.expression = attribute.toString();
+        isLeaf = true;
+        isImmediateValue = IMMEDIATE_NO;
+        leaf = attribute;
+        return true;
+    }
+    
+    public boolean buildExpression() {
+        boolean returnVal;
+        
+        removeUselessBrackets();
+
+        if (!expression.matches("^.+[\\+\\-<>=:;\\$&\\|\\*/].*$")) {
+            // leaf
+            isLeaf = true;
+            checkNot();
+            checkNegated();
+            checkNegatedNoBrackets();
+            if (expression.equals("true")) {
+                intValue = 1;
+                isImmediateValue = IMMEDIATE_INT;
+                returnVal = true;
+            } else if (expression.equals("false")) {
+                intValue = 0;
+                isImmediateValue = IMMEDIATE_INT;
+                returnVal = true;
+            } else if (expression.matches("-?\\d+")) {
+                intValue = Integer.parseInt(expression);
+                isImmediateValue = IMMEDIATE_INT;
+                returnVal = true;
+            } else {
+                returnVal = false;
+            }
+            //System.out.println("Variable " + expression + "\n");
+            return returnVal;
+        }
+        
+        isLeaf = false;
+        
+        returnVal = checkNot();
+        returnVal &= checkNegated();
+        
+        if (!returnVal) {
+            return false;
+        }
+        
+        int index = getOperatorIndex();
+        
+        if (index == -1) {
+            return false;
+        }
+        
+        operator = expression.charAt(index);
+        
+        //split and recur
+        String leftExpression = expression.substring(0, index).trim();
+        String rightExpression = expression.substring(index + 1, expression.length()).trim();
+        
+        left = new AvatarExpressionSolver(leftExpression);
+        right = new AvatarExpressionSolver(rightExpression);
+        //System.out.println("Expression " + expression + " ; " + leftExpression + " ; " + rightExpression + "\n");  
+        returnVal = left.buildExpression();
+        returnVal &= right.buildExpression();
+        
+        return returnVal;
+    }
+    
+    private void replaceOperators() {
+        expression = expression.replaceAll("\\|\\|", "\\|").trim();
+        expression = expression.replaceAll("&&", "&").trim();
+        expression = expression.replaceAll("==", "=").trim();
+        expression = expression.replaceAll("!=", "\\$").trim();
+        expression = expression.replaceAll(">=", ":").trim();
+        expression = expression.replaceAll("<=", ";").trim(); 
+        expression = expression.replaceAll("\\bor\\b", "\\|").trim();
+        expression = expression.replaceAll("\\band\\b", "&").trim();
+        //expression.replaceAll("\\btrue\\b", "t").trim();
+        //expression.replaceAll("\\bfalse\\b", "f").trim(); 
+    }
+    
+    private boolean checkNot() {
+        if (expression.startsWith("not(")) {
+            //not bracket must be closed in the last char
+            int closingIndex = getClosingBracket(4);
+            
+            if (closingIndex == -1) {
+                return false;
+            }
+            if (closingIndex == expression.length() - 1) {
+              //not(expression)
+                isNot = true;
+                expression = expression.substring(4, expression.length() - 1).trim();
+            }
+        }
+        return true;
+    }
+    
+    private boolean checkNegated() {
+        if (expression.startsWith("-(")) {
+            //not bracket must be closed in the last char
+            int closingIndex = getClosingBracket(2);
+            
+            if (closingIndex == -1) {
+                return false;
+            }
+            if (closingIndex == expression.length() - 1) {
+              //-(expression)
+                isNegated = true;
+                expression = expression.substring(2, expression.length() - 1).trim();
+            }
+        }
+        return true;
+    }
+    
+    private boolean checkNegatedNoBrackets() {
+        if (expression.startsWith("-")) {     
+            isNegated = true;
+            expression = expression.substring(1, expression.length()).trim();
+        }
+        return true;
+    }
+    
+    private int getOperatorIndex() {
+        int index;
+        // find the last executed operator
+        int i, level, priority;
+        boolean subVar = true; //when a subtraction is only one one variable
+        char a;
+        level = 0;
+        priority = 0;
+        for (i = 0, index = -1; i < expression.length(); i++) {
+            a = expression.charAt(i);
+            switch (a) {
+            case '=':
+                if (level == 0) {
+                    index = i;
+                    priority = 2;
+                }
+                subVar = true;
+                break;
+            case '$':
+                if (level == 0) {
+                    index = i;
+                    priority = 2;
+                }
+                subVar = true;
+                break;
+            case '<':
+                if (level == 0) {
+                    index = i;
+                    priority = 2;
+                }
+                subVar = true;
+                break;
+            case '>':
+                if (level == 0) {
+                    index = i;
+                    priority = 2;
+                }
+                subVar = true;
+                break;
+            case ':':
+                if (level == 0) {
+                    index = i;
+                    priority = 2;
+                }
+                subVar = true;
+                break;
+            case ';':
+                if (level == 0) {
+                    index = i;
+                    priority = 2;
+                }
+                subVar = true;
+                break;
+            case '-':
+                if (level == 0 && !subVar && priority < 2) {
+                    index = i;
+                    priority = 1;
+                }
+                break;
+            case '+':
+                if (level == 0 && !subVar && priority < 2) {
+                    index = i;
+                    priority = 1;
+                }
+                break;
+            case '|':
+                if (level == 0 && priority < 2) {
+                    index = i;
+                    priority = 1;
+                }
+                break;
+            case '/':
+                if (level == 0  && priority == 0) {
+                    index = i;
+                }
+                break;
+            case '*':
+                if (level == 0  && priority == 0) {
+                    index = i;
+                }
+                break;
+            case '&':
+                if (level == 0  && priority == 0) {
+                    index = i;
+                }
+                break;
+            case '(':
+                level++;
+                subVar = true;
+                break;
+            case ')':
+                level--;
+                subVar = false;
+                break;
+            case ' ':
+                break;
+            default:
+                subVar = false;
+                break;
+            }
+        }
+        return index;
+    }
+    
+    public int getResult() {
+        int res;
+        if (isLeaf) {
+            if (isImmediateValue == IMMEDIATE_INT) {
+                res = intValue;
+            } else {
+                return 0;
+            }
+        } else {
+            res = getChildrenResult(left.getResult(), right.getResult());
+        }
+        
+        if (isNot) {
+            res = (res == 0) ? 1 : 0;
+        } else if (isNegated) {
+            res = -res;
+        }       
+        return res;
+    }
+    
+    public int getResult(SpecificationState ss) {
+        int res;
+        if (isLeaf) {
+            if (isImmediateValue == IMMEDIATE_INT) {
+                res = intValue;
+            } else {
+                res = leaf.getValue(ss);
+            }
+        } else {
+            res = getChildrenResult(left.getResult(ss), right.getResult(ss));
+        }
+        
+        if (isNot) {
+            res = (res == 0) ? 1 : 0;
+        } else if (isNegated) {
+            res = -res;
+        }
+        return res;
+    }
+    
+    public int getResult(SpecificationState ss, AvatarStateMachineElement asme) {
+        int res;
+        if (isLeaf) {
+            if (isImmediateValue == IMMEDIATE_INT) {
+                res = intValue;
+            } else {
+                res = leaf.getValue(ss, asme);
+            }
+        } else {
+            res = getChildrenResult(left.getResult(ss, asme), right.getResult(ss, asme));
+        }
+        
+        if (isNot) {
+            res = (res == 0) ? 1 : 0;
+        } else if (isNegated) {
+            res = -res;
+        }
+        return res;
+    }
+    
+    public int getResult(SpecificationBlock sb) {
+        int res;
+        if (isLeaf) {
+            if (isImmediateValue == IMMEDIATE_INT) {
+                res = intValue;
+            } else {
+                res = leaf.getValue(sb);
+            }
+        } else {
+            res = getChildrenResult(left.getResult(sb), right.getResult(sb));
+        }
+        
+        if (isNot) {
+            res = (res == 0) ? 1 : 0;
+        } else if (isNegated) {
+            res = -res;
+        }
+        return res;
+    }
+    
+    private int getChildrenResult(int leftV, int rightV) {
+        int result;
+        
+        switch (operator) {
+        case '=':
+            result = (leftV == rightV) ? 1 : 0;
+            break;
+        case '$':
+            result = (leftV != rightV) ? 1 : 0;
+            break;
+        case '<':
+            result = (leftV < rightV) ? 1 : 0;
+            break;
+        case '>':
+            result = (leftV > rightV) ? 1 : 0;
+            break;
+        case ':':
+            result = (leftV >= rightV) ? 1 : 0;
+            break;
+        case ';':
+            result = (leftV <= rightV) ? 1 : 0;
+            break;
+        case '-':
+            result = leftV - rightV;
+            break;
+        case '+':
+            result = leftV + rightV;
+            break;
+        case '|':
+            result = (leftV == 0 && rightV == 0) ? 0 : 1;
+            break;
+        case '/':
+            result = leftV / rightV;
+            break;
+        case '*':
+            result = leftV * rightV;
+            break;
+        case '&':
+            result = (leftV == 0 || rightV == 0) ? 0 : 1;
+            break;
+        default:
+            //System.out.println("Error in EquationSolver::getResult");
+            result = 0;
+            break;
+        }
+        //System.out.println(leftV + " " + operator + " " + rightV + " = " + result);
+        return result;
+    }
+    
+    public String toString() {
+        String retS;
+        if (isLeaf) {
+            if (isImmediateValue == IMMEDIATE_NO) {
+                retS = leaf.toString();
+            } else {
+                retS = String.valueOf(intValue);
+            }
+            if (isNegated) {
+                retS = "-(" + retS + ")";
+            }
+            if (isNot) {
+                retS = "not(" + retS + ")";
+            }
+        } else {
+            String leftString = left.toString();
+            String rightString = right.toString();
+            String opString;
+            switch (operator) {
+            case '=':
+                opString = "==";
+                break;
+            case '$':
+                opString = "!=";
+                break;
+            case ':':
+                opString = ">=";
+                break;
+            case ';':
+                opString = "<=";
+                break;
+            case '|':
+                opString = "||";
+                break;
+            case '&':
+                opString = "&&";
+                break;
+            default:
+                opString = "" + operator;
+                break;
+            }
+            retS = "(" + leftString + " " + opString + " " + rightString + ")";
+            if (isNegated) {
+                retS = "-" + retS;
+            }
+            if (isNot) {
+                retS = "not" + retS;
+            }
+        }
+        return retS;
+    }
+    
+    public boolean hasState() {
+        boolean hasState;
+        if (isLeaf) {
+            if (isImmediateValue == IMMEDIATE_NO) {
+                return leaf.isState();
+            } else {
+                return false;
+            }
+        } else {
+            hasState = left.hasState();
+            hasState |= right.hasState();
+            return hasState;
+        }
+    }
+    
+    private void removeUselessBrackets() {
+        while (expression.startsWith("(") && expression.endsWith(")")) {
+            if (getClosingBracket(1) == expression.length() - 1) {
+                expression = expression.substring(1, expression.length() - 1).trim();
+            } else {
+                break;
+            }
+        }
+    }
+    
+    private int getClosingBracket(int startChar) {
+        int level = 0;
+        char a;
+        for (int i = startChar; i < expression.length(); i++) {
+            a = expression.charAt(i);
+            if (a == ')') {
+                if (level == 0) {
+                    return i;
+                } else {
+                    level--;
+                }
+            } else if (a == '(') {
+                level++;
+            }
+        }
+        return -1;
+    }
+
+}