src.planning.PlanSimulator.java Source code

Java tutorial

Introduction

Here is the source code for src.planning.PlanSimulator.java

Source

/*** 
* itSIMPLE: Integrated Tool Software Interface for Modeling PLanning Environments
* 
* Copyright (C) 2007-2012 University of Sao Paulo
* 
*
* This file is part of itSIMPLE.
*
* itSIMPLE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. Other licenses might be available
* upon written agreement.
* 
* itSIMPLE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
* 
* You should have received a copy of the GNU General Public License
* along with itSIMPLE.  If not, see <http://www.gnu.org/licenses/>.
* 
* Authors:   Tiago S. Vaquero, 
*         Victor Romero.
**/

package src.planning;

import java.awt.Dimension;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;
import javax.swing.JLabel;
import org.jaxen.JaxenException;
import org.jaxen.XPath;
import org.jaxen.jdom.JDOMXPath;
import org.jdom.Element;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.SymbolAxis;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

import src.gui.ItSIMPLE;
import src.languages.uml.ocl.ExpressionTreeBuilder;
import src.languages.uml.ocl.OCLUtilities;
import src.languages.xml.XMLUtilities;

public class PlanSimulator {

    private static final String changeColor = "009900";
    private static Element theproblem = null;
    private static Element thedomain = null;
    private static Element theproject = null;

    /**
      * In the simulation process it creates the next state given a 'from'
      * snapshot and a action with its parameters
      * @param action
      * @param parameters
      * @param snapshot
      * @param domain
      * @param project
      * @return
      */
    public static Element nextState(String action, List<String> parameters, Element snapshot, Element domain,
            Element project) {
        //System.out.println("Action: " + action + " " +parameters);

        Element next = null;
        //1. look for the operator in the domain
        Element domainOperator = null;
        try {
            XPath path = new JDOMXPath(
                    "elements/classes/class/operators/operator[lower-case(name)='" + action.toLowerCase() + "']");
            domainOperator = (Element) path.selectSingleNode(project);

        } catch (JaxenException e) {
            e.printStackTrace();
        }
        if (domainOperator != null) {
            //2. initialize an action node
            Element instanceAction = new Element("action");
            instanceAction.addContent((Element) domainOperator.getChild("name").clone());

            //3. look for the same action at the state diagrams
            Element actionConditions = OCLUtilities.buildConditions(domainOperator);

            //XMLUtilities.printXML(actionConditions);

            //4. build the precondition and postcondition
            List<?> preconditions = null;
            try {
                XPath path = new JDOMXPath("preconditions/descendant::condition");
                preconditions = path.selectNodes(actionConditions);
            } catch (JaxenException e) {
                e.printStackTrace();
            }
            String oclpreExpression = "";
            for (Iterator<?> iter = preconditions.iterator(); iter.hasNext();) {
                Element condition = (Element) iter.next();
                oclpreExpression += condition.getText().trim();

                if (iter.hasNext()) {
                    oclpreExpression += " and ";
                }
            }

            List<?> postconditions = null;
            try {
                XPath path = new JDOMXPath("postconditions/descendant::condition");
                postconditions = path.selectNodes(actionConditions);
            } catch (JaxenException e) {
                e.printStackTrace();
            }
            String oclpostExpression = "";
            for (Iterator<?> iter = postconditions.iterator(); iter.hasNext();) {
                Element condition = (Element) iter.next();
                oclpostExpression += condition.getText().trim();

                if (iter.hasNext()) {
                    oclpostExpression += " and ";
                }
            }

            //System.out.println(oclpreExpression);
            //System.out.println(oclpostExpression);
            //5. create the expression tree

            ExpressionTreeBuilder pretreeBuilder = new ExpressionTreeBuilder(oclpreExpression);
            Element preexpTree = pretreeBuilder.getExpressionTree();
            //XMLUtilities.printXML(preexpTree);            

            ExpressionTreeBuilder treeBuilder = new ExpressionTreeBuilder(oclpostExpression);
            Element expTree = treeBuilder.getExpressionTree();
            //XMLUtilities.printXML(expTree);

            //6.0 set up action parameters.
            Element instanceParameters = new Element("parameters");
            int index = 0;

            //if expressions use 'self', add the class to the parameter list
            //look for self parameterin the precondition
            Element selfParamNodePre = null;
            try {
                XPath path = new JDOMXPath("descendant::node[@data='self' and @instance='f']");
                selfParamNodePre = (Element) path.selectSingleNode(preexpTree);
            } catch (JaxenException e) {
                e.printStackTrace();
            }
            //look for self parameterin the postcondition
            Element selfParamNodePost = null;
            try {
                XPath path = new JDOMXPath("descendant::node[@data='self' and @instance='f']");
                selfParamNodePost = (Element) path.selectSingleNode(expTree);
            } catch (JaxenException e) {
                e.printStackTrace();
            }
            if (selfParamNodePre != null || selfParamNodePost != null) {

                Element instanceParam = new Element("parameter");
                //System.out.println("added\n");

                Element paramName = new Element("name");
                paramName.setText("self");
                Element paramType = new Element("type");
                paramType.setText(domainOperator.getParentElement().getParentElement().getAttributeValue("id"));
                Element paramValue = new Element("value");
                paramValue.setText(parameters.get(index++));

                instanceParam.addContent(paramName);
                instanceParam.addContent(paramType);
                instanceParam.addContent(paramValue);

                instanceParameters.addContent(instanceParam);

            }

            for (Iterator<?> iter = domainOperator.getChild("parameters").getChildren("parameter").iterator(); iter
                    .hasNext();) {
                Element opParam = (Element) iter.next();
                Element instanceParam = new Element("parameter");

                Element paramValue = new Element("value");
                paramValue.setText(parameters.get(index++));
                instanceParam.addContent((Element) opParam.getChild("name").clone());
                instanceParam.addContent((Element) opParam.getChild("type").clone());
                instanceParam.addContent(paramValue);

                instanceParameters.addContent(instanceParam);
            }
            instanceAction.addContent(instanceParameters);
            instanceAction.addContent(new Element("precondition"));
            instanceAction.addContent(new Element("postcondition"));
            //XMLUtilities.printXML(instanceAction);

            //6.1 replace the parameters values
            for (Iterator<?> iter = instanceAction.getChild("parameters").getChildren("parameter").iterator(); iter
                    .hasNext();) {
                Element parameter = (Element) iter.next();
                //XMLUtilities.printXML(parameter);
                // look for the parameters in the tree
                List<?> expTreeParameters = null;
                try {
                    XPath path = new JDOMXPath(
                            "descendant::node[@data='" + parameter.getChildText("name") + "' and @instance='f']");
                    expTreeParameters = path.selectNodes(expTree);
                } catch (JaxenException e) {
                    e.printStackTrace();
                }
                for (Iterator<?> iterator = expTreeParameters.iterator(); iterator.hasNext();) {
                    Element expTreeParam = (Element) iterator.next();
                    expTreeParam.setAttribute("data", parameter.getChildText("value"));
                    expTreeParam.setAttribute("instance", "t");
                }
            }
            //XMLUtilities.printXML(expTree);

            //7. evaluate the expression tree
            //7.1 checks if the expression tree root is an "and" node
            // if it's not, add the expression tree to a list so it can be iterated
            // this is done just to avoid code repetition
            List<Element> children;
            if (expTree.getAttributeValue("data").equals("and")) {
                children = expTree.getChildren();
            } else {
                children = new ArrayList<Element>();
                children.add(expTree);
            }

            List<Element> nodesToBeAdded = new ArrayList<Element>();
            List<Element> nodesToBeDeleted = new ArrayList<Element>();
            for (Iterator<?> iter = children.iterator(); iter.hasNext();) {
                Element node = (Element) iter.next();
                if (node.getAttributeValue("data").equals("=")) {
                    // node with expression
                    Element left = (Element) node.getChildren().get(0);
                    Element right = (Element) node.getChildren().get(1);

                    Element attrOrAssoc = null;
                    // get the attribute being set
                    if (left.getAttributeValue("data").equals(".")) {
                        attrOrAssoc = (Element) left.getChildren().get(1);
                    } else if (left.getAttributeValue("type").equals("opd")) {
                        attrOrAssoc = left;
                    }

                    //               check whether the attribute is parameterized
                    String attrOrAssocData = attrOrAssoc.getAttributeValue("data");
                    String attrOrAssocName;

                    if (attrOrAssocData.indexOf('(') > 0) {
                        // the attribute is parameterized
                        // replace the parameter values
                        attrOrAssocName = attrOrAssocData.substring(0, attrOrAssocData.indexOf('('));
                        String attrParameters = attrOrAssocData.substring(attrOrAssocData.indexOf('(') + 1,
                                attrOrAssocData.lastIndexOf(')'));
                        String attrValues = "(";
                        StringTokenizer st = new StringTokenizer(attrParameters, ",");
                        while (st.hasMoreTokens()) {
                            String parameter = st.nextToken().trim().toLowerCase();
                            Element instanceParameter = null;
                            try {
                                XPath path = new JDOMXPath("parameter[lower-case(name)='" + parameter + "']");
                                instanceParameter = (Element) path.selectSingleNode(instanceParameters);
                            } catch (JaxenException e) {
                                e.printStackTrace();
                            }
                            if (instanceParameter != null) {
                                attrValues += instanceParameter.getChildText("value");

                                if (st.hasMoreTokens()) {
                                    attrValues += ",";
                                }
                            } else {
                                //System.out.println("Parameter \""+ parameter +"\" not found in parameters list.");
                                //TODO: Check if it is a literal
                                Element literal = null;
                                try {
                                    XPath path = new JDOMXPath(
                                            "project/elements/classes/enumeration/literals/literal[lower-case(name)='"
                                                    + parameter + "']");
                                    literal = (Element) path.selectSingleNode(domain.getDocument());
                                } catch (JaxenException e) {
                                    e.printStackTrace();
                                }
                                if (literal != null) {
                                    attrValues += parameter;
                                } else {
                                    attrValues += "#error";
                                }

                            }
                        }
                        attrValues += ")";

                        String newAttrData = attrOrAssocName + attrValues;
                        attrOrAssoc.setAttribute("data", newAttrData);
                        attrOrAssoc.setAttribute("instance", "t");
                    } else {
                        attrOrAssocName = attrOrAssocData;
                    }

                    if (right.getAttributeValue("type").equals("opr")) {
                        // deal with int and float difference
                        // look for the type of the attribute (int or float)
                        Element modelAttrOrAssoc = null;
                        try {
                            XPath path = new JDOMXPath(
                                    "elements/classes/class/attributes/attribute[lower-case(name)='"
                                            + attrOrAssocName.toLowerCase() + "'] | elements/classAssociations/"
                                            + "classAssociation[associationEnds/associationEnd/rolename[lower-case(value)='"
                                            + attrOrAssocName.toLowerCase() + "'] or lower-case(name)='"
                                            + attrOrAssocName.toLowerCase() + "']");
                            modelAttrOrAssoc = (Element) path.selectSingleNode(project);
                        } catch (JaxenException e) {
                            e.printStackTrace();
                        }
                        if (modelAttrOrAssoc != null) {
                            //Element newRight = evaluateExpressionNode(right, instanceParameters, snapshot, domain, project);                     
                            Element newRight = evaluateExpressionNodeInSnapshot(right, instanceParameters, snapshot,
                                    domain, project);

                            if (modelAttrOrAssoc.getChild("type") != null
                                    && modelAttrOrAssoc.getChildText("type").equals("2")) {//int
                                int value = (int) Double.parseDouble(newRight.getAttributeValue("data"));
                                newRight.setAttribute("data", String.valueOf(value));
                                newRight.setAttribute("instance", "t");
                            }

                            if (newRight != null) {
                                node.removeContent(right);
                                node.addContent(newRight);
                            } else {
                                //System.out.println("Error in evaluating procces");
                            }
                        }

                    }

                }

                else if (node.getAttributeValue("data").equals("->")) {
                    Element left = (Element) node.getChildren().get(0);
                    Element right = (Element) node.getChildren().get(1);

                    // operations
                    if (right.getAttributeValue("type").equals("opn")) {

                        // forAll
                        if (right.getAttributeValue("data").equals("forAll")) {
                            // the left node represents a lisf of objects
                            //Element newLeft = evaluateExpressionNode(left, instanceParameters, snapshot, domain, project);
                            Element newLeft = evaluateExpressionNodeInSnapshot(left, instanceParameters, snapshot,
                                    domain, project);

                            // get forAll parameters (only one is supported currently)
                            List<?> forAllParameters = null;
                            try {
                                XPath path = new JDOMXPath("node[@type='par']");
                                forAllParameters = path.selectNodes(right);
                            } catch (JaxenException e) {
                                e.printStackTrace();
                            }

                            if (forAllParameters != null && forAllParameters.size() == 1) {
                                Element forAllParam = (Element) forAllParameters.get(0);
                                String paramData = forAllParam.getAttributeValue("data");
                                String paramName = paramData.substring(0, paramData.indexOf(':'));
                                int i = paramData.indexOf(':');
                                String paramType = "";
                                if (i > 0) {
                                    paramType = paramData.substring(i + 1, paramData.length());
                                }

                                // get the model class representing the parameter type (if any)
                                Element modelClass = null;
                                if (!paramType.equals("")) {
                                    try {
                                        XPath path = new JDOMXPath("elements/classes/class[lower-case(name)='"
                                                + paramType.toLowerCase() + "']");
                                        modelClass = (Element) path.selectSingleNode(project);
                                    } catch (JaxenException e) {
                                        e.printStackTrace();
                                    }
                                }

                                for (Iterator<?> iterator = newLeft.getChildren().iterator(); iterator.hasNext();) {

                                    Element object = (Element) iterator.next();

                                    // look for the model object
                                    Element modelObject = null;
                                    try {
                                        XPath path = new JDOMXPath("elements/objects/object[lower-case(name)='"
                                                + object.getAttributeValue("data").toLowerCase() + "']");
                                        modelObject = (Element) path.selectSingleNode(domain);
                                    } catch (JaxenException e) {
                                        e.printStackTrace();
                                    }

                                    // if the parameter type is defined, check whether the object
                                    // is an instance of that type
                                    boolean rightType = true;
                                    if (modelClass != null) {
                                        if (!modelObject.getChildText("class")
                                                .equals(modelClass.getAttributeValue("id"))) {
                                            rightType = false;
                                        }
                                    }

                                    if (rightType) {
                                        // clone the node under "suchthat" node and replace
                                        // the forAll parameter with the object name
                                        // this way, for each object, an atribution will be created
                                        Element attributionClone = (Element) ((Element) right.getChildren()
                                                .get(right.getChildren().size() - 1)).getChild("node").clone();

                                        if (attributionClone.getAttributeValue("data").equals("=")) {
                                            //                                  replace the parameter value in all nodes where it appears
                                            List<?> nodesWithParameter = null;
                                            try {
                                                XPath path = new JDOMXPath(
                                                        "descendant::node[@data='" + paramName + "']");
                                                nodesWithParameter = path.selectNodes(attributionClone);
                                            } catch (JaxenException e) {
                                                e.printStackTrace();
                                            }

                                            for (Iterator iterator2 = nodesWithParameter.iterator(); iterator2
                                                    .hasNext();) {
                                                Element nodeWithParameter = (Element) iterator2.next();
                                                nodeWithParameter.setAttribute("data",
                                                        modelObject.getChildText("name").toUpperCase());
                                            }

                                            Element arrowNode = null;
                                            try {
                                                XPath path = new JDOMXPath("descendant::node[@data='->']");
                                                arrowNode = (Element) path.selectSingleNode(attributionClone);
                                            } catch (JaxenException e) {
                                                e.printStackTrace();
                                            }

                                            if (arrowNode != null) {

                                                // get including/excluding node (if any)
                                                Element incOrExc = null;
                                                try {
                                                    XPath path = new JDOMXPath(
                                                            "node[@data='including' or @data='excluding']");
                                                    incOrExc = (Element) path.selectSingleNode(arrowNode);
                                                } catch (JaxenException e) {
                                                    e.printStackTrace();
                                                }

                                                if (incOrExc != null) {
                                                    // replace it in arrowNode place
                                                    arrowNode.getParentElement().addContent(incOrExc.detach());
                                                    arrowNode.detach();
                                                }

                                            }

                                            // add the atribution in the add list
                                            nodesToBeAdded.add((Element) attributionClone);

                                        }
                                    }

                                }

                                // add to the remove list
                                nodesToBeDeleted.add(node);
                            }
                        }
                    }
                }
            }

            for (Iterator iter = nodesToBeDeleted.iterator(); iter.hasNext();) {
                Element toBeDeleted = (Element) iter.next();
                toBeDeleted.detach();
            }

            for (Iterator iter = nodesToBeAdded.iterator(); iter.hasNext();) {
                Element toBeAdded = (Element) iter.next();
                expTree.addContent(toBeAdded);
            }

            //XMLUtilities.printXML(expTree);

            //8. create the next snapshot
            //8.1 clone the current snapshot
            next = (Element) snapshot.clone();

            // reset the colors
            List<?> colors = null;
            try {
                XPath path = new JDOMXPath("descendant::color[text()!='']");
                colors = path.selectNodes(next);

            } catch (JaxenException e) {
                e.printStackTrace();
            }

            for (Iterator<?> iter = colors.iterator(); iter.hasNext();) {
                Element color = (Element) iter.next();
                color.setText("");
            }

            //8.2 for each attribution in the postcondition, make the change it in the snapshot
            List<Element> attributions;
            if (!expTree.getAttributeValue("data").equals("and")) {
                // there is only one node in the tree
                attributions = new ArrayList<Element>();
                attributions.add(expTree);
            } else {
                attributions = expTree.getChildren("node");
            }
            for (Iterator<?> iter = attributions.iterator(); iter.hasNext();) {
                Element node = (Element) iter.next();
                //XMLUtilities.printXML(node);   
                if (node.getAttributeValue("data").equals("=")) {
                    Element left = (Element) node.getChildren().get(0);
                    Element right = (Element) node.getChildren().get(1);

                    //look for the "." (dot) operator (non global attributes) in left
                    if (left.getAttributeValue("data").equals(".")) {

                        // check whether the left node represents an attribute
                        Element objectNode = (Element) left.getChildren().get(0);
                        Element attrOrAssoc = (Element) left.getChildren().get(1);

                        // look for the instance parameter
                        Element instanceParameter = null;
                        try {
                            XPath path = new JDOMXPath("parameter[lower-case(value)='"
                                    + objectNode.getAttributeValue("data").toLowerCase() + "']");
                            instanceParameter = (Element) path.selectSingleNode(instanceParameters);
                        } catch (JaxenException e) {
                            e.printStackTrace();
                        }

                        if (instanceParameter != null) {
                            // look for the object class
                            Element objectClass = null;
                            try {
                                XPath path = new JDOMXPath("elements/classes/class[@id='"
                                        + instanceParameter.getChildText("type") + "']");
                                objectClass = (Element) path.selectSingleNode(project);
                            } catch (JaxenException e) {
                                e.printStackTrace();
                            }
                            if (objectClass != null) {
                                //                        look for the object in the snapshot domain                        
                                Element domainObject = null;
                                try {
                                    XPath path = new JDOMXPath("elements/objects/object[lower-case(name)='"
                                            + instanceParameter.getChildText("value").toLowerCase() + "']");
                                    domainObject = (Element) path.selectSingleNode(domain);
                                } catch (JaxenException e) {
                                    e.printStackTrace();
                                }
                                if (domainObject != null) {
                                    // look for the object in the snapshot
                                    Element snapshotObject = null;
                                    try {
                                        XPath path = new JDOMXPath("objects/object[@id='"
                                                + domainObject.getAttributeValue("id") + "']");
                                        snapshotObject = (Element) path.selectSingleNode(next);
                                    } catch (JaxenException e) {
                                        e.printStackTrace();
                                    }
                                    if (snapshotObject != null) {
                                        // look for an attribute (from class), association (from elements in project) or rolename (from elements in project)
                                        Element oclNode = null;
                                        String oclAttributeStr = attrOrAssoc.getAttributeValue("data");
                                        String attrName;
                                        if (oclAttributeStr.indexOf('(') > 0) {
                                            // parameterized attribute
                                            attrName = oclAttributeStr.substring(0, oclAttributeStr.indexOf('('));
                                        } else {
                                            attrName = oclAttributeStr;
                                        }
                                        try {
                                            XPath path = new JDOMXPath(
                                                    "elements/classes/class/attributes/attribute[lower-case(name)='"
                                                            + attrName.toLowerCase()
                                                            + "'] | elements/classAssociations/classAssociation["
                                                            + "associationEnds/associationEnd/rolename[lower-case(value)='"
                                                            + attrName.toLowerCase() + "'] or lower-case(name)='"
                                                            + attrName.toLowerCase() + "']");
                                            oclNode = (Element) path.selectSingleNode(project);
                                        } catch (JaxenException e) {
                                            e.printStackTrace();
                                        }
                                        if (oclNode != null) {
                                            //attributes
                                            if (oclNode.getName().equals("attribute")) {

                                                List<?> attrParameters = oclNode.getChild("parameters")
                                                        .getChildren("parameter");
                                                if (attrParameters.size() > 0) {
                                                    //parameterized attribute
                                                    String attrParams = oclAttributeStr.substring(
                                                            oclAttributeStr.indexOf('(') + 1,
                                                            oclAttributeStr.lastIndexOf(')'));
                                                    String query = "attributes/attribute[@id='"
                                                            + oclNode.getAttributeValue("id")
                                                            + "']/value/parameterizedValue[";
                                                    StringTokenizer st = new StringTokenizer(attrParams, ",");
                                                    for (Iterator<?> iterator = attrParameters.iterator(); iterator
                                                            .hasNext();) {
                                                        Element attrParam = (Element) iterator.next();
                                                        String paramValue = "";
                                                        if (st.hasMoreTokens()) {
                                                            paramValue = st.nextToken().trim().toLowerCase();
                                                        } else {
                                                            //System.out.println("There are fewer parameters than expected at attribute: "+ oclNode.getChildText("name"));
                                                        }
                                                        query += "parameters/parameter[@id='"
                                                                + attrParam.getAttributeValue("id")
                                                                + "' and lower-case(value)='" + paramValue + "']";

                                                        if (iterator.hasNext()) {
                                                            query += " and ";
                                                        }
                                                    }
                                                    query += "]";

                                                    if (st.hasMoreTokens()) {
                                                        //System.out.println("There are more parameters than expected at attribute: "+ oclNode.getChildText("name"));
                                                    }
                                                    Element parameterizedValue = null;
                                                    try {
                                                        XPath path = new JDOMXPath(query);
                                                        parameterizedValue = (Element) path
                                                                .selectSingleNode(snapshotObject);
                                                    } catch (JaxenException e) {
                                                        e.printStackTrace();
                                                    }
                                                    if (parameterizedValue != null) {
                                                        //System.out.println("Before: "+ domainObject.getChildText("name")+ " - "+ oclNode.getChildText("name"));
                                                        //XMLUtilities.printXML(parameterizedValue);

                                                        //refresh the value in the snapshot                              
                                                        parameterizedValue.getChild("value")
                                                                .setText(right.getAttributeValue("data"));

                                                        //set highlight color
                                                        parameterizedValue.getChild("graphics").getChild("color")
                                                                .setText(changeColor);

                                                        //System.out.println("After:");
                                                        //XMLUtilities.printXML(parameterizedValue);
                                                        //System.out.println("-----------------------------------------------");
                                                    } else {
                                                        //System.out.println("Parameterized value \""+ oclAttributeStr
                                                        //      +"\" not found in snapshot object.");
                                                    }

                                                } else {
                                                    // not parameterized attributes
                                                    Element objectAttribute = null;
                                                    try {
                                                        XPath path = new JDOMXPath("attributes/attribute[@id='"
                                                                + oclNode.getAttributeValue("id") + "' and @class='"
                                                                + oclNode.getParentElement().getParentElement()
                                                                        .getAttributeValue("id")
                                                                + "']");
                                                        objectAttribute = (Element) path
                                                                .selectSingleNode(snapshotObject);
                                                    } catch (JaxenException e) {
                                                        e.printStackTrace();
                                                    }
                                                    if (objectAttribute != null) {
                                                        //check whether the value is to be changed                                    
                                                        if (!right.getAttributeValue("data").toLowerCase()
                                                                .equals(objectAttribute.getChildText("value")
                                                                        .toLowerCase())) {
                                                            //System.out.println("Before: "+ domainObject.getChildText("name")+ " - "+ oclNode.getChildText("name"));
                                                            //XMLUtilities.printXML(objectAttribute);
                                                            // do the change
                                                            objectAttribute.getChild("value")
                                                                    .setText(right.getAttributeValue("data"));

                                                            // set highlight color
                                                            objectAttribute.getChild("graphics").getChild("color")
                                                                    .setText(changeColor);

                                                            //System.out.println("After:");
                                                            //XMLUtilities.printXML(objectAttribute);
                                                            //System.out.println("-----------------------------------------------");
                                                        }
                                                    } else {
                                                        //System.out.println("Attribute \"" + oclAttributeStr + "\" not found in snapshot object.");
                                                    }
                                                }
                                            }

                                            // associations
                                            else if (oclNode.getName().equals("classAssociation")) {

                                                Element targetAssociationEnd = null;
                                                try {
                                                    XPath path = new JDOMXPath(
                                                            "associationEnds/associationEnd[rolename[lower-case(value)='"
                                                                    + oclAttributeStr.toLowerCase() + "']]");
                                                    targetAssociationEnd = (Element) path.selectSingleNode(oclNode);
                                                } catch (JaxenException e) {
                                                    e.printStackTrace();
                                                }

                                                if (targetAssociationEnd == null) {
                                                    // if it's null, there is no rolename, so check navigation
                                                    try {
                                                        XPath path = new JDOMXPath(
                                                                "associationEnds/associationEnd[@navigation='true']");
                                                        targetAssociationEnd = (Element) path
                                                                .selectSingleNode(oclNode);
                                                    } catch (JaxenException e) {
                                                        e.printStackTrace();
                                                    }
                                                }

                                                //TODO case with both association ends navigation true or false is not currently dealed

                                                if (targetAssociationEnd != null) {

                                                    //XMLUtilities.printXML(oclNode);
                                                    //XMLUtilities.printXML(domainObject);
                                                    //rolename
                                                    String objectAssociationEndID = (targetAssociationEnd
                                                            .getAttributeValue("id").equals("1")) ? "2" : "1";
                                                    Element objectAssociation = null;
                                                    try {
                                                        XPath path = new JDOMXPath(
                                                                "associations/objectAssociation[classAssociation='"
                                                                        + oclNode.getAttributeValue("id")
                                                                        + "' and associationEnds/objectAssociationEnd[@element-id='"
                                                                        + domainObject.getAttributeValue("id")
                                                                        + "' and @id='" + objectAssociationEndID
                                                                        + "']]");
                                                        objectAssociation = (Element) path.selectSingleNode(next);
                                                    } catch (JaxenException e) {
                                                        e.printStackTrace();
                                                    }
                                                    if (right.getAttributeValue("data").toLowerCase()
                                                            .equals("null")) {
                                                        //System.out.print("remove");
                                                        if (objectAssociation != null) {
                                                            //XMLUtilities.printXML(objectAssociation);
                                                            // delete the object association
                                                            Element associations = objectAssociation
                                                                    .getParentElement();
                                                            associations.removeContent(objectAssociation);

                                                            //System.out.println("Association removed: " + oclNode.getChildText("name"));                                             
                                                        }
                                                    } else if (right.getAttributeValue("data").equals("set")) {
                                                        // the only currently supported structure is: a.b = a.b->including/excluding(c)

                                                        //Element evalLeft = evaluateExpressionNode(left, instanceParameters, snapshot, domain, project);
                                                        Element evalLeft = evaluateExpressionNodeInSnapshot(left,
                                                                instanceParameters, snapshot, domain, project);

                                                        List<?> leftChildren = evalLeft.getChildren();
                                                        List<?> rightChildren = right.getChildren();

                                                        // if right set has more nodes than left set, it's an including operation
                                                        if (rightChildren.size() > leftChildren.size()) {
                                                            Element rightClone = (Element) right.clone(); // done to keep the expression tree
                                                            for (Iterator<?> iterator = leftChildren
                                                                    .iterator(); iterator.hasNext();) {
                                                                Element leftChild = (Element) iterator.next();
                                                                // look for the child in right set
                                                                Element rightChild = null;
                                                                try {
                                                                    XPath path = new JDOMXPath("node[@data='"
                                                                            + leftChild.getAttributeValue("data")
                                                                            + "']");
                                                                    rightChild = (Element) path
                                                                            .selectSingleNode(rightClone);
                                                                } catch (JaxenException e) {
                                                                    e.printStackTrace();
                                                                }
                                                                if (rightChild != null) {
                                                                    // remove from set
                                                                    rightChild.detach();
                                                                }
                                                            }

                                                            // at the end, the only remaining node in right set is the one to be included
                                                            if (rightClone.getChildren().size() == 1) {
                                                                Element nodeToInclude = rightClone.getChild("node");

                                                                // find the second object, i. e., the object to which the association points
                                                                Element valueObject = null;
                                                                try {
                                                                    XPath path = new JDOMXPath(
                                                                            "elements/objects/object[lower-case(name)='"
                                                                                    + nodeToInclude
                                                                                            .getAttributeValue(
                                                                                                    "data")
                                                                                            .toLowerCase()
                                                                                    + "']");
                                                                    valueObject = (Element) path
                                                                            .selectSingleNode(domain);
                                                                } catch (JaxenException e) {
                                                                    e.printStackTrace();
                                                                }

                                                                if (valueObject != null) {

                                                                    // create a new object association
                                                                    Element commonData = ItSIMPLE.getCommonData();

                                                                    Element newObjectAssociation = (Element) commonData
                                                                            .getChild("definedNodes")
                                                                            .getChild("elements").getChild("model")
                                                                            .getChild("objectAssociation").clone();

                                                                    newObjectAssociation
                                                                            .getChild("classAssociation")
                                                                            .setText(oclNode
                                                                                    .getAttributeValue("id"));

                                                                    Element newSourceAssociationEnd = null;
                                                                    Element newTargetAssociationEnd = null;
                                                                    //(Element)newObjectAssociation.getChild("associationEnds").getChildren("objectAssociationEnd").get(1);
                                                                    try {
                                                                        XPath path = new JDOMXPath(
                                                                                "associationEnds/objectAssociationEnd[@id='"
                                                                                        + targetAssociationEnd
                                                                                                .getAttributeValue(
                                                                                                        "id")
                                                                                        + "']");
                                                                        newTargetAssociationEnd = (Element) path
                                                                                .selectSingleNode(
                                                                                        newObjectAssociation);
                                                                    } catch (JaxenException e) {
                                                                        e.printStackTrace();
                                                                    }

                                                                    if (newTargetAssociationEnd != null) {

                                                                        String sourceId = (newTargetAssociationEnd
                                                                                .getAttributeValue("id")
                                                                                .equals("1")) ? "2" : "1";
                                                                        try {
                                                                            XPath path = new JDOMXPath(
                                                                                    "associationEnds/objectAssociationEnd[@id='"
                                                                                            + sourceId + "']");
                                                                            newSourceAssociationEnd = (Element) path
                                                                                    .selectSingleNode(
                                                                                            newObjectAssociation);
                                                                        } catch (JaxenException e) {
                                                                            e.printStackTrace();
                                                                        }

                                                                        if (newSourceAssociationEnd != null) {

                                                                        }
                                                                    }

                                                                    // 1st association end
                                                                    newSourceAssociationEnd.setAttribute("element",
                                                                            "object");
                                                                    newSourceAssociationEnd.setAttribute(
                                                                            "element-id",
                                                                            domainObject.getAttributeValue("id"));

                                                                    // 2nd association end
                                                                    newTargetAssociationEnd.setAttribute("element",
                                                                            "object");
                                                                    newTargetAssociationEnd.setAttribute(
                                                                            "element-id",
                                                                            valueObject.getAttributeValue("id"));

                                                                    newObjectAssociation.setAttribute("id", String
                                                                            .valueOf(XMLUtilities.getId(snapshot
                                                                                    .getChild("associations"))));

                                                                    //set the highlight color
                                                                    newObjectAssociation.getChild("graphics")
                                                                            .getChild("color").setText(changeColor);

                                                                    // add it to the snapshot
                                                                    next.getChild("associations")
                                                                            .addContent(newObjectAssociation);

                                                                    //System.out.println("Object association created: "
                                                                    //      + oclNode.getChildText("name")+ " " 
                                                                    //      + domainObject.getChildText("name")+ " ---- " + valueObject.getChildText("name"));      
                                                                    //System.out.println("-----------------------------------------------");
                                                                }
                                                            } else {
                                                                //System.out.println("ERROR: Set has more nodes than expected");
                                                            }

                                                        }

                                                        // if left set has more nodes than right set, it's an excluding operation
                                                        else if (leftChildren.size() > rightChildren.size()) {
                                                            for (Iterator<?> iterator = rightChildren
                                                                    .iterator(); iterator.hasNext();) {
                                                                Element rightChild = (Element) iterator.next();
                                                                // look for the child in right set
                                                                Element leftChild = null;
                                                                try {
                                                                    XPath path = new JDOMXPath("node[@data='"
                                                                            + rightChild.getAttributeValue("data")
                                                                            + "']");
                                                                    leftChild = (Element) path
                                                                            .selectSingleNode(evalLeft);
                                                                } catch (JaxenException e) {
                                                                    e.printStackTrace();
                                                                }
                                                                if (rightChild != null) {
                                                                    // remove from set
                                                                    leftChild.detach();
                                                                }
                                                            }

                                                            // at the end, the only remaining node in left is the one to be excluded
                                                            if (evalLeft.getChildren().size() == 1) {
                                                                Element nodeToExclude = evalLeft.getChild("node");

                                                                Element valueObject = null;
                                                                try {
                                                                    XPath path = new JDOMXPath(
                                                                            "elements/objects/object[lower-case(name)='"
                                                                                    + nodeToExclude
                                                                                            .getAttributeValue(
                                                                                                    "data")
                                                                                            .toLowerCase()
                                                                                    + "']");
                                                                    valueObject = (Element) path
                                                                            .selectSingleNode(domain);
                                                                } catch (JaxenException e) {
                                                                    e.printStackTrace();
                                                                }
                                                                if (valueObject != null) {
                                                                    //String objectAssociationEndID = (associationEnd.getAttributeValue("id").equals("1")) ?"2" :"1";
                                                                    Element association = null;
                                                                    try {
                                                                        XPath path = new JDOMXPath(
                                                                                "associations/objectAssociation[classAssociation='"
                                                                                        + oclNode.getAttributeValue(
                                                                                                "id")
                                                                                        + "' and associationEnds/objectAssociationEnd[@element-id='"
                                                                                        + valueObject
                                                                                                .getAttributeValue(
                                                                                                        "id")
                                                                                        + "' and @id='"
                                                                                        + targetAssociationEnd
                                                                                                .getAttributeValue(
                                                                                                        "id")
                                                                                        + "']]");
                                                                        association = (Element) path
                                                                                .selectSingleNode(next);
                                                                    } catch (JaxenException e) {
                                                                        e.printStackTrace();
                                                                    }

                                                                    if (association != null) {
                                                                        association.detach();
                                                                        //System.out.println("Association removed: " + oclNode.getChildText("name"));

                                                                        //System.out.println("-----------------------------------------------");
                                                                    }
                                                                }

                                                            } else {
                                                                //System.out.println("ERROR: Set has more nodes than expected");
                                                            }
                                                        }

                                                    }

                                                    else if (right.getAttributeValue("data").equals("including")) {
                                                        // the only currently supported structure is: a.b = a.b->including/excluding(c)

                                                        Element nodeToInclude = right.getChild("node");

                                                        //Element evalLeft = evaluateExpressionNode(left, instanceParameters, snapshot, domain, project);
                                                        Element evalLeft = evaluateExpressionNodeInSnapshot(left,
                                                                instanceParameters, snapshot, domain, project);
                                                        Element sameNode = null;
                                                        try {
                                                            XPath path = new JDOMXPath("node[@data='"
                                                                    + nodeToInclude.getAttributeValue("data")
                                                                    + "']");
                                                            sameNode = (Element) path.selectSingleNode(evalLeft);
                                                        } catch (JaxenException e) {
                                                            e.printStackTrace();
                                                        }

                                                        if (sameNode == null) {
                                                            // adds the node
                                                            //                                              find the second object, i. e., the object to which the association points
                                                            Element valueObject = null;
                                                            try {
                                                                XPath path = new JDOMXPath(
                                                                        "elements/objects/object[lower-case(name)='"
                                                                                + nodeToInclude
                                                                                        .getAttributeValue("data")
                                                                                        .toLowerCase()
                                                                                + "']");
                                                                valueObject = (Element) path
                                                                        .selectSingleNode(domain);
                                                            } catch (JaxenException e) {
                                                                e.printStackTrace();
                                                            }

                                                            if (valueObject != null) {

                                                                // create a new object association
                                                                Element commonData = ItSIMPLE.getCommonData();

                                                                Element newObjectAssociation = (Element) commonData
                                                                        .getChild("definedNodes")
                                                                        .getChild("elements").getChild("model")
                                                                        .getChild("objectAssociation").clone();

                                                                newObjectAssociation.getChild("classAssociation")
                                                                        .setText(oclNode.getAttributeValue("id"));

                                                                Element newSourceAssociationEnd = null;
                                                                Element newTargetAssociationEnd = null;
                                                                //(Element)newObjectAssociation.getChild("associationEnds").getChildren("objectAssociationEnd").get(1);
                                                                try {
                                                                    XPath path = new JDOMXPath(
                                                                            "associationEnds/objectAssociationEnd[@id='"
                                                                                    + targetAssociationEnd
                                                                                            .getAttributeValue("id")
                                                                                    + "']");
                                                                    newTargetAssociationEnd = (Element) path
                                                                            .selectSingleNode(newObjectAssociation);
                                                                } catch (JaxenException e) {
                                                                    e.printStackTrace();
                                                                }

                                                                if (newTargetAssociationEnd != null) {

                                                                    String sourceId = (newTargetAssociationEnd
                                                                            .getAttributeValue("id").equals("1"))
                                                                                    ? "2"
                                                                                    : "1";
                                                                    try {
                                                                        XPath path = new JDOMXPath(
                                                                                "associationEnds/objectAssociationEnd[@id='"
                                                                                        + sourceId + "']");
                                                                        newSourceAssociationEnd = (Element) path
                                                                                .selectSingleNode(
                                                                                        newObjectAssociation);
                                                                    } catch (JaxenException e) {
                                                                        e.printStackTrace();
                                                                    }

                                                                    if (newSourceAssociationEnd != null) {

                                                                    }
                                                                }

                                                                // 1st association end
                                                                newSourceAssociationEnd.setAttribute("element",
                                                                        "object");
                                                                newSourceAssociationEnd.setAttribute("element-id",
                                                                        domainObject.getAttributeValue("id"));

                                                                // 2nd association end
                                                                newTargetAssociationEnd.setAttribute("element",
                                                                        "object");
                                                                newTargetAssociationEnd.setAttribute("element-id",
                                                                        valueObject.getAttributeValue("id"));

                                                                newObjectAssociation.setAttribute("id",
                                                                        String.valueOf(XMLUtilities.getId(snapshot
                                                                                .getChild("associations"))));

                                                                //set the highlight color
                                                                newObjectAssociation.getChild("graphics")
                                                                        .getChild("color").setText(changeColor);

                                                                // add it to the snapshot
                                                                next.getChild("associations")
                                                                        .addContent(newObjectAssociation);

                                                                //System.out.println("Object association created: "
                                                                //      + oclNode.getChildText("name")+ " " 
                                                                //      + domainObject.getChildText("name")+ " ---- " + valueObject.getChildText("name"));      
                                                                //System.out.println("-----------------------------------------------");
                                                            }
                                                        }

                                                    }

                                                    else if (right.getAttributeValue("data").equals("excluding")) {
                                                        // the only currently supported structure is: a.b = a.b->including/excluding(c)

                                                        Element nodeToExclude = right.getChild("node");

                                                        //Element evalLeft = evaluateExpressionNode(left, instanceParameters, snapshot, domain, project);
                                                        Element evalLeft = evaluateExpressionNodeInSnapshot(left,
                                                                instanceParameters, snapshot, domain, project);
                                                        Element sameNode = null;
                                                        try {
                                                            XPath path = new JDOMXPath("node[@data='"
                                                                    + nodeToExclude.getAttributeValue("data")
                                                                    + "']");
                                                            sameNode = (Element) path.selectSingleNode(evalLeft);
                                                        } catch (JaxenException e) {
                                                            e.printStackTrace();
                                                        }

                                                        if (sameNode != null) {
                                                            // excludes node
                                                            //nodeToExclude = evalLeft.getChild("node");

                                                            Element valueObject = null;
                                                            try {
                                                                XPath path = new JDOMXPath(
                                                                        "elements/objects/object[lower-case(name)='"
                                                                                + nodeToExclude
                                                                                        .getAttributeValue("data")
                                                                                        .toLowerCase()
                                                                                + "']");
                                                                valueObject = (Element) path
                                                                        .selectSingleNode(domain);
                                                            } catch (JaxenException e) {
                                                                e.printStackTrace();
                                                            }
                                                            if (valueObject != null) {
                                                                //String objectAssociationEndID = (associationEnd.getAttributeValue("id").equals("1")) ?"2" :"1";
                                                                Element association = null;
                                                                try {
                                                                    XPath path = new JDOMXPath(
                                                                            "associations/objectAssociation[classAssociation='"
                                                                                    + oclNode
                                                                                            .getAttributeValue("id")
                                                                                    + "' and associationEnds/objectAssociationEnd[@element-id='"
                                                                                    + valueObject
                                                                                            .getAttributeValue("id")
                                                                                    + "' and @id='"
                                                                                    + targetAssociationEnd
                                                                                            .getAttributeValue("id")
                                                                                    + "']]");
                                                                    association = (Element) path
                                                                            .selectSingleNode(next);
                                                                } catch (JaxenException e) {
                                                                    e.printStackTrace();
                                                                }

                                                                if (association != null) {
                                                                    association.detach();
                                                                    //System.out.println("Association removed: " + oclNode.getChildText("name"));

                                                                    //System.out.println("-----------------------------------------------");
                                                                }
                                                            }
                                                        }
                                                    }

                                                    else {//there is a value
                                                            // look for the value in domain
                                                        Element valueInstanceParameter = null;
                                                        try {
                                                            XPath path = new JDOMXPath("parameter[value='"
                                                                    + right.getAttributeValue("data") + "']");
                                                            valueInstanceParameter = (Element) path
                                                                    .selectSingleNode(instanceParameters);
                                                        } catch (JaxenException e) {
                                                            e.printStackTrace();
                                                        }
                                                        if (valueInstanceParameter != null) {
                                                            Element valueObject = null;
                                                            try {
                                                                XPath path = new JDOMXPath(
                                                                        "elements/objects/object[lower-case(name)='"
                                                                                + valueInstanceParameter
                                                                                        .getChildText("value")
                                                                                        .toLowerCase()
                                                                                + "']");
                                                                valueObject = (Element) path
                                                                        .selectSingleNode(domain);
                                                            } catch (JaxenException e) {
                                                                e.printStackTrace();
                                                            }
                                                            if (valueObject != null) {
                                                                boolean createAssociation;
                                                                if (objectAssociation == null) {
                                                                    createAssociation = true;
                                                                } else {
                                                                    Element firstAssociationEnd = (Element) objectAssociation
                                                                            .getChild("associationEnds")
                                                                            .getChildren("objectAssociationEnd")
                                                                            .get(0);
                                                                    Element secondAssociationEnd = (Element) objectAssociation
                                                                            .getChild("associationEnds")
                                                                            .getChildren("objectAssociationEnd")
                                                                            .get(1);
                                                                    String firstElementID = firstAssociationEnd
                                                                            .getAttributeValue("element-id");
                                                                    String secondElementID = secondAssociationEnd
                                                                            .getAttributeValue("element-id");
                                                                    if (firstElementID.equals(
                                                                            domainObject.getAttributeValue("id"))
                                                                            && secondElementID.equals(valueObject
                                                                                    .getAttributeValue("id"))) {
                                                                        //don't create a new object association   
                                                                        createAssociation = false;
                                                                    } else {
                                                                        // create a new association
                                                                        createAssociation = true;
                                                                    }
                                                                }
                                                                if (createAssociation) {
                                                                    // create a new object association
                                                                    Element commonData = ItSIMPLE.getCommonData();

                                                                    Element newObjectAssociation = (Element) commonData
                                                                            .getChild("definedNodes")
                                                                            .getChild("elements").getChild("model")
                                                                            .getChild("objectAssociation").clone();
                                                                    newObjectAssociation
                                                                            .getChild("classAssociation")
                                                                            .setText(oclNode
                                                                                    .getAttributeValue("id"));
                                                                    Element newSourceAssociationEnd = null;
                                                                    Element newTargetAssociationEnd = null;
                                                                    //(Element)newObjectAssociation.getChild("associationEnds").getChildren("objectAssociationEnd").get(1);
                                                                    try {
                                                                        XPath path = new JDOMXPath(
                                                                                "associationEnds/objectAssociationEnd[@id='"
                                                                                        + targetAssociationEnd
                                                                                                .getAttributeValue(
                                                                                                        "id")
                                                                                        + "']");
                                                                        newTargetAssociationEnd = (Element) path
                                                                                .selectSingleNode(
                                                                                        newObjectAssociation);
                                                                    } catch (JaxenException e) {
                                                                        e.printStackTrace();
                                                                    }

                                                                    if (newTargetAssociationEnd != null) {

                                                                        String sourceId = (newTargetAssociationEnd
                                                                                .getAttributeValue("id")
                                                                                .equals("1")) ? "2" : "1";
                                                                        try {
                                                                            XPath path = new JDOMXPath(
                                                                                    "associationEnds/objectAssociationEnd[@id='"
                                                                                            + sourceId + "']");
                                                                            newSourceAssociationEnd = (Element) path
                                                                                    .selectSingleNode(
                                                                                            newObjectAssociation);
                                                                        } catch (JaxenException e) {
                                                                            e.printStackTrace();
                                                                        }

                                                                        if (newSourceAssociationEnd != null) {
                                                                            //                                                          1st association end
                                                                            newSourceAssociationEnd.setAttribute(
                                                                                    "element", "object");
                                                                            newSourceAssociationEnd.setAttribute(
                                                                                    "element-id",
                                                                                    domainObject.getAttributeValue(
                                                                                            "id"));

                                                                            // 2nd association end
                                                                            newTargetAssociationEnd.setAttribute(
                                                                                    "element", "object");
                                                                            newTargetAssociationEnd.setAttribute(
                                                                                    "element-id",
                                                                                    valueObject.getAttributeValue(
                                                                                            "id"));

                                                                            newObjectAssociation.setAttribute("id",
                                                                                    String.valueOf(XMLUtilities
                                                                                            .getId(next.getChild(
                                                                                                    "associations"))));

                                                                            // set the highlight color
                                                                            newObjectAssociation
                                                                                    .getChild("graphics")
                                                                                    .getChild("color")
                                                                                    .setText(changeColor);

                                                                            next.getChild("associations")
                                                                                    .addContent(
                                                                                            newObjectAssociation);

                                                                            //System.out.println("Object association created: "+ oclNode.getChildText("name")+ " " 
                                                                            //      + domainObject.getChildText("name")+ " ---- " + valueObject.getChildText("name"));

                                                                            if (objectAssociation != null) {
                                                                                // delete the old object association
                                                                                Element associations = objectAssociation
                                                                                        .getParentElement();
                                                                                associations.removeContent(
                                                                                        objectAssociation);

                                                                                //System.out.println("Association removed: " + oclNode.getChildText("name"));

                                                                                //System.out.println("-----------------------------------------------");
                                                                            }
                                                                        }

                                                                    }

                                                                }
                                                            } else {
                                                                //System.out.println("Object \""+ valueInstanceParameter.getChildText("value") +
                                                                //      "\"  not found in domain.");
                                                            }
                                                        } else {
                                                            //System.out.println("Value \""+ right.getAttributeValue("data") +"\" not found in parameters list.");
                                                        }
                                                    }
                                                } else {
                                                    //association
                                                    //TODO associations without rolenames

                                                }
                                            }
                                        } else {
                                            //System.out.println("Attribute or association \"" + attrName + "\" not found in project.");
                                        }
                                    } else {
                                        //System.out.println("Object \"" + domainObject.getAttributeValue("id") + "\" not found in next snapshot.");
                                    }
                                } else {
                                    //System.out.println("Object \"" + instanceParameter.getChildText("value") + "\"  not found in domain.");
                                }
                            } else {
                                //System.out.println("Class \"" + instanceParameter.getChildText("type") + "\" not found in domain.");
                            }
                        } else {
                            //System.out.println("Object \"" + objectNode.getAttributeValue("data") + "\" not found in parameters list.");
                        }

                    } else {
                        // global attributes
                        Element classAttr = null;
                        String attrName;
                        if (left.getAttributeValue("data").indexOf("(") > 0) {
                            // parameterized attribute
                            attrName = left.getAttributeValue("data")
                                    .substring(0, left.getAttributeValue("data").indexOf("(")).toLowerCase();
                        } else {
                            attrName = left.getAttributeValue("data").toLowerCase();
                        }
                        try {
                            XPath path = new JDOMXPath(
                                    "elements/classes/class[stereotype='utility']/attributes/attribute[lower-case(name)='"
                                            + attrName + "']");
                            classAttr = (Element) path.selectSingleNode(project);
                        } catch (JaxenException e) {
                            e.printStackTrace();
                        }
                        if (classAttr != null) {
                            Element utilityClass = classAttr.getParentElement().getParentElement();
                            //                      not parameterized attribute

                            // look for the domain object
                            Element domainObject = null;
                            try {
                                XPath path = new JDOMXPath("elements/objects/object[class='"
                                        + utilityClass.getAttributeValue("id") + "']");
                                domainObject = (Element) path.selectSingleNode(domain);
                            } catch (JaxenException e) {
                                e.printStackTrace();
                            }
                            if (domainObject != null) {
                                // look for the snapshot object
                                Element snapshotObject = null;
                                try {
                                    XPath path = new JDOMXPath(
                                            "objects/object[@id='" + domainObject.getAttributeValue("id") + "']");
                                    snapshotObject = (Element) path.selectSingleNode(next);
                                } catch (JaxenException e) {
                                    e.printStackTrace();
                                }
                                if (snapshotObject != null) {
                                    Element objectAttribute = null;
                                    try {
                                        XPath path = new JDOMXPath(
                                                "attributes/attribute[@id='" + classAttr.getAttributeValue("id")
                                                        + "' and @class='" + classAttr.getParentElement()
                                                                .getParentElement().getAttributeValue("id")
                                                        + "']");
                                        objectAttribute = (Element) path.selectSingleNode(snapshotObject);
                                    } catch (JaxenException e) {
                                        e.printStackTrace();
                                    }
                                    if (objectAttribute != null) {
                                        List<?> attrParameters = classAttr.getChild("parameters")
                                                .getChildren("parameter");
                                        if (attrParameters.size() > 0) {

                                            String leftData = left.getAttributeValue("data");

                                            //parameterized attribute
                                            String attrParams = leftData.substring(leftData.indexOf('(') + 1,
                                                    leftData.lastIndexOf(')'));
                                            String query = "attributes/attribute[@id='"
                                                    + classAttr.getAttributeValue("id")
                                                    + "']/value/parameterizedValue[";
                                            StringTokenizer st = new StringTokenizer(attrParams, ",");
                                            for (Iterator<?> iterator = attrParameters.iterator(); iterator
                                                    .hasNext();) {
                                                Element attrParam = (Element) iterator.next();
                                                String paramValue = "";
                                                if (st.hasMoreTokens()) {
                                                    paramValue = st.nextToken().trim().toLowerCase();
                                                } else {
                                                    //System.out.println("There are fewer parameters than expected at attribute: "+ classAttr.getChildText("name"));
                                                }
                                                query += "lower-case(parameters/parameter[@id='"
                                                        + attrParam.getAttributeValue("id") + "']/value)='"
                                                        + paramValue + "'";

                                                if (iterator.hasNext()) {
                                                    query += " and ";
                                                }
                                            }
                                            query += "]";
                                            if (st.hasMoreTokens()) {
                                                //System.out.println("There are more parameters than expected at attribute: "+ classAttr.getChildText("name"));
                                            }
                                            Element parameterizedValue = null;
                                            try {
                                                XPath path = new JDOMXPath(query);
                                                parameterizedValue = (Element) path
                                                        .selectSingleNode(snapshotObject);
                                            } catch (JaxenException e) {
                                                e.printStackTrace();
                                            }
                                            if (parameterizedValue != null) {
                                                //System.out.println("Before: "+ domainObject.getChildText("name")+ " - "+ classAttr.getChildText("name"));
                                                //XMLUtilities.printXML(parameterizedValue);

                                                //refresh the value in the snapshot                              
                                                parameterizedValue.getChild("value")
                                                        .setText(right.getAttributeValue("data"));

                                                //set the highlight color
                                                parameterizedValue.getChild("graphics").getChild("color")
                                                        .setText(changeColor);

                                                //System.out.println("After:");
                                                //XMLUtilities.printXML(parameterizedValue);
                                                //System.out.println("-----------------------------------------------");
                                            } else {
                                                //System.out.println("Parameterized value \""+ left.getAttributeValue("data")
                                                //      +"\" not found in snapshot object.");
                                            }

                                        } else {
                                            // not parameterized value
                                            //                                 check whether the value is to be changed                                    
                                            if (!right.getAttributeValue("data").toLowerCase()
                                                    .equals(objectAttribute.getChildText("value").toLowerCase())) {
                                                //System.out.println("Before: "+ domainObject.getChildText("name")+ " - "+ classAttr.getChildText("name"));
                                                //XMLUtilities.printXML(objectAttribute);
                                                // do the change
                                                objectAttribute.getChild("value")
                                                        .setText(right.getAttributeValue("data"));

                                                // set the highlight color
                                                //set the highlight color
                                                objectAttribute.getChild("graphics").getChild("color")
                                                        .setText(changeColor);

                                                //System.out.println("After:");
                                                //XMLUtilities.printXML(objectAttribute);   
                                                //System.out.println("-----------------------------------------------");
                                            }
                                        }
                                    } else {
                                        //System.out.println("Attribute \"" + classAttr.getChildText("name") + "\" not found in snapshot object.");
                                    }
                                } else {
                                    //System.out.println("Object with utility stereotype not found in snapshot.");
                                }
                            } else {
                                //System.out.println("Object with utility stereotype not found in domain.");
                            }
                        } else {
                            //System.out.println("Global attribute \""+ left.getAttributeValue("data") +"\" not found.");
                        }
                    }
                }
            }
        } else {
            //System.out.println("Operator \""+ action +"\" not found.");
        }

        return next;
    }

    /**
     * This method evaluate a expression node in a given snaphot considering
     * a list of action's parameters.
     * This method is depricated; use evaluateExpressionNodeInSnapshot instead.
     * @param node
     * @param instanceParameters
     * @param snapshot
     * @param domain
     * @param project
     * @return
     */
    @Deprecated
    private static Element evaluateExpressionNode(Element node, Element instanceParameters, Element snapshot,
            Element domain, Element project) {
        Element evaluatedNode = null;
        String nodeData = node.getAttributeValue("data");
        if (nodeData.equals(".")) {
            Element objectNode = (Element) node.getChildren().get(0);
            Element attrOrAssocNode = (Element) node.getChildren().get(1);
            String data = attrOrAssocNode.getAttributeValue("data");

            String attrOrAssocName;
            if (data.indexOf("(") > 0) {
                // parameterized attribute (take off parenthesis)
                attrOrAssocName = data.substring(0, data.indexOf('(')).toLowerCase();

                // replace parameter values
                String attrName = data.substring(0, data.indexOf('('));
                String attrParameters = data.substring(data.indexOf('(') + 1, data.lastIndexOf(')'));
                String attrValues = "(";
                StringTokenizer st = new StringTokenizer(attrParameters, ",");
                while (st.hasMoreTokens()) {
                    String parameter = st.nextToken().trim().toLowerCase();
                    Element instanceParameter = null;
                    try {
                        XPath path = new JDOMXPath("parameter[lower-case(name)='" + parameter + "']");
                        instanceParameter = (Element) path.selectSingleNode(instanceParameters);
                    } catch (JaxenException e) {
                        e.printStackTrace();
                    }
                    if (instanceParameter != null) {
                        attrValues += instanceParameter.getChildText("value");

                        if (st.hasMoreTokens()) {
                            attrValues += ",";
                        }
                    } else {
                        //System.out.println("Parameter \""+ parameter +"\" not found in parameters list.");
                        //TODO: Check if it is a literal
                        Element literal = null;
                        try {
                            XPath path = new JDOMXPath(
                                    "project/elements/classes/enumeration/literals/literal[lower-case(name)='"
                                            + parameter + "']");
                            literal = (Element) path.selectSingleNode(domain.getDocument());
                        } catch (JaxenException e) {
                            e.printStackTrace();
                        }
                        if (literal != null) {
                            attrValues += parameter;
                        } else {
                            attrValues += "#error";
                        }

                        //attrValues += "#error";
                    }
                }
                attrValues += ")";

                String newAttrData = attrName + attrValues;
                attrOrAssocNode.setAttribute("data", newAttrData);
                attrOrAssocNode.setAttribute("instance", "t");

                // update data
                data = newAttrData;
            } else {
                attrOrAssocName = data.toLowerCase();
            }

            //         look for the instance parameter
            Element instanceParameter = null;
            try {
                XPath path = new JDOMXPath("parameter[lower-case(value)='"
                        + objectNode.getAttributeValue("data").toLowerCase() + "']");
                instanceParameter = (Element) path.selectSingleNode(instanceParameters);
            } catch (JaxenException e) {
                e.printStackTrace();
            }

            if (instanceParameter != null) {
                //             look for the object class
                Element objectClass = null;
                try {
                    XPath path = new JDOMXPath(
                            "elements/classes/class[@id='" + instanceParameter.getChildText("type") + "']");
                    objectClass = (Element) path.selectSingleNode(project);
                } catch (JaxenException e) {
                    e.printStackTrace();
                }
                if (objectClass != null) {
                    //               look for the object in the snapshot domain               
                    Element domainObject = null;
                    try {
                        XPath path = new JDOMXPath("elements/objects/object[lower-case(name)='"
                                + instanceParameter.getChildText("value").toLowerCase() + "']");
                        domainObject = (Element) path.selectSingleNode(domain);
                    } catch (JaxenException e) {
                        e.printStackTrace();
                    }
                    if (domainObject != null) {
                        //                   look for the object in the snapshot
                        Element snapshotObject = null;
                        try {
                            XPath path = new JDOMXPath(
                                    "objects/object[@id='" + domainObject.getAttributeValue("id") + "']");
                            snapshotObject = (Element) path.selectSingleNode(snapshot);
                        } catch (JaxenException e) {
                            e.printStackTrace();
                        }
                        if (snapshotObject != null) {
                            // check whether the second node is an attribute or an association
                            Element attrOrAssocModelNode = null;
                            try {
                                XPath path = new JDOMXPath(
                                        "elements/classes/class/attributes/attribute[lower-case(name)='"
                                                + attrOrAssocName + "'] | elements/classAssociations/"
                                                + "classAssociation[associationEnds/associationEnd/rolename[lower-case(value)='"
                                                + attrOrAssocName + "'] or lower-case(name)='" + attrOrAssocName
                                                + "']");
                                attrOrAssocModelNode = (Element) path.selectSingleNode(project);
                            } catch (JaxenException e) {
                                e.printStackTrace();
                            }

                            if (attrOrAssocModelNode != null) {

                                // attribute
                                if (attrOrAssocModelNode.getName().equals("attribute")) {
                                    // look for the attribute in the object class 
                                    Element classAttr = null;

                                    try {
                                        XPath path = new JDOMXPath(
                                                "elements/classes/class/attributes/attribute[lower-case(name)='"
                                                        + attrOrAssocName + "']");
                                        classAttr = (Element) path.selectSingleNode(project);
                                    } catch (JaxenException e) {
                                        e.printStackTrace();
                                    }
                                    if (classAttr != null) {
                                        List<?> attrParameters = classAttr.getChild("parameters").getChildren();
                                        if (attrParameters.size() > 0) {
                                            // parameterized attribute                           
                                            String attrParams = data.toLowerCase().substring(data.indexOf('(') + 1,
                                                    data.lastIndexOf(')'));
                                            String query = "attributes/attribute[@id='"
                                                    + classAttr.getAttributeValue("id")
                                                    + "']/value/parameterizedValue[";
                                            StringTokenizer st = new StringTokenizer(attrParams, ",");
                                            for (Iterator<?> iter = attrParameters.iterator(); iter.hasNext();) {
                                                Element attrParam = (Element) iter.next();
                                                String value = "";
                                                if (st.hasMoreTokens()) {
                                                    value = st.nextToken().trim().toLowerCase();
                                                } else {
                                                    //System.out.println("There are less parameters than expected at attribute: "+ classAttr.getChildText("name"));
                                                }
                                                query += "parameters/parameter[@id='"
                                                        + attrParam.getAttributeValue("id")
                                                        + "' and lower-case(value)='" + value + "']";

                                                if (iter.hasNext()) {
                                                    query += " and ";
                                                }
                                            }
                                            query += "]";

                                            if (st.hasMoreTokens()) {
                                                //System.out.println("There are more parameters than expected at attribute: "+ classAttr.getChildText("name"));
                                            }
                                            Element parameterizedValue = null;
                                            try {
                                                XPath path = new JDOMXPath(query);
                                                parameterizedValue = (Element) path
                                                        .selectSingleNode(snapshotObject);
                                            } catch (JaxenException e) {
                                                e.printStackTrace();
                                            }
                                            if (parameterizedValue != null) {
                                                //returns the value given in the snapshot                              
                                                evaluatedNode = (Element) node.clone();
                                                evaluatedNode.removeContent();
                                                evaluatedNode.setAttribute("type", "opd");
                                                evaluatedNode.setAttribute("data",
                                                        parameterizedValue.getChildText("value"));
                                                evaluatedNode.setAttribute("instance", "t");
                                            } else {
                                                //System.out.println("Parameterized value "+ attrOrAssocName +" not found in snapshot object.");
                                            }
                                        } else {
                                            // not parameterized attribute
                                            Element objectAttribute = null;
                                            try {
                                                XPath path = new JDOMXPath(
                                                        "attributes/attribute[@id='"
                                                                + classAttr.getAttributeValue("id")
                                                                + "' and @class='" + classAttr.getParentElement()
                                                                        .getParentElement().getAttributeValue("id")
                                                                + "']");
                                                objectAttribute = (Element) path.selectSingleNode(snapshotObject);
                                            } catch (JaxenException e) {
                                                e.printStackTrace();
                                            }
                                            if (objectAttribute != null) {
                                                // returns the value given in the snapshot                              
                                                evaluatedNode = (Element) node.clone();
                                                evaluatedNode.removeContent();
                                                evaluatedNode.setAttribute("type", "opd");
                                                evaluatedNode.setAttribute("data",
                                                        objectAttribute.getChildText("value"));
                                                evaluatedNode.setAttribute("instance", "t");
                                            } else {
                                                //System.out.println("Object attribute \"" + classAttr.getChildText("name") + "\" not found in snapshot.");
                                            }
                                        }
                                    } else {
                                        //System.out.println("Attribute \"" + attrOrAssocNode.getAttributeValue("data") + "\" not found in project.");
                                    }
                                } else {
                                    // association
                                    //get the second object association end has the rolename or the navigation false
                                    Element secondObjectAssociationEnd = null;
                                    // try with rolename
                                    try {
                                        XPath path = new JDOMXPath(
                                                "associationEnds/associationEnd[lower-case(rolename/value)='"
                                                        + attrOrAssocName.toLowerCase() + "']");
                                        secondObjectAssociationEnd = (Element) path
                                                .selectSingleNode(attrOrAssocModelNode);
                                    } catch (JaxenException e) {
                                        e.printStackTrace();
                                    }
                                    if (secondObjectAssociationEnd == null) {
                                        // if it's null, there is no rolename, so check navigation
                                        try {
                                            XPath path = new JDOMXPath(
                                                    "associationEnds/associationEnd[@navigation='true']");
                                            secondObjectAssociationEnd = (Element) path
                                                    .selectSingleNode(attrOrAssocModelNode);
                                        } catch (JaxenException e) {
                                            e.printStackTrace();
                                        }
                                    }

                                    //TODO case with both association ends navigation true or false is not currently dealed

                                    // get the first object of the association
                                    Element firstObject = null;
                                    try {
                                        XPath path = new JDOMXPath("elements/objects/object[lower-case(name)='"
                                                + objectNode.getAttributeValue("data").toLowerCase() + "']");
                                        firstObject = (Element) path.selectSingleNode(domain);
                                    } catch (JaxenException e) {
                                        e.printStackTrace();
                                    }

                                    if (secondObjectAssociationEnd != null && firstObject != null) {
                                        // get the class association
                                        Element classAssociation = secondObjectAssociationEnd.getParentElement()
                                                .getParentElement();

                                        //get the first object association end id
                                        String secondObjectAssociationEndId = secondObjectAssociationEnd
                                                .getAttributeValue("id");
                                        String firstObjectAssociationEndId = (secondObjectAssociationEndId
                                                .equals("1")) ? "2" : "1";

                                        // get all object associations with that name and with the same first object
                                        List<?> objectAssociations = null;
                                        try {
                                            XPath path = new JDOMXPath(
                                                    "associations/objectAssociation[classAssociation='"
                                                            + classAssociation.getAttributeValue("id") + "' and "
                                                            + "associationEnds/objectAssociationEnd[@element='object' and "
                                                            + "@element-id='" + firstObject.getAttributeValue("id")
                                                            + "' and " + "@id='" + firstObjectAssociationEndId
                                                            + "']]");
                                            objectAssociations = path.selectNodes(snapshot);
                                        } catch (JaxenException e) {
                                            e.printStackTrace();
                                        }

                                        // create the set node to receive the objects
                                        evaluatedNode = new Element("node");
                                        evaluatedNode.setAttribute("type", "opd");
                                        evaluatedNode.setAttribute("data", "set");
                                        evaluatedNode.setAttribute("instance", "t");

                                        for (Iterator<?> iter = objectAssociations.iterator(); iter.hasNext();) {
                                            Element objectAssociation = (Element) iter.next();

                                            // for each object association, get the second object
                                            Element currentSecondObjectAssociationEnd = null;
                                            try {
                                                XPath path = new JDOMXPath(
                                                        "associationEnds/objectAssociationEnd[@id='"
                                                                + secondObjectAssociationEndId + "']");
                                                currentSecondObjectAssociationEnd = (Element) path
                                                        .selectSingleNode(objectAssociation);
                                            } catch (JaxenException e) {
                                                e.printStackTrace();
                                            }

                                            if (currentSecondObjectAssociationEnd != null) {
                                                // get the object corresponding to this association end
                                                Element currentSecondObject = null;
                                                try {
                                                    XPath path = new JDOMXPath(
                                                            "elements/objects/object[@id='"
                                                                    + currentSecondObjectAssociationEnd
                                                                            .getAttributeValue("element-id")
                                                                    + "']");
                                                    currentSecondObject = (Element) path.selectSingleNode(domain);
                                                } catch (JaxenException e) {
                                                    e.printStackTrace();
                                                }

                                                if (currentSecondObject != null) {
                                                    // add a node to the set
                                                    Element newNode = new Element("node");
                                                    newNode.setAttribute("type", "opd");
                                                    newNode.setAttribute("data",
                                                            currentSecondObject.getChildText("name").toUpperCase());
                                                    newNode.setAttribute("instance", "t");

                                                    evaluatedNode.addContent(newNode);
                                                }
                                            }
                                        }
                                    }
                                }
                            }

                        } else {
                            //System.out.println("Object \"" + domainObject.getAttributeValue("id") + "\" not found in  snapshot.");
                        }
                    } else {
                        //System.out.println("Object \"" + instanceParameter.getChildText("value") + "\"  not found in domain.");
                    }
                } else {
                    //System.out.println("Class \"" + instanceParameter.getChildText("type") + "\" not found in domain.");
                }
            } else {
                //System.out.println("Object \"" + objectNode.getAttributeValue("data") + "\" not found in parameters list.");
            }

        } else if (nodeData.equals("->")) {// including, excluding
            Element left = (Element) node.getChildren().get(0);
            Element right = (Element) node.getChildren().get(1);
            String rightData = right.getAttributeValue("data");
            //Element set = evaluateExpressionNode(left, instanceParameters, snapshot, domain, project);
            Element set = evaluateExpressionNodeInSnapshot(left, instanceParameters, snapshot, domain, project);

            // with including or excluding, it will return the result of the set
            // after the inclusion or exclusion
            if (rightData.equals("including") || rightData.equals("excluding")) {
                //Element param = evaluateExpressionNode(right.getChild("node"), instanceParameters, snapshot, domain, project);
                Element param = evaluateExpressionNodeInSnapshot(right.getChild("node"), instanceParameters,
                        snapshot, domain, project);
                if (rightData.equals("including")) {
                    // add the node to the set
                    set.addContent(param);
                } else {// excluding
                        // look for the node in the set
                    Element nodeToBeDeleted = null;
                    try {
                        XPath path = new JDOMXPath(
                                "node[lower-case(@data)='" + param.getAttributeValue("data").toLowerCase() + "']");
                        nodeToBeDeleted = (Element) path.selectSingleNode(set);
                    } catch (JaxenException e) {
                        e.printStackTrace();
                    }
                    if (nodeToBeDeleted != null) {
                        // exclude the node from set
                        nodeToBeDeleted.detach();
                    } else {
                        //System.out.println("Object to be excluded \""+ param.getAttributeValue("data") 
                        //      +"\" not found.");
                    }
                }
                evaluatedNode = set;
            }
        }

        else if (nodeData.equals("+") || nodeData.equals("-") || nodeData.equals("*") || nodeData.equals("/")) {
            Element left = (Element) node.getChildren().get(0);
            Element right = (Element) node.getChildren().get(1);

            //XMLUtilities.printXML(left);
            //XMLUtilities.printXML(right);

            //Element evalLeft = evaluateExpressionNode(left, instanceParameters, snapshot, domain, project);
            Element evalLeft = evaluateExpressionNodeInSnapshot(left, instanceParameters, snapshot, domain,
                    project);
            //Element evalRight = evaluateExpressionNode(right, instanceParameters, snapshot, domain, project);
            Element evalRight = evaluateExpressionNodeInSnapshot(right, instanceParameters, snapshot, domain,
                    project);

            //XMLUtilities.printXML(evalLeft);
            //XMLUtilities.printXML(evalRight);

            evaluatedNode = (Element) node.clone();
            evaluatedNode.removeContent();
            evaluatedNode.setAttribute("type", "opd");
            evaluatedNode.setAttribute("instance", "t");

            switch (node.getAttributeValue("data").charAt(0)) {
            case '+': {
                double result = Double.parseDouble(evalLeft.getAttributeValue("data"))
                        + Double.parseDouble(evalRight.getAttributeValue("data"));

                evaluatedNode.setAttribute("data", String.valueOf(result));
            }
                break;
            case '-': {
                double result = Double.parseDouble(evalLeft.getAttributeValue("data"))
                        - Double.parseDouble(evalRight.getAttributeValue("data"));

                evaluatedNode.setAttribute("data", String.valueOf(result));
            }
                break;
            case '*': {
                double result = Double.parseDouble(evalLeft.getAttributeValue("data"))
                        * Double.parseDouble(evalRight.getAttributeValue("data"));

                evaluatedNode.setAttribute("data", String.valueOf(result));
            }
                break;
            case '/': {
                double result = Double.parseDouble(evalLeft.getAttributeValue("data"))
                        / Double.parseDouble(evalRight.getAttributeValue("data"));

                evaluatedNode.setAttribute("data", String.valueOf(result));
            }
                break;
            }
        } else if (node.getAttributeValue("type").equals("opd")) {
            // check whether the attribute is global (stereotype 'utility')
            String attrData = node.getAttributeValue("data");
            String attrNodeName;
            if (attrData.indexOf("(") > 0) {
                // parameterized attribute
                attrNodeName = attrData.substring(0, attrData.indexOf("(")).toLowerCase();
            } else {
                attrNodeName = attrData.toLowerCase();
            }
            Element classAttr = null;
            try {
                XPath path = new JDOMXPath(
                        "elements/classes/class[stereotype='utility']/attributes/attribute[lower-case(name)='"
                                + attrNodeName + "']");
                classAttr = (Element) path.selectSingleNode(project);
            } catch (JaxenException e) {
                e.printStackTrace();
            }
            if (classAttr != null) {
                Element utilityClass = classAttr.getParentElement().getParentElement();

                //             look for the domain object
                Element domainObject = null;
                try {
                    XPath path = new JDOMXPath(
                            "elements/objects/object[class='" + utilityClass.getAttributeValue("id") + "']");
                    domainObject = (Element) path.selectSingleNode(domain);
                } catch (JaxenException e) {
                    e.printStackTrace();
                }
                if (domainObject != null) {
                    // look for the snapshot object
                    Element snapshotObject = null;
                    try {
                        XPath path = new JDOMXPath(
                                "objects/object[@id='" + domainObject.getAttributeValue("id") + "']");
                        snapshotObject = (Element) path.selectSingleNode(snapshot);
                    } catch (JaxenException e) {
                        e.printStackTrace();
                    }
                    if (snapshotObject != null) {
                        Element objectAttribute = null;
                        try {
                            XPath path = new JDOMXPath(
                                    "attributes/attribute[@id='"
                                            + classAttr.getAttributeValue("id") + "' and @class='" + classAttr
                                                    .getParentElement().getParentElement().getAttributeValue("id")
                                            + "']");
                            objectAttribute = (Element) path.selectSingleNode(snapshotObject);
                        } catch (JaxenException e) {
                            e.printStackTrace();
                        }
                        if (objectAttribute != null) {
                            List<?> attrParameters = classAttr.getChild("parameters").getChildren();
                            if (attrParameters.size() > 0) {
                                // parameterized attribute                           
                                String attrParams = attrData.substring(attrData.indexOf('(') + 1,
                                        attrData.lastIndexOf(')'));
                                String query = "attributes/attribute[@id='"
                                        + objectAttribute.getAttributeValue("id") + "']/value/parameterizedValue[";
                                StringTokenizer st = new StringTokenizer(attrParams, ",");
                                for (Iterator<?> iter = attrParameters.iterator(); iter.hasNext();) {
                                    Element attrParam = (Element) iter.next();
                                    String attrParamName = "";
                                    if (st.hasMoreTokens()) {
                                        attrParamName = st.nextToken().trim().toLowerCase();
                                    } else {
                                        //System.out.println("There are less parameters than expected at attribute: "+ classAttr.getChildText("name"));
                                    }

                                    // look for the attribute parameter value in instance parameters
                                    Element instanceParameter = null;
                                    try {
                                        XPath path = new JDOMXPath("parameter[lower-case(name)='"
                                                + attrParamName.toLowerCase() + "']");
                                        instanceParameter = (Element) path.selectSingleNode(instanceParameters);
                                    } catch (JaxenException e) {
                                        e.printStackTrace();
                                    }

                                    if (instanceParameter != null) {

                                        query += "lower-case(parameters/parameter[@id='"
                                                + attrParam.getAttributeValue("id") + "']/value)='"
                                                + instanceParameter.getChildText("value").toLowerCase() + "'";

                                        if (iter.hasNext()) {
                                            query += " and ";
                                        }
                                    } else {
                                        //System.out.println("Error evaluating parameterized value: " +
                                        //      "instance parameter \""+ attrParamName +"\" not found.");
                                    }

                                }
                                query += "]";
                                //System.out.println(query);
                                if (st.hasMoreTokens()) {
                                    //System.out.println("There are more parameters than expected at attribute: "+ classAttr.getChildText("name"));
                                }
                                Element parameterizedValue = null;
                                try {
                                    XPath path = new JDOMXPath(query);
                                    parameterizedValue = (Element) path.selectSingleNode(snapshotObject);
                                } catch (JaxenException e) {
                                    e.printStackTrace();
                                }
                                if (parameterizedValue != null) {
                                    //returns the value given in the snapshot                              
                                    evaluatedNode = (Element) node.clone();
                                    evaluatedNode.removeContent();
                                    evaluatedNode.setAttribute("type", "opd");
                                    evaluatedNode.setAttribute("data", parameterizedValue.getChildText("value"));
                                    evaluatedNode.setAttribute("instance", "t");
                                } else {
                                    //System.out.println("Parameterized value "+ attrData +"not found in snapshot object.");
                                }
                            } else {
                                evaluatedNode = (Element) node.clone();
                                evaluatedNode.removeContent();
                                evaluatedNode.setAttribute("type", "opd");
                                evaluatedNode.setAttribute("data", objectAttribute.getChildText("value"));
                                evaluatedNode.setAttribute("instance", "t");
                            }
                        } else {
                            //System.out.println("Attribute \"" + classAttr.getChildText("name") + "\" not found in snapshot object.");
                        }
                    } else {
                        //System.out.println("Object with utility stereotype not found in snapshot.");
                    }
                } else {
                    //System.out.println("Object with utility stereotype not found in domain.");
                }
            } else {
                // returns the node itself
                evaluatedNode = (Element) node.clone();
            }
        }
        return evaluatedNode;

    }

    /**
     * This method evaluate a expression node in a given snapshot based considering
     * a list of action's parameters (if such list exists). If the list do not exist
     * it will look for key elements in the domain.
     * @param node
     * @param instanceParameters
     * @param snapshot
     * @param domain
     * @param project
     * @return
     */
    private static Element evaluateExpressionNodeInSnapshot(Element node, Element instanceParameters,
            Element snapshot, Element domain, Element project) {
        Element evaluatedNode = null;
        String nodeData = node.getAttributeValue("data");
        if (nodeData.equals(".")) {
            Element objectNode = (Element) node.getChildren().get(0);
            Element attrOrAssocNode = (Element) node.getChildren().get(1);
            String data = attrOrAssocNode.getAttributeValue("data");

            String attrOrAssocName;
            if (data.indexOf("(") > 0) {
                // parameterized attribute (take off parenthesis)
                attrOrAssocName = data.substring(0, data.indexOf('(')).toLowerCase();

                // replace parameter values
                String attrName = data.substring(0, data.indexOf('('));
                String attrParameters = data.substring(data.indexOf('(') + 1, data.lastIndexOf(')'));
                String attrValues = "(";
                StringTokenizer st = new StringTokenizer(attrParameters, ",");
                while (st.hasMoreTokens()) {
                    boolean foundIt = false;
                    String parameter = st.nextToken().trim().toLowerCase();
                    Element instanceParameter = null;

                    //1. try to find if in the parameters
                    try {
                        XPath path = new JDOMXPath("parameter[lower-case(name)='" + parameter + "']");
                        instanceParameter = (Element) path.selectSingleNode(instanceParameters);
                    } catch (JaxenException e) {
                        e.printStackTrace();
                    }
                    if (instanceParameter != null) {
                        attrValues += instanceParameter.getChildText("value");
                        foundIt = true;

                        if (st.hasMoreTokens()) {
                            attrValues += ",";
                        }
                    }
                    //2.try to see if it is an enumeration
                    if (!foundIt) {
                        //System.out.println("Parameter \""+ parameter +"\" not found in parameters list.");
                        //TODO: Check if it is a literal
                        Element literal = null;
                        try {
                            XPath path = new JDOMXPath(
                                    "project/elements/classes/enumeration/literals/literal[lower-case(name)='"
                                            + parameter + "']");
                            literal = (Element) path.selectSingleNode(domain.getDocument());
                        } catch (JaxenException e) {
                            e.printStackTrace();
                        }
                        if (literal != null) {
                            attrValues += parameter;
                            foundIt = true;
                        }
                    }
                    //3.try to see if it is an object from the domain
                    if (!foundIt) {
                        //System.out.println("Parameter \""+ parameter +"\" not found in parameters list.");
                        //TODO: Check if it is a literal
                        Element object = null;
                        try {
                            XPath path = new JDOMXPath(
                                    "elements/objects/object[lower-case(name)='" + parameter + "']");
                            object = (Element) path.selectSingleNode(domain);
                        } catch (JaxenException e) {
                            e.printStackTrace();
                        }
                        if (object != null) {
                            attrValues += parameter;
                            foundIt = true;
                        }
                    }

                    //If it was not found at all sen error
                    if (!foundIt) {
                        attrValues += "#error";
                    }

                }
                attrValues += ")";

                String newAttrData = attrName + attrValues;
                attrOrAssocNode.setAttribute("data", newAttrData);
                attrOrAssocNode.setAttribute("instance", "t");

                // update data
                data = newAttrData;
            } else {
                attrOrAssocName = data.toLowerCase();
            }

            boolean foundObjectNode = false;
            Element domainObject = null;
            Element objectClass = null;

            //1. check if it is a instance parameter
            Element instanceParameter = null;
            try {
                XPath path = new JDOMXPath("parameter[lower-case(value)='"
                        + objectNode.getAttributeValue("data").toLowerCase() + "']");
                instanceParameter = (Element) path.selectSingleNode(instanceParameters);
            } catch (JaxenException e) {
                e.printStackTrace();
            }
            if (instanceParameter != null) {
                //look for the object class
                try {
                    XPath path = new JDOMXPath(
                            "elements/classes/class[@id='" + instanceParameter.getChildText("type") + "']");
                    objectClass = (Element) path.selectSingleNode(project);
                } catch (JaxenException e) {
                    e.printStackTrace();
                }
                if (objectClass != null) {
                    //look for the object in the snapshot domain
                    try {
                        XPath path = new JDOMXPath("elements/objects/object[lower-case(name)='"
                                + instanceParameter.getChildText("value").toLowerCase() + "']");
                        domainObject = (Element) path.selectSingleNode(domain);
                    } catch (JaxenException e) {
                        e.printStackTrace();
                    }
                    if (domainObject != null) {
                        foundObjectNode = true;
                    }
                }
            }

            //2. check if it is an object from the domain
            if (!foundObjectNode) {
                try {
                    XPath path = new JDOMXPath("elements/objects/object[lower-case(name)='"
                            + objectNode.getAttributeValue("data").toLowerCase() + "']");
                    domainObject = (Element) path.selectSingleNode(domain);
                } catch (JaxenException e) {
                    e.printStackTrace();
                }
                if (domainObject != null) {
                    //look for the object class
                    try {
                        XPath path = new JDOMXPath(
                                "elements/classes/class[@id='" + domainObject.getChildText("class") + "']");
                        objectClass = (Element) path.selectSingleNode(project);
                    } catch (JaxenException e) {
                        e.printStackTrace();
                    }
                    if (objectClass != null) {
                        foundObjectNode = true;
                    }
                }
            }

            //If it was not found at all sen error
            if (!foundObjectNode) {
                System.out.println("object \"" + objectNode.getAttributeValue("data") + "\" not found in domain.");

            }

            //if we found the object
            if (foundObjectNode) {
                //look for the object in the snapshot
                Element snapshotObject = null;
                try {
                    XPath path = new JDOMXPath(
                            "objects/object[@id='" + domainObject.getAttributeValue("id") + "']");
                    snapshotObject = (Element) path.selectSingleNode(snapshot);
                } catch (JaxenException e) {
                    e.printStackTrace();
                }
                if (snapshotObject != null) {
                    // check whether the second node is an attribute or an association
                    Element attrOrAssocModelNode = null;
                    try {
                        XPath path = new JDOMXPath("elements/classes/class/attributes/attribute[lower-case(name)='"
                                + attrOrAssocName + "'] | elements/classAssociations/"
                                + "classAssociation[associationEnds/associationEnd/rolename[lower-case(value)='"
                                + attrOrAssocName + "'] or lower-case(name)='" + attrOrAssocName + "']");
                        attrOrAssocModelNode = (Element) path.selectSingleNode(project);
                    } catch (JaxenException e) {
                        e.printStackTrace();
                    }

                    if (attrOrAssocModelNode != null) {

                        // attribute
                        if (attrOrAssocModelNode.getName().equals("attribute")) {
                            // look for the attribute in the object class
                            Element classAttr = null;

                            try {
                                XPath path = new JDOMXPath(
                                        "elements/classes/class/attributes/attribute[lower-case(name)='"
                                                + attrOrAssocName + "']");
                                classAttr = (Element) path.selectSingleNode(project);
                            } catch (JaxenException e) {
                                e.printStackTrace();
                            }
                            if (classAttr != null) {
                                List<?> attrParameters = classAttr.getChild("parameters").getChildren();
                                if (attrParameters.size() > 0) {
                                    // parameterized attribute
                                    String attrParams = data.toLowerCase().substring(data.indexOf('(') + 1,
                                            data.lastIndexOf(')'));
                                    String query = "attributes/attribute[@id='" + classAttr.getAttributeValue("id")
                                            + "']/value/parameterizedValue[";
                                    StringTokenizer st = new StringTokenizer(attrParams, ",");
                                    for (Iterator<?> iter = attrParameters.iterator(); iter.hasNext();) {
                                        Element attrParam = (Element) iter.next();
                                        String value = "";
                                        if (st.hasMoreTokens()) {
                                            value = st.nextToken().trim().toLowerCase();
                                        } else {
                                            //System.out.println("There are less parameters than expected at attribute: "+ classAttr.getChildText("name"));
                                        }
                                        query += "parameters/parameter[@id='" + attrParam.getAttributeValue("id")
                                                + "' and lower-case(value)='" + value + "']";

                                        if (iter.hasNext()) {
                                            query += " and ";
                                        }
                                    }
                                    query += "]";

                                    if (st.hasMoreTokens()) {
                                        //System.out.println("There are more parameters than expected at attribute: "+ classAttr.getChildText("name"));
                                    }
                                    Element parameterizedValue = null;
                                    try {
                                        XPath path = new JDOMXPath(query);
                                        parameterizedValue = (Element) path.selectSingleNode(snapshotObject);
                                    } catch (JaxenException e) {
                                        e.printStackTrace();
                                    }
                                    if (parameterizedValue != null) {
                                        //returns the value given in the snapshot
                                        evaluatedNode = (Element) node.clone();
                                        evaluatedNode.removeContent();
                                        evaluatedNode.setAttribute("type", "opd");
                                        evaluatedNode.setAttribute("data",
                                                parameterizedValue.getChildText("value"));
                                        evaluatedNode.setAttribute("instance", "t");
                                    } else {
                                        //System.out.println("Parameterized value "+ attrOrAssocName +" not found in snapshot object.");
                                    }
                                } else {
                                    // not parameterized attribute
                                    Element objectAttribute = null;
                                    try {
                                        XPath path = new JDOMXPath(
                                                "attributes/attribute[@id='" + classAttr.getAttributeValue("id")
                                                        + "' and @class='" + classAttr.getParentElement()
                                                                .getParentElement().getAttributeValue("id")
                                                        + "']");
                                        objectAttribute = (Element) path.selectSingleNode(snapshotObject);
                                    } catch (JaxenException e) {
                                        e.printStackTrace();
                                    }
                                    if (objectAttribute != null) {
                                        // returns the value given in the snapshot
                                        evaluatedNode = (Element) node.clone();
                                        evaluatedNode.removeContent();
                                        evaluatedNode.setAttribute("type", "opd");
                                        evaluatedNode.setAttribute("data", objectAttribute.getChildText("value"));
                                        evaluatedNode.setAttribute("instance", "t");
                                    } else {
                                        //System.out.println("Object attribute \"" + classAttr.getChildText("name") + "\" not found in snapshot.");
                                    }
                                }
                            } else {
                                //System.out.println("Attribute \"" + attrOrAssocNode.getAttributeValue("data") + "\" not found in project.");
                            }
                        } else {
                            // association
                            //get the second object association end has the rolename or the navigation false
                            Element secondObjectAssociationEnd = null;
                            // try with rolename
                            try {
                                XPath path = new JDOMXPath(
                                        "associationEnds/associationEnd[lower-case(rolename/value)='"
                                                + attrOrAssocName.toLowerCase() + "']");
                                secondObjectAssociationEnd = (Element) path.selectSingleNode(attrOrAssocModelNode);
                            } catch (JaxenException e) {
                                e.printStackTrace();
                            }
                            if (secondObjectAssociationEnd == null) {
                                // if it's null, there is no rolename, so check navigation
                                try {
                                    XPath path = new JDOMXPath(
                                            "associationEnds/associationEnd[@navigation='true']");
                                    secondObjectAssociationEnd = (Element) path
                                            .selectSingleNode(attrOrAssocModelNode);
                                } catch (JaxenException e) {
                                    e.printStackTrace();
                                }
                            }

                            //TODO case with both association ends navigation true or false is not currently dealed

                            // get the first object of the association
                            Element firstObject = null;
                            try {
                                XPath path = new JDOMXPath("elements/objects/object[lower-case(name)='"
                                        + objectNode.getAttributeValue("data").toLowerCase() + "']");
                                firstObject = (Element) path.selectSingleNode(domain);
                            } catch (JaxenException e) {
                                e.printStackTrace();
                            }

                            if (secondObjectAssociationEnd != null && firstObject != null) {
                                // get the class association
                                Element classAssociation = secondObjectAssociationEnd.getParentElement()
                                        .getParentElement();

                                //get the first object association end id
                                String secondObjectAssociationEndId = secondObjectAssociationEnd
                                        .getAttributeValue("id");
                                String firstObjectAssociationEndId = (secondObjectAssociationEndId.equals("1"))
                                        ? "2"
                                        : "1";

                                // get all object associations with that name and with the same first object
                                List<?> objectAssociations = null;
                                try {
                                    XPath path = new JDOMXPath("associations/objectAssociation[classAssociation='"
                                            + classAssociation.getAttributeValue("id") + "' and "
                                            + "associationEnds/objectAssociationEnd[@element='object' and "
                                            + "@element-id='" + firstObject.getAttributeValue("id") + "' and "
                                            + "@id='" + firstObjectAssociationEndId + "']]");
                                    objectAssociations = path.selectNodes(snapshot);
                                } catch (JaxenException e) {
                                    e.printStackTrace();
                                }

                                // create the set node to receive the objects
                                evaluatedNode = new Element("node");
                                evaluatedNode.setAttribute("type", "opd");
                                evaluatedNode.setAttribute("data", "set");
                                evaluatedNode.setAttribute("instance", "t");

                                for (Iterator<?> iter = objectAssociations.iterator(); iter.hasNext();) {
                                    Element objectAssociation = (Element) iter.next();

                                    // for each object association, get the second object
                                    Element currentSecondObjectAssociationEnd = null;
                                    try {
                                        XPath path = new JDOMXPath("associationEnds/objectAssociationEnd[@id='"
                                                + secondObjectAssociationEndId + "']");
                                        currentSecondObjectAssociationEnd = (Element) path
                                                .selectSingleNode(objectAssociation);
                                    } catch (JaxenException e) {
                                        e.printStackTrace();
                                    }

                                    if (currentSecondObjectAssociationEnd != null) {
                                        // get the object corresponding to this association end
                                        Element currentSecondObject = null;
                                        try {
                                            XPath path = new JDOMXPath("elements/objects/object[@id='"
                                                    + currentSecondObjectAssociationEnd
                                                            .getAttributeValue("element-id")
                                                    + "']");
                                            currentSecondObject = (Element) path.selectSingleNode(domain);
                                        } catch (JaxenException e) {
                                            e.printStackTrace();
                                        }

                                        if (currentSecondObject != null) {
                                            // add a node to the set
                                            Element newNode = new Element("node");
                                            newNode.setAttribute("type", "opd");
                                            newNode.setAttribute("data",
                                                    currentSecondObject.getChildText("name").toUpperCase());
                                            newNode.setAttribute("instance", "t");

                                            evaluatedNode.addContent(newNode);
                                        }
                                    }
                                }
                            }
                        }
                    }

                } else {
                    System.out.println(
                            "Object \"" + domainObject.getAttributeValue("id") + "\" not found in  snapshot.");
                }

            }

        } else if (nodeData.equals("->")) {// including, excluding
            Element left = (Element) node.getChildren().get(0);
            Element right = (Element) node.getChildren().get(1);
            String rightData = right.getAttributeValue("data");
            Element set = evaluateExpressionNodeInSnapshot(left, instanceParameters, snapshot, domain, project);

            // with including or excluding, it will return the result of the set
            // after the inclusion or exclusion
            if (rightData.equals("including") || rightData.equals("excluding")) {
                Element param = evaluateExpressionNodeInSnapshot(right.getChild("node"), instanceParameters,
                        snapshot, domain, project);
                if (rightData.equals("including")) {
                    // add the node to the set
                    set.addContent(param);
                } else {// excluding
                        // look for the node in the set
                    Element nodeToBeDeleted = null;
                    try {
                        XPath path = new JDOMXPath(
                                "node[lower-case(@data)='" + param.getAttributeValue("data").toLowerCase() + "']");
                        nodeToBeDeleted = (Element) path.selectSingleNode(set);
                    } catch (JaxenException e) {
                        e.printStackTrace();
                    }
                    if (nodeToBeDeleted != null) {
                        // exclude the node from set
                        nodeToBeDeleted.detach();
                    } else {
                        //System.out.println("Object to be excluded \""+ param.getAttributeValue("data")
                        //      +"\" not found.");
                    }
                }
                evaluatedNode = set;
            }
        }

        else if (nodeData.equals("+") || nodeData.equals("-") || nodeData.equals("*") || nodeData.equals("/")) {
            Element left = (Element) node.getChildren().get(0);
            Element right = (Element) node.getChildren().get(1);

            //XMLUtilities.printXML(left);
            //XMLUtilities.printXML(right);

            Element evalLeft = evaluateExpressionNodeInSnapshot(left, instanceParameters, snapshot, domain,
                    project);
            Element evalRight = evaluateExpressionNodeInSnapshot(right, instanceParameters, snapshot, domain,
                    project);
            //XMLUtilities.printXML(evalLeft);
            //XMLUtilities.printXML(evalRight);

            evaluatedNode = (Element) node.clone();
            evaluatedNode.removeContent();
            evaluatedNode.setAttribute("type", "opd");
            evaluatedNode.setAttribute("instance", "t");

            switch (node.getAttributeValue("data").charAt(0)) {
            case '+': {
                double result = Double.parseDouble(evalLeft.getAttributeValue("data"))
                        + Double.parseDouble(evalRight.getAttributeValue("data"));

                evaluatedNode.setAttribute("data", String.valueOf(result));
            }
                break;
            case '-': {
                double result = Double.parseDouble(evalLeft.getAttributeValue("data"))
                        - Double.parseDouble(evalRight.getAttributeValue("data"));

                evaluatedNode.setAttribute("data", String.valueOf(result));
            }
                break;
            case '*': {
                double result = Double.parseDouble(evalLeft.getAttributeValue("data"))
                        * Double.parseDouble(evalRight.getAttributeValue("data"));

                evaluatedNode.setAttribute("data", String.valueOf(result));
            }
                break;
            case '/': {
                double result = Double.parseDouble(evalLeft.getAttributeValue("data"))
                        / Double.parseDouble(evalRight.getAttributeValue("data"));

                evaluatedNode.setAttribute("data", String.valueOf(result));
            }
                break;
            }
        } else if (node.getAttributeValue("type").equals("opd")) {
            // check whether the attribute is global (stereotype 'utility')
            String attrData = node.getAttributeValue("data");
            String attrNodeName;
            if (attrData.indexOf("(") > 0) {
                // parameterized attribute
                attrNodeName = attrData.substring(0, attrData.indexOf("(")).toLowerCase();
            } else {
                attrNodeName = attrData.toLowerCase();
            }
            Element classAttr = null;
            try {
                XPath path = new JDOMXPath(
                        "elements/classes/class[stereotype='utility']/attributes/attribute[lower-case(name)='"
                                + attrNodeName + "']");
                classAttr = (Element) path.selectSingleNode(project);
            } catch (JaxenException e) {
                e.printStackTrace();
            }
            if (classAttr != null) {
                Element utilityClass = classAttr.getParentElement().getParentElement();

                //             look for the domain object
                Element domainObject = null;
                try {
                    XPath path = new JDOMXPath(
                            "elements/objects/object[class='" + utilityClass.getAttributeValue("id") + "']");
                    domainObject = (Element) path.selectSingleNode(domain);
                } catch (JaxenException e) {
                    e.printStackTrace();
                }
                if (domainObject != null) {
                    // look for the snapshot object
                    Element snapshotObject = null;
                    try {
                        XPath path = new JDOMXPath(
                                "objects/object[@id='" + domainObject.getAttributeValue("id") + "']");
                        snapshotObject = (Element) path.selectSingleNode(snapshot);
                    } catch (JaxenException e) {
                        e.printStackTrace();
                    }
                    if (snapshotObject != null) {
                        Element objectAttribute = null;
                        try {
                            XPath path = new JDOMXPath(
                                    "attributes/attribute[@id='"
                                            + classAttr.getAttributeValue("id") + "' and @class='" + classAttr
                                                    .getParentElement().getParentElement().getAttributeValue("id")
                                            + "']");
                            objectAttribute = (Element) path.selectSingleNode(snapshotObject);
                        } catch (JaxenException e) {
                            e.printStackTrace();
                        }
                        if (objectAttribute != null) {
                            List<?> attrParameters = classAttr.getChild("parameters").getChildren();
                            if (attrParameters.size() > 0) {
                                // parameterized attribute
                                String attrParams = attrData.substring(attrData.indexOf('(') + 1,
                                        attrData.lastIndexOf(')'));
                                String query = "attributes/attribute[@id='"
                                        + objectAttribute.getAttributeValue("id") + "']/value/parameterizedValue[";
                                StringTokenizer st = new StringTokenizer(attrParams, ",");
                                for (Iterator<?> iter = attrParameters.iterator(); iter.hasNext();) {
                                    Element attrParam = (Element) iter.next();
                                    String attrParamName = "";
                                    if (st.hasMoreTokens()) {
                                        attrParamName = st.nextToken().trim().toLowerCase();
                                    } else {
                                        //System.out.println("There are less parameters than expected at attribute: "+ classAttr.getChildText("name"));
                                    }

                                    // look for the attribute parameter value in instance parameters
                                    Element instanceParameter = null;
                                    try {
                                        XPath path = new JDOMXPath("parameter[lower-case(name)='"
                                                + attrParamName.toLowerCase() + "']");
                                        instanceParameter = (Element) path.selectSingleNode(instanceParameters);
                                    } catch (JaxenException e) {
                                        e.printStackTrace();
                                    }

                                    if (instanceParameter != null) {

                                        query += "lower-case(parameters/parameter[@id='"
                                                + attrParam.getAttributeValue("id") + "']/value)='"
                                                + instanceParameter.getChildText("value").toLowerCase() + "'";

                                        if (iter.hasNext()) {
                                            query += " and ";
                                        }
                                    } else {
                                        //System.out.println("Error evaluating parameterized value: " +
                                        //      "instance parameter \""+ attrParamName +"\" not found.");
                                    }

                                }
                                query += "]";
                                //System.out.println(query);
                                if (st.hasMoreTokens()) {
                                    //System.out.println("There are more parameters than expected at attribute: "+ classAttr.getChildText("name"));
                                }
                                Element parameterizedValue = null;
                                try {
                                    XPath path = new JDOMXPath(query);
                                    parameterizedValue = (Element) path.selectSingleNode(snapshotObject);
                                } catch (JaxenException e) {
                                    e.printStackTrace();
                                }
                                if (parameterizedValue != null) {
                                    //returns the value given in the snapshot
                                    evaluatedNode = (Element) node.clone();
                                    evaluatedNode.removeContent();
                                    evaluatedNode.setAttribute("type", "opd");
                                    evaluatedNode.setAttribute("data", parameterizedValue.getChildText("value"));
                                    evaluatedNode.setAttribute("instance", "t");
                                } else {
                                    //System.out.println("Parameterized value "+ attrData +"not found in snapshot object.");
                                }
                            } else {
                                evaluatedNode = (Element) node.clone();
                                evaluatedNode.removeContent();
                                evaluatedNode.setAttribute("type", "opd");
                                evaluatedNode.setAttribute("data", objectAttribute.getChildText("value"));
                                evaluatedNode.setAttribute("instance", "t");
                            }
                        } else {
                            //System.out.println("Attribute \"" + classAttr.getChildText("name") + "\" not found in snapshot object.");
                        }
                    } else {
                        //System.out.println("Object with utility stereotype not found in snapshot.");
                    }
                } else {
                    //System.out.println("Object with utility stereotype not found in domain.");
                }
            } else {
                // returns the node itself
                evaluatedNode = (Element) node.clone();
            }
        }
        return evaluatedNode;

    }

    /**
     * This method creates a sequence of object diagrams (snapshots) for a given planning problem using a plan as a guide.
     * Starting from the initial state, the process fires each action in the plan compousing a movie.
     * @param xmlPlan
     * @param problem
     * @return
     */
    public static Element getMovie(Element xmlPlan, Element problem) {

        //hold problem, domain and project
        theproblem = problem;
        thedomain = problem.getParentElement().getParentElement();
        theproject = problem.getDocument().getRootElement();

        //set movie node
        Element movie = new Element("movie");

        //GET MOVIE
        // get init snapshot
        Element currentSnapshot = null;
        try {
            XPath path = new JDOMXPath("objectDiagrams/objectDiagram[sequenceReference='init']");
            currentSnapshot = (Element) path.selectSingleNode(problem);
        } catch (JaxenException e) {
            e.printStackTrace();
        }

        if (currentSnapshot != null) {
            // add it to movie (first scene)
            currentSnapshot = (Element) currentSnapshot.clone();
            movie.addContent(currentSnapshot);

            // set id = 1 (first scene)
            currentSnapshot.setAttribute("id", "1");

            // get metrics from inital snapshot
            //gatherMetricsDataset(metrics, null, currentSnapshot);

            // iterate over all actions in xmlPlan
            List<?> actions = xmlPlan.getChild("plan").getChildren("action");
            // diagrams sequence
            int i = 2;

            JLabel status = ItSIMPLE.getInstance().getPlanSimStatusBar();
            status.setText("Status: Generating movie... (0%)");
            int progressIndex = 0;

            for (Iterator<?> iter = actions.iterator(); iter.hasNext();) {
                Element action = (Element) iter.next();
                // get next snap shot
                String actionName = action.getAttributeValue("id");
                List<String> actionParams = new ArrayList<String>();
                for (Iterator<?> iterator = action.getChild("parameters").getChildren("parameter")
                        .iterator(); iterator.hasNext();) {
                    Element param = (Element) iterator.next();
                    actionParams.add(param.getAttributeValue("id"));
                }
                //   objectDiagrams   domain
                Element domain = problem.getParentElement().getParentElement();
                Element project = problem.getDocument().getRootElement();

                //generates next state
                currentSnapshot = nextState(actionName, actionParams, currentSnapshot, domain, project);

                // set the id
                currentSnapshot.setAttribute("id", String.valueOf(i++));

                //get action start time (restricted so far to INTEGER
                int startTime = i - 1;
                try {
                    startTime = Integer.parseInt(action.getChildText("startTime"));
                } catch (Exception e) {
                }
                //get action duration (restricted so far to INTEGER
                int duration = 1;
                try {
                    duration = Integer.parseInt(action.getChildText("duration"));
                } catch (Exception e) {
                }

                int snapshotRef = startTime + duration;

                // set the sequence time
                //currentSnapshot.getChild("sequenceReference").setText(action.getChildText("startTime"));
                currentSnapshot.getChild("sequenceReference").setText(Integer.toString(snapshotRef));

                movie.addContent(currentSnapshot);

                // get metrics from inital snapshot
                //gatherMetricsDataset(metrics, action, currentSnapshot);

                // refresh the status bar
                int progressPercentage = (int) ((double) ++progressIndex / (double) actions.size() * 100);
                status.setText("Status: Generating movie... (" + progressPercentage + "%)");

            }

            status.setText("Status: Done generating movie!");
        }

        //XMLUtilities.printXML(metrics);

        //PUT METRICS IN THE PLAN
        //xmlPlan.removeChildren("metrics"); //clear metrics
        //xmlPlan.addContent(metrics); //put the metrics in the plan

        //XMLUtilities.printXML(movie);
        return movie;
    }

    public static void buildPlanAnalysisDataset(Element analysis, Element xmlPlan, Element problem) {

        if (analysis != null && xmlPlan != null && problem != null) {
            Element currentSnapshot = null;
            try {
                XPath path = new JDOMXPath("objectDiagrams/objectDiagram[sequenceReference='init']");
                currentSnapshot = (Element) path.selectSingleNode(problem);
            } catch (JaxenException e) {
                e.printStackTrace();
            }
            Element planNode = xmlPlan.getChild("plan");
            List<?> actions = planNode.getChildren("action");

            //get the status bar
            JLabel status = ItSIMPLE.getInstance().getPlanSimStatusBar();
            int progressIndex = 0;
            status.setText("Status: Generating chart... (0%)");

            if (currentSnapshot != null) {
                for (int i = 0; i <= actions.size(); i++) {

                    // get the values first
                    List<?> variables = analysis.getChild("variables").getChildren("variable");
                    for (Iterator<?> iterator = variables.iterator(); iterator.hasNext();) {
                        Element variable = (Element) iterator.next();
                        if (variable.getAttributeValue("type").equals("attr")) {
                            // attribute

                            // get the attribute in the current snapshot
                            Element snapshotObjectAttr = null;
                            try {
                                XPath path = new JDOMXPath("objects/object[@id='"
                                        + variable.getChild("object").getAttributeValue("id")
                                        + "']/attributes/attribute[@class='"
                                        + variable.getChild("object").getChild("attribute")
                                                .getAttributeValue("class")
                                        + "' and @id='"
                                        + variable.getChild("object").getChild("attribute").getAttributeValue("id")
                                        + "']");
                                snapshotObjectAttr = (Element) path.selectSingleNode(currentSnapshot);
                            } catch (JaxenException e) {
                                e.printStackTrace();
                            }
                            if (snapshotObjectAttr != null) {
                                if (snapshotObjectAttr.getChild("value").getChildren().size() == 0) {
                                    // not parameterized attribute
                                    Element value = new Element("value");
                                    value.setAttribute("id", String
                                            .valueOf(variable.getChild("values").getChildren("value").size()));
                                    value.setText(snapshotObjectAttr.getChildText("value"));
                                    variable.getChild("values").addContent(value);
                                } else {
                                    // TODO parameterized attribute
                                }
                            }
                        }
                    }

                    // get next snap shot
                    if (i < actions.size()) {// in the last state, there is no "next state"
                        Element action = (Element) actions.get(i);
                        String actionName = action.getAttributeValue("id");
                        List<String> actionParams = new ArrayList<String>();
                        for (Iterator<?> iterator = action.getChild("parameters").getChildren("parameter")
                                .iterator(); iterator.hasNext();) {
                            Element param = (Element) iterator.next();
                            actionParams.add(param.getAttributeValue("id"));
                        }
                        //   objectDiagrams   domain
                        Element domain = problem.getParentElement().getParentElement();
                        Element project = problem.getDocument().getRootElement();

                        currentSnapshot = nextState(actionName, actionParams, currentSnapshot, domain, project);

                        // refresh the status bar
                        int progressPercentage = (int) ((double) ++progressIndex / (double) actions.size() * 100);
                        status.setText("Status: Generating chart... (" + progressPercentage + "%)");
                    }

                }

                status.setText("Status: Done generating chart!");

            }

            else {
                System.out.println(
                        "No initial snapshot was found in problem \"" + problem.getChildText("name") + "\".");
            }

            XMLUtilities.printXML(analysis);
        }

    }

    public static List<ChartPanel> drawCharts(Element analysis, Element problem) {
        List<ChartPanel> charts = new ArrayList<ChartPanel>();

        // draw the charts
        List<?> variables = analysis.getChild("variables").getChildren("variable");
        for (Iterator<?> iter = variables.iterator(); iter.hasNext();) {
            Element variable = (Element) iter.next();

            Element domainObject = null;
            try {
                XPath path = new JDOMXPath("elements/objects/object[@id='"
                        + variable.getChild("object").getAttributeValue("id") + "']");
                domainObject = (Element) path.selectSingleNode(problem.getParentElement().getParentElement());
            } catch (JaxenException e) {
                e.printStackTrace();
            }

            Element attribute = variable.getChild("object").getChild("attribute");
            Element classAttr = null;
            try {
                XPath path = new JDOMXPath(
                        "project/elements/classes/class[@id='" + attribute.getAttributeValue("class")
                                + "']/attributes/attribute[@id='" + attribute.getAttributeValue("id") + "']");
                classAttr = (Element) path.selectSingleNode(problem.getDocument());
            } catch (JaxenException e) {
                e.printStackTrace();
            }

            String chartTitle = domainObject.getChildText("name") + "." + classAttr.getChildText("name");

            if (variable.getAttributeValue("type").equals("attr")) {
                // attribute
                String attrType = variable.getChild("object").getChild("attribute").getAttributeValue("type");
                if (attrType.equals("1")) { //BOOLEAN attribute

                    XYSeriesCollection dataset = new XYSeriesCollection();
                    XYSeries series = new XYSeries("Boolean");
                    int stepIndex = 0;
                    for (Iterator<?> iterator = variable.getChild("values").getChildren("value")
                            .iterator(); iterator.hasNext();) {
                        Element value = (Element) iterator.next();
                        series.add(stepIndex++, (value.getText().equals("false") ? 0 : 1));
                    }
                    dataset.addSeries(series);

                    JFreeChart chart = ChartFactory.createXYStepChart(chartTitle, "Values", "Steps", dataset,
                            PlotOrientation.VERTICAL, false, true, false);

                    XYPlot plot = (XYPlot) chart.getPlot();
                    NumberAxis domainAxis = new NumberAxis("Steps");
                    domainAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
                    domainAxis.setAutoRangeIncludesZero(false);
                    plot.setDomainAxis(domainAxis);

                    String[] values = { "false", "true" };
                    SymbolAxis rangeAxis = new SymbolAxis("Values", values);
                    plot.setRangeAxis(rangeAxis);

                    ChartPanel chartPanel = new ChartPanel(chart);
                    chartPanel.setPreferredSize(new Dimension(chartPanel.getSize().width, 175));

                    charts.add(chartPanel);

                } else if (attrType.equals("2") || attrType.equals("3")) { //NUMERIC attributes

                    XYSeriesCollection dataset = new XYSeriesCollection();
                    XYSeries series = new XYSeries("variable");
                    int stepIndex = 0;
                    for (Iterator<?> iterator = variable.getChild("values").getChildren("value")
                            .iterator(); iterator.hasNext();) {
                        Element value = (Element) iterator.next();
                        series.add(stepIndex++, Double.parseDouble(value.getText()));
                    }
                    dataset.addSeries(series);

                    JFreeChart chart = ChartFactory.createXYLineChart(chartTitle, "Steps", "Values", dataset,
                            PlotOrientation.VERTICAL, false, true, false);

                    XYPlot xyPlot = (XYPlot) chart.getPlot();
                    XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) xyPlot.getRenderer();
                    renderer.setShapesVisible(true);
                    renderer.setShapesFilled(true);

                    NumberAxis rangeAxis = (NumberAxis) xyPlot.getRangeAxis();
                    rangeAxis.setAutoRangeIncludesZero(true);
                    rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
                    if (attrType.equals("2")) {
                        NumberAxis domainAxis = (NumberAxis) xyPlot.getDomainAxis();
                        domainAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
                    }

                    ChartPanel chartPanel = new ChartPanel(chart);

                    charts.add(chartPanel);
                } else if (!attrType.equals("4")) {//NOT PRIMITIVE attributes

                    Element attrClass = null;
                    try {
                        XPath path = new JDOMXPath(
                                "project/elements/classes/class[@id='" + classAttr.getChildText("type") + "']");
                        attrClass = (Element) path.selectSingleNode(problem.getDocument());
                    } catch (JaxenException e) {
                        e.printStackTrace();
                    }

                    if (attrClass != null) {

                        List<Element> classes = XMLUtilities.getClassDescendents(attrClass);
                        String query = "elements/objects/object[";
                        for (Iterator<?> iterator = classes.iterator(); iterator.hasNext();) {
                            Element childClass = (Element) iterator.next();
                            query += "class='" + childClass.getAttributeValue("id") + "'";

                            query += " or ";// the last or is for the parent class                     

                        }
                        query += "class='" + attrClass.getAttributeValue("id") + "']";

                        // get all the objects of all descendant classes, including the parent class
                        List<?> objects = null;
                        try {
                            XPath path = new JDOMXPath(query);
                            objects = path.selectNodes(problem.getParentElement().getParentElement());
                        } catch (JaxenException e) {
                            e.printStackTrace();
                        }
                        if (objects.size() > 0) {
                            //build a list with all the objects names                     
                            String[] names = new String[objects.size() + 1];// the array is for the axis
                            names[0] = "null";// default null value

                            List<String> objectNames = new ArrayList<String>();
                            int i = 1;
                            for (Iterator<?> iterator = objects.iterator(); iterator.hasNext();) {
                                Element object = (Element) iterator.next();
                                names[i++] = object.getChildText("name");
                                objectNames.add(object.getChildText("name").toLowerCase());
                            }

                            XYSeriesCollection dataset = new XYSeriesCollection();
                            XYSeries series = new XYSeries("Objects");
                            int stepIndex = 0;
                            for (Iterator<?> iterator = variable.getChild("values").getChildren("value")
                                    .iterator(); iterator.hasNext();) {
                                Element value = (Element) iterator.next();

                                series.add(stepIndex++, objectNames.indexOf(value.getText().toLowerCase()) + 1);
                            }
                            dataset.addSeries(series);

                            // draw the chart
                            JFreeChart chart = ChartFactory.createXYStepChart(chartTitle, "Objects", "Steps",
                                    dataset, PlotOrientation.VERTICAL, false, true, false);

                            XYPlot plot = (XYPlot) chart.getPlot();
                            NumberAxis domainAxis = new NumberAxis("Steps");
                            domainAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
                            domainAxis.setAutoRangeIncludesZero(false);
                            plot.setDomainAxis(domainAxis);

                            SymbolAxis rangeAxis = new SymbolAxis("Objects", names);
                            plot.setRangeAxis(rangeAxis);

                            ChartPanel chartPanel = new ChartPanel(chart);

                            charts.add(chartPanel);
                        }
                    }
                }
            }
        }

        return charts;
    }

    /**
     * This method creates a html version of the plan analysis with charts based on the seceted variables.
     * @param analysis the xml node with the values of all attributes being analyzed
     * @param the plan (in a xml format)
     * @param the problem (in xml format)
     * @return a string with representing the content of a html file.
     */
    public static String createHTMLPlanAnalysis(Element analysis, Element xmlPlan, Element problem) {

        String html = "<html> \n" + "   <head> \n"
                + "      <meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\" /> \n"
                + "      <title>itSIMPLE Plan Analysis - Variable Tracking</title> \n"
                + "      <script language=\"JavaScript\" src=\"jsclass/FusionCharts.js\"></script> \n"
                + "   </head> \n" + "   <body> \n";

        //Set html Title
        html += "       <h1 align=\"center\">" + problem.getChildText("name") + "</h1> <br><br> \n";

        Integer chartIndex = 0;
        // draw the charts
        List<?> variables = analysis.getChild("variables").getChildren("variable");
        for (Iterator<?> iter = variables.iterator(); iter.hasNext();) {
            Element variable = (Element) iter.next();
            //Get object (from domain, to get the name and properties)
            Element domainObject = null;
            try {
                XPath path = new JDOMXPath("elements/objects/object[@id='"
                        + variable.getChild("object").getAttributeValue("id") + "']");
                domainObject = (Element) path.selectSingleNode(problem.getParentElement().getParentElement());
            } catch (JaxenException e) {
                e.printStackTrace();
            }
            //get attribute (from domain, to get the name and its properties)
            Element attribute = variable.getChild("object").getChild("attribute");
            Element classAttr = null;
            try {
                XPath path = new JDOMXPath(
                        "project/elements/classes/class[@id='" + attribute.getAttributeValue("class")
                                + "']/attributes/attribute[@id='" + attribute.getAttributeValue("id") + "']");
                classAttr = (Element) path.selectSingleNode(problem.getDocument());
            } catch (JaxenException e) {
                e.printStackTrace();
            }

            String chartTitle = domainObject.getChildText("name") + "." + classAttr.getChildText("name");
            //html += "       <h2><img src=\"LogoSmalTest.png\"> " + chartTitle + "</h2> \n"; 
            html += "       <h2>" + chartTitle + "</h2> \n";

            if (variable.getAttributeValue("type").equals("attr")) {
                // attribute
                String attrType = variable.getChild("object").getChild("attribute").getAttributeValue("type");
                String attrTypeStr = "";
                String dataXML = ""; //XML data in the FusionChart format

                //XMLUtilities.printXML(variable);

                //BOOLEAN attribute
                if (attrType.equals("1")) {
                    attrTypeStr = "Boolean";

                    int horizLines = variable.getChild("values").getChildren("value").size() - 1;
                    //Set the string containing the xml data of the chart (FusionChart format)
                    dataXML = "<graph caption='Attribute " + chartTitle + "' subcaption='(" + attrTypeStr + ")' "
                            + "xAxisName='Steps' yAxisName='" + classAttr.getChildText("name")
                            + "' yAxisMinValue='0' yAxisMaxValue='3' "
                            + "zeroPlaneThickness='0' showhovercap='0' numVDivLines='" + horizLines + "' "
                            + "numdivlines='2' showLimits='0' showDivLineValue='0' decimalPrecision='0' "
                            + "formatNumberScale='0' showNames='1' showValues='0' showAlternateHGridColor='1' "
                            + "AlternateHGridColor='ff5904' divLineColor='FF0000' divLineAlpha='20' alternateHGridAlpha='5' "
                            + "showShadow='0'>";

                    String categories = "<categories>";
                    String dataSetTrue = "<dataset seriesname='True' color='1D8BD1' showValue='1' alpha='100' showAnchors='1' lineThickness='5'>";
                    String dataSetFalse = "<dataset seriesname='False' color='FF0000' showValue='1' alpha='80' showAnchors='1' lineThickness='5'>";

                    //read each value (X,Y) and creat each set of the graph
                    for (Iterator<?> iterator = variable.getChild("values").getChildren("value")
                            .iterator(); iterator.hasNext();) {
                        Element value = (Element) iterator.next();

                        categories += "<category name='" + value.getAttributeValue("id") + "' />";
                        dataSetTrue += "<set value='2' alpha='" + (value.getText().equals("false") ? "1" : "100")
                                + "' />";
                        dataSetFalse += "<set value='1' alpha='" + (value.getText().equals("false") ? "100" : "1")
                                + "' />";

                        //Just to create a final line to show what happen after the plan.
                        if (!iterator.hasNext()) {
                            //int duringLastStep = Integer.parseInt(value.getAttributeValue("id")) + 1;
                            //categories += "<category name='" + duringLastStep + "' />";
                            categories += "<category name='' />";
                            dataSetTrue += "<set value='2' alpha='"
                                    + (value.getText().equals("false") ? "1" : "100") + "' />";
                            dataSetFalse += "<set value='1' alpha='"
                                    + (value.getText().equals("false") ? "100" : "1") + "' />";
                        }

                    }

                    categories += "</categories>";
                    dataSetTrue += "</dataset>";
                    dataSetFalse += "</dataset>";

                    dataXML += categories + dataSetTrue + dataSetFalse;

                    dataXML += "<trendlines>"
                            + "<line startvalue='2' displayValue='true' color='009999' thickness='1' isTrendZone='0'/>"
                            + "<line startvalue='1' displayValue='false' color='FF0000' thickness='1' isTrendZone='0'/>"
                            + "</trendlines>";

                    dataXML += "</graph>";

                    //Create the html chart component with the dataXML
                    html += "       <table width=\"98%\" border=\"0\" cellspacing=\"0\" cellpadding=\"3\" align=\"center\"> \n"
                            + "           <tr> \n"
                            + "               <td valign=\"top\" class=\"text\" align=\"center\"> \n"
                            + "                   <div id=\"chartdiv" + chartIndex + "\" align=\"center\">"
                            + chartTitle + "</div> \n"
                            + "                       <script type=\"text/javascript\"> \n"
                            + "                           var chart" + chartIndex
                            + " = new FusionCharts(\"charts/FCF_MSLine.swf\", \"ChartId\", \"750\", \"400\"); \n"
                            + "                           chart" + chartIndex + ".setDataXML(\"" + dataXML
                            + "\"); \n" + "                           chart" + chartIndex + ".render(\"chartdiv"
                            + chartIndex + "\"); \n" + "                       </script> \n"
                            + "               </td> \n" + "           </tr> \n" + "       </table> \n";

                }

                //NUMERIC attributes
                else if (attrType.equals("2") || attrType.equals("3")) {

                    if (attrType.equals("2"))
                        attrTypeStr = "Integer";
                    else
                        attrTypeStr = "Float";

                    //Set the string containing the xml data of the chart (FusionChart format)
                    dataXML = "<graph caption='Attribute " + chartTitle + "' subcaption='(" + attrTypeStr + ")' "
                            + "xAxisName='Steps' yAxisMinValue='0' yAxisName='Value' "
                            + "decimalPrecision='0' formatNumberScale='0' showNames='1' "
                            + "showValues='0' showAlternateHGridColor='1' AlternateHGridColor='ff5904' "
                            + "divLineColor='ff5904' divLineAlpha='20' alternateHGridAlpha='5' >";

                    //read each value (X,Y) and creat each set of the graph
                    for (Iterator<?> iterator = variable.getChild("values").getChildren("value")
                            .iterator(); iterator.hasNext();) {
                        Element value = (Element) iterator.next();
                        dataXML += "<set name='" + value.getAttributeValue("id") + "' value='" + value.getText()
                                + "' hoverText='" + value.getAttributeValue("id") + "'/>";
                        //html += "       <p>Chart Point: (X=" + value.getAttributeValue("id") + "; Y=" + value.getText() + ")</p> \n";                   

                        //extend the X Axis by one unit for convinience when viewing the last points
                        if (!iterator.hasNext()) {
                            int lastIndex = Integer.parseInt(value.getAttributeValue("id")) + 1;
                            dataXML += "<set name='" + lastIndex + "' value='' hoverText='" + lastIndex + "'/>";
                        }
                    }

                    dataXML += "</graph>";

                    //Create the html chart component with the dataXML
                    html += "       <table width=\"98%\" border=\"0\" cellspacing=\"0\" cellpadding=\"3\" align=\"center\"> \n"
                            + "           <tr> \n"
                            + "               <td valign=\"top\" class=\"text\" align=\"center\"> \n"
                            + "                   <div id=\"chartdiv" + chartIndex + "\" align=\"center\">"
                            + chartTitle + "</div> \n"
                            + "                       <script type=\"text/javascript\"> \n"
                            + "                           var chart" + chartIndex
                            + " = new FusionCharts(\"charts/FCF_Line.swf\", \"ChartId\", \"750\", \"400\"); \n"
                            + "                           chart" + chartIndex + ".setDataXML(\"" + dataXML
                            + "\"); \n" + "                           chart" + chartIndex + ".render(\"chartdiv"
                            + chartIndex + "\"); \n" + "                       </script> \n"
                            + "               </td> \n" + "           </tr> \n" + "       </table> \n";
                }

                //NOT PRIMITIVE attributes
                else if (!attrType.equals("4")) {

                    //Get the corresponding class
                    Element attrClass = null;
                    try {
                        XPath path = new JDOMXPath(
                                "project/elements/classes/class[@id='" + classAttr.getChildText("type") + "']");
                        attrClass = (Element) path.selectSingleNode(problem.getDocument());
                    } catch (JaxenException e) {
                        e.printStackTrace();
                    }

                    if (attrClass != null) {
                        attrTypeStr = attrClass.getChildText("name");

                        List<Element> classes = XMLUtilities.getClassDescendents(attrClass);
                        String query = "elements/objects/object[";
                        for (Iterator<?> iterator = classes.iterator(); iterator.hasNext();) {
                            Element childClass = (Element) iterator.next();
                            query += "class='" + childClass.getAttributeValue("id") + "'";

                            query += " or ";// the last or is for the parent class                     

                        }
                        query += "class='" + attrClass.getAttributeValue("id") + "']";

                        // get all the objects of all descendant classes, including the parent class
                        List<?> objects = null;
                        try {
                            XPath path = new JDOMXPath(query);
                            objects = path.selectNodes(problem.getParentElement().getParentElement());
                        } catch (JaxenException e) {
                            e.printStackTrace();
                        }
                        if (objects.size() > 0) {
                            //build a list with all the objects names                     
                            String[] names = new String[objects.size() + 1];// the array is for the axis
                            names[0] = "null";// default null value

                            List<String> objectNames = new ArrayList<String>();
                            int i = 1;
                            for (Iterator<?> iterator = objects.iterator(); iterator.hasNext();) {
                                Element object = (Element) iterator.next();
                                names[i++] = object.getChildText("name");
                                objectNames.add(object.getChildText("name").toLowerCase());
                            }

                            /**
                            XYSeriesCollection dataset = new XYSeriesCollection();
                            XYSeries series = new XYSeries("Objects");
                            int stepIndex = 0;
                            for (Iterator<?> iterator = variable.getChild("values").getChildren("value").iterator(); iterator
                            .hasNext();) {
                            Element value = (Element)iterator.next();
                                
                            series.add(stepIndex++, objectNames.indexOf(value.getText().toLowerCase())+1);
                            }
                            dataset.addSeries(series);
                                
                                
                            // draw the chart
                            JFreeChart chart = ChartFactory.createXYStepChart(chartTitle, "Objects", "Steps", dataset, PlotOrientation.VERTICAL, false, true, false); 
                                
                            XYPlot plot = (XYPlot)chart.getPlot(); 
                            NumberAxis domainAxis = new NumberAxis("Steps"); 
                            domainAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits()); 
                            domainAxis.setAutoRangeIncludesZero(false); 
                            plot.setDomainAxis(domainAxis);                     
                                
                                
                            SymbolAxis rangeAxis = new SymbolAxis("Objects", names); 
                            plot.setRangeAxis(rangeAxis); 
                                
                            ChartPanel chartPanel = new ChartPanel(chart);
                                
                            charts.add(chartPanel);
                            **/
                        }
                    }
                }
            }
            chartIndex++;
        }

        html = html + "  </body> \n" + "</html>";

        /**
        String html ="<html> \n" +
             "   <body> \n" +
             "      <h1>Some header</h1> \n" +
             "      <p>A paragraph with a <a href=\"http://www.google.com\">link</a>.</p> \n" +
             "  </body> \n"+
            "</html>";
         **/

        return html;
    }

    /**
      * This method fill out the metrics' datasets for a given snapshot
      * @param metrics the set of metrics been capture/analyzed
      * @param action the action that produced the snapshot (null when is the init)
      * @param snapshot the snapshot
      */
    public static void setMetricDatasetsForSnapshot(Element metrics, Element action, Element snapshot) {

        if (metrics != null && snapshot != null) {

            //get the status bar
            //JLabel status = ItSIMPLE.getInstance().getPlanSimStatusBar();
            //int progressIndex = 0;
            //status.setText("Status: Generating chart... (0%)");
            for (Iterator it = metrics.getChildren().iterator(); it.hasNext();) {
                Element eacMetric = (Element) it.next();

                //Sets the sequence reference
                String sequenceReference = snapshot.getChildText("sequenceReference");
                //System.out.println(sequenceReference);
                if (sequenceReference.equals("init")) {
                    sequenceReference = "0";
                } else {
                    try {
                        //Parse to int (TODO, treat the other cases)
                        Integer ref = Integer.parseInt(sequenceReference);
                        sequenceReference = ref.toString();
                    } catch (Exception e) {
                        System.out.println("Unable to identify reference " + sequenceReference + " on the plan");
                    }
                }

                //Check the type
                //VARIABLE - ATTRIBUE
                if (eacMetric.getChildText("type").equals("variable")) {
                    // variable
                    /**
                     * qualityMetric
                     *  name
                     *  type
                     *  variable
                     *      chosenVariable
                     *          object
                     *              variable
                     *  dataset
                     *      set
                     *      set
                     *      ...
                     */
                    Element chosenVariable = eacMetric.getChild("variable").getChild("chosenVariable");
                    Element chosenObject = chosenVariable.getChild("object");
                    Element chosenAttribute = chosenObject.getChild("attribute");

                    // get the attribute in the current snapshot
                    Element snapshotObjectAttr = null;
                    try {
                        XPath path = new JDOMXPath("objects/object[@id='" + chosenObject.getAttributeValue("id")
                                + "']/attributes/attribute[@class='" + chosenAttribute.getAttributeValue("class")
                                + "' and @id='" + chosenAttribute.getAttributeValue("id") + "']");
                        snapshotObjectAttr = (Element) path.selectSingleNode(snapshot);
                    } catch (JaxenException e) {
                        e.printStackTrace();
                    }
                    if (snapshotObjectAttr != null) {
                        if (snapshotObjectAttr.getChild("value").getChildren().size() == 0) {
                            // not parameterized attribute
                            Element set = new Element("set");
                            set.setAttribute("name", sequenceReference);
                            set.setAttribute("value", snapshotObjectAttr.getChildText("value"));
                            String comments = "";
                            if (action != null) {
                                comments = action.getAttributeValue("id");
                            } else {
                                comments = "init";
                            }
                            set.setAttribute("comments", comments);
                            eacMetric.getChild("dataset").addContent(set);
                        } else {
                            //TODO: parameterized attribute
                        }
                    }
                }
                //If it's a expression
                //TODO: evaluate an expression with objects and global variables.
                else if (eacMetric.getChildText("type").equals("expression")) {
                    // expression
                    /**
                     * qualityMetric
                     *  name
                     *  type
                     *  expression
                     *      rule
                     *  dataset
                     *      set
                     *      set
                     *      ...
                     */
                    Element expressionNode = eacMetric.getChild("expression");
                    String rule = expressionNode.getChildText("rule");
                    ExpressionTreeBuilder treeBuilder = new ExpressionTreeBuilder(rule);
                    Element expTree = treeBuilder.getExpressionTree();
                    //XMLUtilities.printXML(expTree);

                    Element eval = evaluateExpressionNodeInSnapshot(expTree, null, snapshot, thedomain, theproject);
                    //XMLUtilities.printXML(eval);

                    Element set = new Element("set");
                    set.setAttribute("name", sequenceReference);
                    if (eval != null) {
                        set.setAttribute("value", eval.getAttributeValue("data"));
                    }
                    //put zero if something went wrong
                    else {
                        set.setAttribute("value", "0");
                        System.out.println("System cound not parse the metric expression at snapshot reference '"
                                + sequenceReference + "'");
                    }

                    String comments = "";
                    if (action != null) {
                        comments = action.getAttributeValue("id");
                    } else {
                        comments = "init";
                    }

                    set.setAttribute("comments", comments);
                    eacMetric.getChild("dataset").addContent(set);

                }

                //if it's an actionCounter
                else if (eacMetric.getChildText("type").equals("actionCounter")) {
                    // actionCounter
                    /**
                     * qualityMetric
                     *  name
                     *  type
                     *  actionCounter
                     *      chosenOperator
                     *          parameters
                     *              parameter
                     *  dataset
                     *      set
                     *      set
                     *      ...
                     */
                    Element chosenOperator = eacMetric.getChild("actionCounter").getChild("chosenOperator");
                    Element chosenParameters = chosenOperator.getChild("parameters");
                    Element counterValue = eacMetric.getChild("actionCounter").getChild("value");

                    if (action != null) {
                        String operatorName = chosenOperator.getAttributeValue("name").trim().toLowerCase();
                        String actionName = action.getAttributeValue("id").trim().toLowerCase();
                        if (actionName.equals(operatorName)) {
                            boolean canCount = true;
                            //check parameters
                            List actionParametersList = action.getChild("parameters").getChildren();
                            List chosenParametersList = chosenParameters.getChildren();
                            //Check each parameter to see if is the chosen action
                            for (int i = 0; i < actionParametersList.size(); i++) {
                                Element actionPar = (Element) actionParametersList.get(i);
                                Element chosenPar = (Element) chosenParametersList.get(i);

                                String actionParStr = actionPar.getAttributeValue("id").trim().toLowerCase();
                                String chosenParStr = chosenPar.getAttributeValue("objectName").trim()
                                        .toLowerCase();

                                if (!chosenParStr.equals("")) {//if there is something specify
                                    if (!actionParStr.equals(chosenParStr)) {//if it is not the parameter
                                        canCount = false;
                                    }
                                }
                            }

                            //update the counter
                            if (canCount) {
                                int thevalue = Integer.parseInt(counterValue.getText());
                                thevalue += 1;
                                counterValue.setText(Integer.toString(thevalue));
                            }

                        }
                    }

                    //add set element to dataset
                    Element set = new Element("set");
                    set.setAttribute("name", sequenceReference);
                    set.setAttribute("value", counterValue.getText());
                    String comments = "";
                    if (action != null) {
                        comments = action.getAttributeValue("id");
                    } else {
                        comments = "init";
                    }
                    set.setAttribute("comments", comments);
                    eacMetric.getChild("dataset").addContent(set);

                }

            }

        }
        //XMLUtilities.printXML(metrics);

    }

    /**
     * This method fill out the metrics' data set only when they do not require simulation (e.g., action counter)
     * @param metrics the reference metrics (domain and problem, all together). It is the result of createMetricNode method
     * @param xmlPlan the plan
     */
    public static void setMetricDatasetsForNoSimulation(Element metrics, Element xmlPlan) {

        if (metrics != null && xmlPlan != null) {

            //create the first set/value 0 which represent the initial state
            for (Iterator it = metrics.getChildren().iterator(); it.hasNext();) {
                Element eacMetric = (Element) it.next();

                //add set element to dataset
                Element set = new Element("set");
                set.setAttribute("name", "0");
                set.setAttribute("value", "0");
                String comments = "init";
                set.setAttribute("comments", comments);
                eacMetric.getChild("dataset").addContent(set);
            }

            //create the other set/value for the plan
            List<Element> actions = xmlPlan.getChild("plan").getChildren("action");
            int planIndex = 0;

            for (Iterator<Element> ita = actions.iterator(); ita.hasNext();) {
                Element action = ita.next();

                //analyze each metric
                for (Iterator it = metrics.getChildren().iterator(); it.hasNext();) {
                    Element eacMetric = (Element) it.next();

                    //get action start time (restricted so far to INTEGER)
                    int startTime = planIndex;
                    try {
                        startTime = Integer.parseInt(action.getChildText("startTime"));
                    } catch (Exception e) {
                    }
                    //get action duration (restricted so far to INTEGER)
                    int duration = 1;
                    try {
                        duration = Integer.parseInt(action.getChildText("duration"));
                    } catch (Exception e) {
                    }
                    //Action index
                    int snapshotRef = startTime + duration;

                    //Sets the sequence reference
                    String sequenceReference = Integer.toString(snapshotRef);
                    //System.out.println(sequenceReference);

                    //if it's an actionCounter
                    if (eacMetric.getChildText("type").equals("actionCounter")) {
                        // variable
                        /**
                         * qualityMetric
                         *  name
                         *  type
                         *  actionCounter
                         *      chosenOperator
                         *          parameters
                         *              parameter
                         *              ...
                         *  dataset
                         *      set
                         *      set
                         *      ...
                         */
                        Element chosenOperator = eacMetric.getChild("actionCounter").getChild("chosenOperator");
                        Element chosenParameters = chosenOperator.getChild("parameters");
                        Element counterValue = eacMetric.getChild("actionCounter").getChild("value");

                        String operatorName = chosenOperator.getAttributeValue("name").trim().toLowerCase();
                        String actionName = action.getAttributeValue("id").trim().toLowerCase();
                        if (actionName.equals(operatorName)) {
                            boolean canCount = true;
                            //check parameters
                            List actionParametersList = action.getChild("parameters").getChildren();
                            List chosenParametersList = chosenParameters.getChildren();
                            //Check each parameter to see if is the chosen action
                            for (int i = 0; i < actionParametersList.size(); i++) {
                                Element actionPar = (Element) actionParametersList.get(i);
                                Element chosenPar = (Element) chosenParametersList.get(i);

                                String actionParStr = actionPar.getAttributeValue("id").trim().toLowerCase();
                                String chosenParStr = chosenPar.getAttributeValue("objectName").trim()
                                        .toLowerCase();

                                if (!chosenParStr.equals("")) {//if there is something specify
                                    if (!actionParStr.equals(chosenParStr)) {//if it is not the parameter
                                        canCount = false;
                                    }
                                }
                            }

                            //update the counter
                            if (canCount) {
                                int thevalue = Integer.parseInt(counterValue.getText());
                                thevalue += 1;
                                counterValue.setText(Integer.toString(thevalue));
                            }

                        }

                        //add set element to dataset
                        Element set = new Element("set");
                        set.setAttribute("name", sequenceReference);
                        set.setAttribute("value", counterValue.getText());
                        String comments = action.getAttributeValue("id");
                        set.setAttribute("comments", comments);
                        eacMetric.getChild("dataset").addContent(set);

                    }
                    //OTHER CASES (FUTURE)

                }

                planIndex++;
            }

        }
        //XMLUtilities.printXML(metrics);

    }

    /**
     * This method creates the metrics node for containing all metrics (together) from domain and problem
     * for filling the datasets
     * @param problem
     * @param domain
     */
    public static Element createMetricsNode(Element problem, Element domain) {

        //hold problem, domain and project
        theproblem = problem;
        thedomain = domain;
        theproject = domain.getDocument().getRootElement();

        //METRICS PREPARATION
        //set metrics node
        Element metrics = new Element("metrics");
        //collect all metrics
        List<Element> metricList = new ArrayList<Element>();

        //gather metrics from domain
        List domainMetrics = null;
        try {
            XPath path = new JDOMXPath("metrics/qualityMetric");
            domainMetrics = path.selectNodes(problem.getParentElement().getParentElement());
        } catch (JaxenException e) {
            e.printStackTrace();
        }
        if (domainMetrics != null) {
            metricList.addAll(domainMetrics);
        }

        //gather metrics from problem
        List problemMetrics = null;
        try {
            XPath path = new JDOMXPath("metrics/qualityMetric");
            problemMetrics = path.selectNodes(problem);
        } catch (JaxenException e) {
            e.printStackTrace();
        }
        if (problemMetrics != null) {
            metricList.addAll(problemMetrics);
        }

        for (Iterator it = metricList.iterator(); it.hasNext();) {
            Element eaMetric = (Element) it.next();

            Element refMetric = new Element(eaMetric.getName());
            /**
             * qualityMetric
             *  name
             *  type
             *  type node (expession, variavle, or actionCounter)
             *  dataset
             *  value
             *  evaluation
             */
            //set main attributes of node quality metric
            Element levelParent = eaMetric.getParentElement().getParentElement();
            refMetric.setAttribute("level", levelParent.getName());
            refMetric.setAttribute("id", eaMetric.getAttributeValue("id"));
            //cloning the basics
            refMetric.addContent((Element) eaMetric.getChild("name").clone()); //name
            refMetric.addContent((Element) eaMetric.getChild("type").clone()); //type
            refMetric.addContent((Element) eaMetric.getChild("weight").clone()); //weight
            String type = eaMetric.getChildText("type");
            refMetric.addContent((Element) eaMetric.getChild(type).clone()); //type node (variable, expression, actionCounter)

            refMetric.addContent((Element) eaMetric.getChild("preferenceFunction").clone()); //preferenceFunction

            //facilitate search and action counter, put the name of the
            //  operator at the qualitMetric and also the name of parameters
            if (type.equals("actionCounter")) {
                //find operator in the project
                Element chosenOperator = refMetric.getChild("actionCounter").getChild("chosenOperator");
                Element chosenParameters = chosenOperator.getChild("parameters");

                //Put the name of the operator
                Element operator = null;
                try {
                    XPath path = new JDOMXPath("project/elements/classes/class[@id='"
                            + chosenOperator.getAttributeValue("class") + "']/operators/operator[@id='"
                            + chosenOperator.getAttributeValue("id") + "']");
                    operator = (Element) path.selectSingleNode(problem.getDocument());
                } catch (JaxenException e) {
                    e.printStackTrace();
                }
                if (operator != null) {
                    //set the name as a attribute of the node "name"
                    chosenOperator.setAttribute("name", operator.getChildText("name"));
                }

                //put the name of the parameters
                for (Iterator it1 = chosenParameters.getChildren().iterator(); it1.hasNext();) {
                    Element param = (Element) it1.next();
                    String objectName = "";
                    if (!param.getAttributeValue("object").equals("")) {
                        //find object in the domain
                        Element pObject = null;
                        try {
                            XPath path = new JDOMXPath(
                                    "elements/objects/object[@id='" + param.getAttributeValue("object") + "']");
                            pObject = (Element) path
                                    .selectSingleNode(problem.getParentElement().getParentElement());
                        } catch (JaxenException e) {
                            e.printStackTrace();
                        }
                        if (pObject != null) {
                            objectName = pObject.getChildText("name");
                        }
                    }
                    param.setAttribute("objectName", objectName);
                }

                //add this node for storing the counter amount (total for example
                Element value = new Element("value");
                value.setText("0");
                refMetric.getChild("actionCounter").addContent(value);
            }

            refMetric.addContent(new Element("dataset"));

            //node to store metric value and evaluation
            refMetric.addContent(new Element("value"));
            Element evaluationNode = new Element("evaluation");
            evaluationNode.setAttribute("value", "");
            refMetric.addContent(evaluationNode);

            metrics.addContent(refMetric);

        }
        //XMLUtilities.printXML(metrics);

        return metrics;
    }

    /**
     * This method fill out the metric dataset for the problem solution given the plan. 
     * Since some metrics require simulation, the methods uses the movie for 
     * creating the sets/values. If a movie is provided the method uses that to fill out the
     * value sets; otherwise, the method can create it by itself.
     * @param metrics the reference metrics (domain and problem, all together). It is the result of createMetricNode method
     * @param xmlPlan the plan
     * @param problem the problem
     * @param domain the domain
     * @param movie the movie (can also be null or a given one)
     */
    public static void createMetricDatasets(Element metrics, Element xmlPlan, Element problem, Element domain,
            Element movie) {

        //1. Check if the metrics need simualtion.
        //  The cases in which simulation is required are the types: variable, expression
        //  The cases that simulation is NOT required: actionCounter.

        boolean needSilumation = false;
        List simulationMetrics = null;
        try {
            XPath path = new JDOMXPath("qualityMetric[type='variable' or type='expression']");
            simulationMetrics = path.selectNodes(metrics);
        } catch (JaxenException e) {
            e.printStackTrace();
        }
        if (simulationMetrics != null && simulationMetrics.size() > 0) {
            needSilumation = true;
        }

        //if we need simulation we need the movie
        if (needSilumation) {
            if (movie == null) {
                movie = getMovie(xmlPlan, problem);
            }
            Element snapshotInit = null;
            try {
                XPath path = new JDOMXPath("objectDiagram[sequenceReference='init']");
                snapshotInit = (Element) path.selectSingleNode(movie);
            } catch (JaxenException e) {
                e.printStackTrace();
            }
            if (snapshotInit != null) {
                // get metrics from inital snapshot
                setMetricDatasetsForSnapshot(metrics, null, snapshotInit);

                int actionIndex = 0;
                List<Element> actions = xmlPlan.getChild("plan").getChildren("action");
                List<Element> snapshots = movie.getChildren("objectDiagram");
                for (Iterator<?> iter = snapshots.iterator(); iter.hasNext();) {
                    Element snapshot = (Element) iter.next();
                    //jump init scene because its was already done
                    if (!snapshot.getChildText("sequenceReference").equals("init")) {

                        Element currentAction = actions.get(actionIndex);
                        // get metrics from inital snapshot
                        setMetricDatasetsForSnapshot(metrics, currentAction, snapshot);

                        actionIndex++;
                    }
                }
            }

        }
        //in case there is no need for simulation
        else {
            //System.out.println("No simulation Case");
            setMetricDatasetsForNoSimulation(metrics, xmlPlan);
        }

        //XMLUtilities.printXML(metrics);

    }

    /*public static void main(String[] args){
      Element project = null;
      try {
     project = XMLUtilities.readFromFile("examples/LogisticDomainv2.xml").getRootElement();
      } catch (JDOMException e) {
     e.printStackTrace();
      } catch (IOException e) {
     e.printStackTrace();
      }
      Element domain = (Element)project.getChild("diagrams").getChild("planningDomains").getChildren("domain").get(1);
          
      List<String> parameters = new ArrayList<String>();
      parameters.add("SATELLITE0");
      parameters.add("INSTRUMENT0");
      parameters.add("STAR0");
      parameters.add("IMAGE2");      
          
      Element snapshot = null;
      try {
     XPath path = new JDOMXPath("diagrams/planningDomains/domain[2]/planningProblems/problem[1]/objectDiagrams/objectDiagram[1]");         
     snapshot = (Element)path.selectSingleNode(project);                  
      } catch (JaxenException e) {         
     e.printStackTrace();
      }
      System.out.println("##################### Step 1 #####################");
      parameters.add("TRUCK2");
      parameters.add("PKG2");
      parameters.add("LOCATIONRJ1");
      //parameters.add("TABLE1");
      Element next1 = nextState("LOADTRUCK", parameters, snapshot, domain, project);
      System.out.println("##################################################\n");
          
      System.out.println("##################### Step 2 #####################");
      parameters.clear();
      parameters.add("TRUCK1");
      parameters.add("PKG1");      
      parameters.add("LOCATIONSP1");
      Element next2 = nextState("LOADTRUCK", parameters, next1, domain, project);
      System.out.println("##################################################\n");
          
      System.out.println("##################### Step 3 #####################");
      parameters.clear();
      parameters.add("AIRPLANE2");
      parameters.add("AIRPORTRJ1");      
      parameters.add("AIRPORTSP1");
      //parameters.add("TABLE1");
      Element next3 = nextState("FLY", parameters, next2, domain, project);
      System.out.println("##################################################\n");
          
      System.out.println("##################### Step 4 #####################");
      parameters.clear();
      parameters.add("TRUCK2");
      parameters.add("LOCATIONRJ1");      
      parameters.add("AIRPORTRJ1");
      parameters.add("RIODEJANEIRO");
      Element next4 = nextState("DRIVE", parameters, next3, domain, project);
      System.out.println("##################################################\n");
          
      System.out.println("##################### Step 5 #####################");
      parameters.clear();
      parameters.add("TRUCK2");      
      parameters.add("PKG2");
      parameters.add("AIRPORTRJ1");
      Element next5 = nextState("UNLOADTRUCK", parameters, next4, domain, project);
      System.out.println("##################################################\n");
          
      System.out.println("##################### Step 6 #####################");
      parameters.clear();
      parameters.add("TRUCK2");
      parameters.add("PKG3");      
      parameters.add("AIRPORTRJ1");
      //parameters.add("TABLE1");
      Element next6 = nextState("UNLOADTRUCK", parameters, next5, domain, project);
      System.out.println("##################################################\n");
          
      System.out.println("##################### Step 7 #####################");
      parameters.clear();      
      parameters.add("TRUCK1");      
      parameters.add("LOCATIONSP1");
      parameters.add("AIRPORTSP1");
      parameters.add("SAOPAULO");
      Element next7 = nextState("DRIVE", parameters, next6, domain, project);
      System.out.println("##################################################\n");
          
      System.out.println("##################### Step 8 #####################");
      parameters.clear();
      parameters.add("TRUCK1");
      parameters.add("PKG1");      
      parameters.add("AIRPORTSP1");
      //parameters.add("TABLE1");
      Element next8 = nextState("UNLOADTRUCK", parameters, next7, domain, project);
      System.out.println("##################################################\n");
          
      System.out.println("##################### Step 9 #####################");
      parameters.clear();
      parameters.add("AIRPLANE2");
      parameters.add("PKG1");      
      parameters.add("AIRPORTSP1");
      //parameters.add("TABLE1");
      Element next9 = nextState("LOADAIRPLANE", parameters, next8, domain, project);
      System.out.println("##################################################\n");
          
      System.out.println("##################### Step 10 #####################");
      parameters.clear();
      parameters.add("AIRPLANE2");
      parameters.add("PKG1");      
      parameters.add("AIRPORTSP1");
      //parameters.add("TABLE1");
      nextState("UNLOADAIRPLANE", parameters, next9, domain, project);
      System.out.println("##################################################\n");
    }*/
}