package myuml;

import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import java.awt.Component;
import java.io.*;
import com.borland.jbcl.layout.XYConstraints;
import javax.swing.JTextField;
import java.util.ArrayList;
import traduccion.TraduccionMarco;
import de.fzi.XPath.*;
import de.fzi.XPath.Parser.*;
import javax.swing.ButtonGroup;
import javax.swing.JRadioButton;
import java.awt.Color;
import java.awt.PopupMenu;
import java.awt.MenuItem;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import traduccion.VariablesClase;
import traduccion.VarUpdateClase;
import java.awt.Frame;
import java.util.StringTokenizer;
import org.dom4j.Element;
import java.awt.event.KeyEvent;

/**
 * <p>Title: Generación de Coreografías de Servicios Web</p>
 *
 * <p>Description: Clase que gestiona los eventos del ratón </p>
 *
 * <p>Copyright: Copyright (c) 2007</p>
 *
 * <p>Company: UCLM</p>
 *
 * @version 1.0
 */
public class MyListener implements MouseListener, MouseMotionListener, Serializable, ActionListener {
    private int startx, starty;
    private MyObjects obj;
    private MyObjects objeto;
    String ident;
    JPanel panel;


    /**
     * Constructor que crea un controlador para los eventos del ratón.
     */
    public MyListener() {
    }


    /**
     * Método que se invoca cuando el ratón sale del componente
     *
     * @param e controla eventos del ratón
     */
    public void mouseExited(MouseEvent e) {
        //System.out.println("Exit");
    }


    /**
     * Método que se invoca cuando el ratón entra sobre el componente
     *
     * @param e controla eventos del ratón
     */
    public void mouseEntered(MouseEvent e) {
        //System.out.println("Enter");
    }


    /**
     * Método que se invoca cuando se deja de presionar el ratón
     * Actualiza la posición del componente
     *
     * @param e controla eventos del ratón
     */
    public void mouseReleased(MouseEvent e) {
        //((MyObjects) e.getComponent()).updatePosition();
    }


    /**
     * Método que se invoca cuando se presiona con el ratón un componente,
     * almacena las coordenadas y el tipo de componente que se ha presionado
     *
     * @param e controla eventos del ratón
     */
    public void mousePressed(MouseEvent e) {
        startx = e.getX();
        starty = e.getY();
        obj = (MyObjects) e.getComponent();

    }


    /**
     * Método que se invoca cuando se clica con el botón del ratón en algún
     * componente.
     * Dependiendo del estado en el que estemos, se enviará o se recibirá
     * un mensaje
     *
     * @param e controla eventos del ratón
     */
    public void mouseClicked(MouseEvent e) {

        //Si hacemos doble click sobre el elemento se le asignará un nombre
        if (e.getClickCount() == 2) {

            //Dejar limpia la tabla de propiedades
            ((TraduccionMarco)(((JPanel)(e.getComponent().getParent())).getRootPane().getParent())).limpiarPropiedades();

            objeto = (MyObjects) e.getComponent();
            JPanel jPanelDraw = (JPanel) objeto.getParent();

            //Modificar el color del objeto al inicial
            objeto.setCol(Color.orange);

            //Se debe repintar el panel que contiene a los objetos
            jPanelDraw.repaint();
            jPanelDraw.updateUI();


            //Si el estado se ha quedado como WAITSOURCE no se ha
            //completado el mensaje y hay que eliminarlo de la lista de componentes
            if (Shared.state.compareTo(Shared.state.WAITSOURCE) == 0) {

                jPanelDraw.remove(0);

            }

            //Si el estado es WAITPOSITION
            if (Shared.state.compareTo(Shared.state.WAITPOSITION) == 0) {

                //Ver la posicion del ultimo frame que se haya añadido a la lista
                int posicion = 0;
                Component[] lista = jPanelDraw.getComponents();

                for (int i = 0; i < lista.length; i++) {

                    //Si se trata de un frame
                    if ((lista[i] instanceof MyFrame)) {

                        posicion = i;
                        break;

                    }

                }

                jPanelDraw.remove(posicion);

                //Devolver el estado al valor por defecto
                Shared.state = Shared.state.DEFAULT;

            }



            //En caso de que el estado sea WAITDEST también se debe eliminar de la lista de mensajes enviados
            //del objeto que corresponda

            if (Shared.state.compareTo(Shared.state.WAITDEST) == 0) {

                //Recoger el mensaje que se va a borrar
                MyMessage mensaje = (MyMessage) jPanelDraw.getComponent(0);

                //Borrar el mensaje de la lista de componentes
                jPanelDraw.remove(0);

                //Buscar el componente que lo envíe y borrarlo de su lista
                Component[] lista = jPanelDraw.getComponents();

                for (int i = 0; i < lista.length; i++) {

                    if (lista[i] instanceof MyActor ||
                        lista[i] instanceof MyLifeLine) {

                        ((MyObjects) lista[i]).deleteSendMessage(mensaje);

                    }

                }

            }

            //Dejar el estado como default
            Shared.state = Shared.State.DEFAULT;


            //Si no se trata de un frame
            if (!(objeto instanceof MyFrame)){

                JOptionPane optionPane= new JOptionPane();
                //JTextField nombre = new FixedLengthTextField(((MyObjects)objeto).getName(),15);
                JTextField nombre = new JTextField(((MyObjects)objeto).getName());
                String name;

                Object[] camposArray = {"Name:", nombre};

                Object[] options = {"Ok", "Cancel"};
                int ret = optionPane.showOptionDialog(optionPane, camposArray,
                                                      "Component name",
                                                      optionPane.YES_NO_OPTION,
                                                      optionPane.QUESTION_MESSAGE, null,
                                                      options, null);


                //String name = (String)JOptionPane.showInputDialog(null,"Name: ", "Component name",JOptionPane.QUESTION_MESSAGE);

                if (ret==JOptionPane.YES_OPTION){

                    name = nombre.getText();

                    //Si tiene nombre asignado
                    if (name != null && name.compareTo("") != 0) {

                        boolean valid = false;

                        try {

                            //Ver que name es una variable XPath válida
                            XPathParser par = new XPathParser(new StringReader(name));

                            String var = par.QName();

                            //Si var y left tienen el mismo tamaño se toma como válido
                            if (var.length() == name.length()) {

                                valid = true;

                            }

                            //Capturar error o excepción, señal de que la expresión no es válida
                        } catch (Throwable ex) {

                            System.out.println(ex);

                        }

                        //Provisional para dejar cualquier expresión de guarda como válida
                        //valid = true;

                        if (valid) {

                            //Se debe comprobar que no exista otro objeto que no sea
                            //el mismo con el mismo nombre

                            Component[] lista = jPanelDraw.getComponents();
                            boolean existe = false;

                            for (int i = 0; i < lista.length; i++) {

                                //Si se trata de un componente con nombre se debe mirar que no coincida con el nuevo nombre
                                if ((lista[i] instanceof MyLifeLine ||
                                     lista[i] instanceof MyActor ||
                                     lista[i] instanceof MyMessage)
                                    && lista[i] != objeto
                                    && name.compareTo(lista[i].getName()) == 0) {

                                    existe = true;
                                    break;

                                }

                            }

                            //Provisionalmente se deja que puedan tener varios el mismo nombre
                            //existe=false;

                            if (!existe) {

                                objeto.setName(name);
                                e.getComponent().repaint();

                            } else {

                                //Mostrar mensaje de que no es válida la expresion
                                JOptionPane optionPane2 = new JOptionPane();
                                Object[] options2 = {"Ok"};
                                optionPane2.showOptionDialog(optionPane2,
                                                             "Component name already exists",
                                                             "Message",
                                                             optionPane2.YES_NO_OPTION,
                                                             optionPane2.ERROR_MESSAGE, null,
                                                             options2, null);

                            }

                        } else {

                            //Mostrar mensaje de que no es válida la expresion
                            JOptionPane optionPane2 = new JOptionPane();
                            Object[] options2 = {"Ok"};
                            optionPane2.showOptionDialog(optionPane2,
                                                         "Invalid component name",
                                                         "Message", optionPane2.YES_NO_OPTION,
                                                         optionPane2.ERROR_MESSAGE, null,
                                                         options2, null);

                        }
                    }
                }
            }

            //Si se trata de un frame
            if (objeto instanceof MyFrame){

                //Ver el tipo de frame
                if(objeto.getName().compareTo("opt")==0){

                    JOptionPane optionPane= new JOptionPane();
                    //JTextField guarda = new FixedLengthTextField(((MyFrame)objeto).getGuard(),15);
                    JTextField guarda = new JTextField(((MyFrame)objeto).getGuard());

                    //También debe poder seleccionarse si se quiere que sea bloqueante (Por defecto a false)
                    //Se debe llamar a un diálogo que permita seleccionar el tipo de frame
                    ButtonGroup buttonGroup = new ButtonGroup();
                    JRadioButton radioButton1 = new JRadioButton("True");
                    JRadioButton radioButton2 = new JRadioButton("False");

                    //Ver en que estado se encuentra actualmente el block del frame
                    if(((MyFrame)objeto).getBlock()){
                        radioButton1.setSelected(true);
                    }
                    else{
                        radioButton2.setSelected(true);
                    }

                    String type = "Block:";
                    Object[] camposArray = {"Guard:", guarda, type, radioButton1, radioButton2};

                    buttonGroup.add(radioButton1);
                    buttonGroup.add(radioButton2);


                    Object[] options = {"Ok", "Cancel"};
                    int ret = optionPane.showOptionDialog(optionPane, camposArray,
                                                          "Frame guard",
                                                          optionPane.YES_NO_OPTION,
                                                          optionPane.QUESTION_MESSAGE, null,
                                                          options, null);

                    //String guard = (String)JOptionPane.showInputDialog(null,"Guard: ", "Frame guard",JOptionPane.QUESTION_MESSAGE,null,null,((MyFrame)objeto).getGuard());

                    if (ret==JOptionPane.YES_OPTION){

                        //Fijar el valor del bloqueo
                        if(radioButton1.isSelected()){

                            ((MyFrame)objeto).setBlock(true);

                        }

                        if(radioButton2.isSelected()){

                            ((MyFrame)objeto).setBlock(false);

                        }

                        //Si tiene nombre asignado
                        if (guarda.getText() != null && guarda.getText().compareTo("") != 0) {

                            String guarda_text = guarda.getText().replaceAll("==","=");

                            //Llamar a la función que se encarga de parsear las guardas
                            boolean valid;
                            String var_guarda = parseoGuarda(guarda_text,false);

                            if(var_guarda!=null) valid = true;
                            else valid = false;

                            if(valid){
                                //Modificar la guarda para que = sea ==
                                guarda_text = cambiarIguales(guarda_text);
                                ((MyFrame) objeto).setGuard(guarda_text);
                                e.getComponent().repaint();

                                //Almacenar las variables que contiene actualmente la guarda
                                ArrayList vars_guarda = new ArrayList();

                                StringTokenizer st = new StringTokenizer(var_guarda);

                                while (st.hasMoreTokens()) {

                                    String var_act = st.nextToken();

                                    //Ver que la variable no forme ya parte del array de variables
                                    boolean esta = false;

                                    for(int i = 0; i < vars_guarda.size();i++){

                                        if(vars_guarda.get(i).toString().compareTo(var_act)==0){

                                            esta = true;
                                            break;

                                        }

                                    }

                                    if(!esta) vars_guarda.add(var_act);

                                }

                                //Actualizar el ArrayList con las variables de la guarda
                                ((MyFrame) objeto).setVariablesGuarda(vars_guarda);

                            }

                            else{

                                //Mostrar mensaje de que no es válida la expresion
                                JOptionPane optionPane2= new JOptionPane();
                                Object[] options2 = {"Ok"};
                                optionPane2.showOptionDialog(optionPane2,
                                            "Invalid guard expresion",
                                            "Message", optionPane2.YES_NO_OPTION,
                                            optionPane2.ERROR_MESSAGE, null,
                                            options2, null);

                            }
                        }

                    }
                }

                if(objeto.getName().compareTo("loop")==0){

                    //Debe tener un par de entradas, para la guarda y para la repetición
                    JOptionPane optionPane= new JOptionPane();
                    //JTextField guarda = new FixedLengthTextField(((MyFrame)objeto).getGuard(),15);
                    JTextField guarda = new JTextField(((MyFrame)objeto).getGuard());
                    //JTextField repeticion = new FixedLengthTextField(((MyFrame)objeto).getRepeat(),14);
                    JTextField repeticion = new JTextField(((MyFrame)objeto).getRepeat());

                    //También debe poder seleccionarse si se quiere que sea bloqueante (Por defecto a false)
                    //Se debe llamar a un diálogo que permita seleccionar el tipo de frame
                    ButtonGroup buttonGroup = new ButtonGroup();
                    JRadioButton radioButton1 = new JRadioButton("True");
                    JRadioButton radioButton2 = new JRadioButton("False");

                    //Ver en que estado se encuentra actualmente el block del frame
                    if(((MyFrame)objeto).getBlock()){
                        radioButton1.setSelected(true);
                    }
                    else{
                        radioButton2.setSelected(true);
                    }

                    String type = "Block:";
                    Object[] campos_radioButtonArray = {"Repeat:", repeticion, "Guard (optional):", guarda,type, radioButton1, radioButton2};

                    buttonGroup.add(radioButton1);
                    buttonGroup.add(radioButton2);



                    Object[] options = {"Ok","Cancel"};

                    int ret = optionPane.showOptionDialog(optionPane, campos_radioButtonArray,
                                                          "Frame guard and repeat",
                                                          optionPane.YES_NO_OPTION,
                                                          optionPane.QUESTION_MESSAGE, null,
                                                          options, null);

                    if (ret==JOptionPane.YES_OPTION){

                        //Fijar el valor del bloqueo
                        if(radioButton1.isSelected()){

                            ((MyFrame)objeto).setBlock(true);

                        }

                        if(radioButton2.isSelected()){

                            ((MyFrame)objeto).setBlock(false);

                        }

                        //Fijar los nuevos valores de las guardas a lo que se haya escrito
                        boolean valid = false;

                        String expresion_repeat = repeticion.getText().replaceAll("==","=");
                        String expresion = guarda.getText().replaceAll("==","=");

                        //Si tiene nombre asignado
                        if (expresion_repeat!= null && expresion_repeat.compareTo("") != 0) {
                            //Llamar a la función que se encarga de parsear las guardas
                            //para la condición de repetición
                            String var_repeat = parseoGuarda(expresion_repeat, false);

                            if (var_repeat != null)
                                valid = true;
                            else
                                valid = false;

                            //Provisional para dejar cualquier expresión de guarda como válida
                            //valid = true;

                            if (valid) {
                                //Modificar la guarda para que = sea ==
                                expresion_repeat = cambiarIguales(expresion_repeat);
                                ((MyFrame) objeto).setRepeat(expresion_repeat);
                                e.getComponent().repaint();

                                //Almacenar las variables que contiene actualmente la guarda
                                ArrayList vars_repeat = new ArrayList();

                                StringTokenizer st = new StringTokenizer(var_repeat);

                                while (st.hasMoreTokens()) {

                                    String var_act = st.nextToken();

                                    //Ver que la variable no forme ya parte del array de variables
                                    boolean esta = false;

                                    for (int i = 0; i < vars_repeat.size(); i++) {

                                        if (vars_repeat.get(i).toString().compareTo(var_act) == 0) {

                                            esta = true;
                                            break;

                                        }

                                    }

                                    if (!esta)
                                        vars_repeat.add(var_act);

                                }

                                //Actualizar el ArrayList con las variables de la guarda
                                ((MyFrame) objeto).setVariablesRepeat(vars_repeat);

                            } else {

                                //Mostrar mensaje de que no es válida la expresion
                                JOptionPane optionPane2 = new JOptionPane();
                                Object[] options2 = {"Ok"};
                                optionPane2.showOptionDialog(optionPane2,
                                                             "Invalid repeat expresion",
                                                             "Message", optionPane2.YES_NO_OPTION,
                                                             optionPane2.ERROR_MESSAGE, null,
                                                             options2, null);

                            }
                        }

                        //Hacer las mismas comprobaciones para guard si no es vacío
                        if (guarda.getText().compareTo("") != 0) {

                            //Llamar a la función que se encarga de parsear las guardas
                            String var_guarda = parseoGuarda(expresion,false);

                            if (var_guarda!=null) valid = true;
                            else valid = false;

                            //Provisional para dejar cualquier expresión de guarda como válida
                            //valid = true;

                            if (valid) {
                                //Modificar la guarda para que = sea ==
                                expresion = cambiarIguales(expresion);
                                ((MyFrame) objeto).setGuard(expresion);
                                e.getComponent().repaint();

                                //Almacenar las variables que contiene actualmente la guarda
                                ArrayList vars_guarda = new ArrayList();

                                StringTokenizer st = new StringTokenizer(var_guarda);

                                while (st.hasMoreTokens()) {

                                    String var_act = st.nextToken();

                                    //Ver que la variable no forme ya parte del array de variables
                                    boolean esta = false;

                                    for(int i = 0; i < vars_guarda.size();i++){

                                        if(vars_guarda.get(i).toString().compareTo(var_act)==0){

                                            esta = true;
                                            break;

                                        }

                                    }

                                    if(!esta) vars_guarda.add(var_act);

                                }

                                //Actualizar el ArrayList con las variables de la guarda
                                ((MyFrame) objeto).setVariablesGuarda(vars_guarda);


                            } else {

                                //Mostrar mensaje de que no es válida la expresion
                                JOptionPane optionPane2 = new JOptionPane();
                                Object[] options2 = {"Ok"};
                                optionPane2.showOptionDialog(optionPane2,
                                                             "Invalid guard expresion",
                                                             "Message", optionPane2.YES_NO_OPTION,
                                                             optionPane2.ERROR_MESSAGE, null,
                                                             options2, null);

                            }

                        }

                    }

                }

                if(objeto.getName().compareTo("alt_else")==0){

                    JOptionPane optionPane= new JOptionPane();
                    //JTextField guarda = new FixedLengthTextField(((MyFrame)objeto).getGuard(),15);
                    JTextField guarda = new JTextField(((MyFrame)objeto).getGuard());

                    Object[] camposArray = {"Guard:", guarda};

                    Object[] options = {"Ok", "Cancel"};
                    int ret = optionPane.showOptionDialog(optionPane, camposArray,
                                                          "Frame guard",
                                                          optionPane.YES_NO_OPTION,
                                                          optionPane.QUESTION_MESSAGE, null,
                                                          options, null);


                    //String guard = (String)JOptionPane.showInputDialog(null,"Guard: ", "Frame guard",JOptionPane.QUESTION_MESSAGE,null,null,((MyFrame)objeto).getGuard());

                    if (ret==JOptionPane.YES_OPTION){

                        //Si tiene nombre asignado
                        if (guarda.getText() != null && guarda.getText().compareTo("") != 0) {

                            String guarda_text = guarda.getText().replaceAll("==","=");

                            //Llamar a la función que se encarga de parsear las guardas
                            boolean valid;
                            String var_guarda = parseoGuarda(guarda_text,false);

                            if(var_guarda!=null) valid = true;
                            else valid = false;

                            //Provisional para dejar cualquier expresión de guarda como válida
                            //valid = true;

                            if(valid){
                                //Modificar la guarda para que = sea ==
                                guarda_text = cambiarIguales(guarda_text);
                                ((MyFrame) objeto).setGuard(guarda_text);
                                e.getComponent().repaint();

                                //Ver como sería la negación de la guarda para dejarla también almacenada
                                String guarda_negada = guardaNegada(guarda_text).replaceAll("\\.0","");
                                ((MyFrame) objeto).setGuard_negada(cambiarIguales(guarda_negada));

                                //Almacenar las variables que contiene actualmente la guarda
                                ArrayList vars_guarda = new ArrayList();

                                StringTokenizer st = new StringTokenizer(var_guarda);

                                while (st.hasMoreTokens()) {

                                    String var_act = st.nextToken();

                                    //Ver que la variable no forme ya parte del array de variables
                                    boolean esta = false;

                                    for(int i = 0; i < vars_guarda.size();i++){

                                        if(vars_guarda.get(i).toString().compareTo(var_act)==0){

                                            esta = true;
                                            break;

                                        }

                                    }

                                    if(!esta) vars_guarda.add(var_act);

                                }

                                //Actualizar el ArrayList con las variables de la guarda
                                ((MyFrame) objeto).setVariablesGuarda(vars_guarda);


                            }
                            else{

                                //Mostrar mensaje de que no es válida la expresion
                                JOptionPane optionPane2= new JOptionPane();
                                Object[] options2 = {"Ok"};
                                optionPane2.showOptionDialog(optionPane2,
                                            "Invalid guard expresion",
                                            "Message", optionPane2.YES_NO_OPTION,
                                            optionPane2.ERROR_MESSAGE, null,
                                            options2, null);

                            }
                        }

                    }

                }

                if(objeto.getName().compareTo("Exception")==0){

                    JOptionPane optionPane= new JOptionPane();
                    JTextField exception_name_field = new JTextField(((MyFrame)objeto).getException_name());
                    JTextField exception_field = new JTextField(((MyFrame)objeto).getException());

                    Object[] camposArray = {"Name:",exception_name_field,"Exception:", exception_field};

                    Object[] options = {"Ok", "Cancel"};
                    int ret = optionPane.showOptionDialog(optionPane, camposArray,
                                                          "Frame exception",
                                                          optionPane.YES_NO_OPTION,
                                                          optionPane.QUESTION_MESSAGE, null,
                                                          options, null);

                    if (ret==JOptionPane.YES_OPTION){

                        //Si tiene nombre asignado
                        if (exception_name_field.getText() != null && exception_name_field.getText().compareTo("") != 0) {

                            //Almacenar el nombre
                            ((MyFrame) objeto).setException_name(exception_name_field.getText());
                        }

                        //Si tiene excepción asignada
                        if (exception_field.getText() != null && exception_field.getText().compareTo("") != 0) {

                            //Llamar a la función que se encargue de ver que sea válido
                            boolean valid = true;
                            valid = parseoException(exception_field.getText());

                            if (valid) {

                                //Almacenar la excepción
                                ((MyFrame) objeto).setException (exception_field.getText());

                            }

                            else {

                                  //Ver si se corresponde con el timeout asociado a algún mensaje
                                  Component[] lista = jPanelDraw.getComponents();

                                  for (int i = 0; i < lista.length; i++) {

                                      if (lista[i] instanceof MyMessage) {

                                          String timeout = ((MyMessage)lista[i]).getTimeout();
                                          String timeout_clock = ((MyMessage)lista[i]).getTimeout_clock();

                                          timeout = timeout_clock + "<=" + timeout;

                                          if (timeout.compareTo(exception_field.getText().replaceAll(" ",""))==0){

                                              valid = true;

                                              //Modificar la excepción
                                              ((MyFrame) objeto).setException(exception_field.getText().replaceAll(" ",""));
                                              ((MyFrame) objeto).repaint();

                                              break;

                                          }

                                      }
                                  }

                                  if(!valid){
                                      //Mostrar mensaje de que no es válido
                                      JOptionPane optionPane2 = new JOptionPane();
                                      Object[] options2 = {"Ok"};
                                      optionPane2.showOptionDialog(optionPane2,
                                                                   "Invalid exception",
                                                                   "Message", optionPane2.YES_NO_OPTION,
                                                                   optionPane2.ERROR_MESSAGE, null,
                                                                   options2, null);
                                  }
                            }

                        }

                    }
                }

            }

            //Modificar el color del objeto al inicial
            objeto.setCol(Color.black);

            //Se debe repintar el panel que contiene a los objetos
            jPanelDraw.repaint();
            jPanelDraw.updateUI();


        }

        //Pulsamos el boton derecho para borrar un componente
        else if(e.getButton()==3){

            //Dejar marcado que el objeto actual se queda como null
            ((TraduccionMarco)(((JPanel)(e.getComponent().getParent())).getRootPane().getParent())).setActual(null);

            //Dejar limpia la tabla de propiedades
            ((TraduccionMarco)(((JPanel)(e.getComponent().getParent())).getRootPane().getParent())).limpiarPropiedades();

            objeto = (MyObjects) e.getComponent();
            ident = objeto.getID();
            JPanel panel_aux = panel;
            panel = (JPanel) objeto.getParent();


            //Si se trata de un lifeline o de un actor

            if(objeto instanceof MyLifeLine || objeto instanceof MyActor){
                //Menú de pop-up para elegir la opción deseada
                PopupMenu pu = new PopupMenu();

                MenuItem mi1 = new MenuItem("Delete");
                mi1.addActionListener(this);

                MenuItem mi2 = new MenuItem("Variables");
                mi2.addActionListener(this);

                pu.add(mi1);
                pu.add(mi2);

                e.getComponent().add(pu);

                pu.show(e.getComponent(), e.getX(), e.getY());
            }

            //Si se trata de un mensaje
            else if(objeto instanceof MyMessage){

                //Menú de pop-up para elegir la opción deseada
                PopupMenu pu = new PopupMenu();

                MenuItem mi1 = new MenuItem("Delete");
                mi1.addActionListener(this);

                MenuItem mi2 = new MenuItem("Update variables");
                mi2.addActionListener(this);

                MenuItem mi3 = new MenuItem("Exchange variables");
                mi3.addActionListener(this);

                MenuItem mi4 = new MenuItem("Time to complete");
                mi4.addActionListener(this);

                MenuItem mi5 = new MenuItem("Cause exception");
                mi5.addActionListener(this);

                pu.add(mi1);
                pu.add(mi2);
                pu.add(mi3);
                pu.add(mi4);
                pu.add(mi5);

                e.getComponent().add(pu);

                pu.show(e.getComponent(), e.getX(), e.getY());

            }

            else{

                //Modificar el color del objeto
                objeto.setCol(Color.red);

                //Si se trata de un objeto de tipo frame colorear también los elementos interiores para notar que se van a eliminar
                if (objeto instanceof MyFrame) {

                    MyFrame frm = (MyFrame) objeto;

                    for (int i = 0; i < frm.includeMsg.size(); i++) {

                        ((MyObjects) frm.includeMsg.get(i)).setCol(new Color(
                                200, 0, 0));

                    }

                    for (int i = 0; i < frm.includeFrm.size(); i++) {

                        ((MyObjects) frm.includeFrm.get(i)).setCol(new Color(
                                200, 0, 0));

                    }

                }

                //Se debe repintar el panel que contiene a los objetos
                panel.repaint();
                panel.updateUI();

                //Si el estado se ha quedado como WAITSOURCE no se ha
                //completado el mensaje y hay que eliminarlo de la lista de componentes
                if (Shared.state.compareTo(Shared.state.WAITSOURCE) == 0) {

                    panel.remove(0);

                }

                //Si el estado es WAITPOSITION
                if (Shared.state.compareTo(Shared.state.WAITPOSITION) == 0) {

                    //Ver la posicion del ultimo frame que se haya añadido a la lista
                    int posicion = 0;
                    Component[] lista = panel.getComponents();

                    for (int i = 0; i < lista.length; i++) {

                        //Si se trata de un frame
                        if ((lista[i] instanceof MyFrame)) {

                            posicion = i;
                            break;

                        }

                    }

                    panel.remove(posicion);

                    //Devolver el estado al valor por defecto
                    Shared.state = Shared.state.DEFAULT;

                }

                //En caso de que el estado sea WAITDEST también se debe eliminar de la lista de mensajes enviados
                //del objeto que corresponda

                if (Shared.state.compareTo(Shared.state.WAITDEST) == 0) {

                    //Recoger el mensaje que se va a borrar
                    MyMessage mensaje = (MyMessage) panel.getComponent(0);

                    //Borrar el mensaje de la lista de componentes
                    panel.remove(0);

                    //Buscar el componente que lo envíe y borrarlo de su lista
                    Component[] lista = panel.getComponents();

                    for (int i = 0; i < lista.length; i++) {

                        if (lista[i] instanceof MyActor ||
                            lista[i] instanceof MyLifeLine) {

                            ((MyObjects) lista[i]).deleteSendMessage(mensaje);

                        }

                    }

                }

                //Dejar el estado como default
                Shared.state = Shared.State.DEFAULT;

                JOptionPane optionPane = new JOptionPane();

                Object[] options = {"Yes", "No", "Cancel"};

                int ret = optionPane.showOptionDialog(optionPane,
                        "Do you want to delete the selected component?",
                        "Delete", optionPane.YES_NO_CANCEL_OPTION,
                        optionPane.QUESTION_MESSAGE, null, options, null);
                if (ret == JOptionPane.YES_OPTION) {

                    panel.remove(objeto);
                    objeto.repaint();

                    Component lista[] = panel.getComponents();
                    int n_mensajes = objeto.includeMsg.size();
                    int n_frames = objeto.includeFrm.size();
                    int n_frames_else = 0;

                    //Ver cuantos frames incluidos son alt_else
                    for (int j = 0; j < n_frames; j++) {

                        if (((MyFrame) objeto.includeFrm.get(j)).getName().
                            compareTo("alt_else") == 0) {

                            n_frames_else++;

                        }

                    }

                    n_frames = n_frames - n_frames_else;

                    for (int j = 0; j < lista.length; j++) {

                        //Se deben subir hacia arriba los mensajes posteriores
                        if (lista[j] instanceof MyMessage &&
                            ((MyMessage) lista[j]).getY() >= objeto.getY()) {

                            //Si el mensaje está incluido en su lista se tiene que borrar

                            if ((objeto.getY() + objeto.getHeight()) >
                                ((MyMessage) lista[j]).getY()) {

                                objeto.deleteIncludeMessage((MyMessage)
                                        lista[j]);
                                panel.remove(lista[j]);

                                //Se deben borrar de la lista de otros frames que lo contengan
                                for (int k = 0; k < lista.length; k++) {

                                    if (lista[k] instanceof MyFrame) {

                                        ((MyFrame) lista[k]).includeMsg.
                                                remove(lista[j]);

                                    }

                                }

                            }

                            else {

                                XYConstraints c = ((MyMessage) lista[j]).
                                        getXY();

                                //Coordenada y en la que se va a dibujar el mensaje
                                if (objeto.getName().compareTo("alt_else") !=
                                    0)
                                    c.setY(c.getY() -
                                           (60 + n_mensajes * 30 +
                                            n_frames * 60 +
                                            n_frames_else * 90));
                                else
                                    c.setY(c.getY() -
                                           (90 + n_mensajes * 30 +
                                            n_frames * 60 +
                                            n_frames_else * 90));

                                ((MyMessage) lista[j]).editXYconstraints(c);

                            }

                        }

                        //También se deben subir hacia arriba los frames posteriores
                        if (lista[j] instanceof MyFrame &&
                            ((MyFrame) lista[j]).getY() > objeto.getY() &&
                            ((MyFrame) lista[j]).getY() +
                            ((MyFrame) lista[j]).getHeight() >
                            objeto.getY() + objeto.getHeight()) {

                            XYConstraints c = ((MyFrame) lista[j]).getXY();

                            //Coordenada y en la que se va a dibujar el frame
                            if (objeto.getName().compareTo("alt_else") != 0)
                                c.setY(c.getY() -
                                       (60 + n_mensajes * 30 +
                                        n_frames * 60 + n_frames_else * 90));
                            else
                                c.setY(c.getY() -
                                       (90 + n_mensajes * 30 +
                                        n_frames * 60 + n_frames_else * 90));

                            ((MyFrame) lista[j]).editXYconstraints(c);

                        }

                        //Se deben borrar los frames incluidos en el frame actual
                        if (lista[j] instanceof MyFrame &&
                            objeto.includeFrm.contains(lista[j])) {

                            panel.remove(lista[j]);

                            //Se deben borrar de la lista de otros frames que lo contengan
                            for (int k = 0; k < lista.length; k++) {

                                if (lista[k] instanceof MyFrame) {

                                    ((MyFrame) lista[k]).includeFrm.remove(
                                            lista[j]);

                                }

                            }

                        }

                        //Se debe recortar el tamaño de los frames que contengan al que se ha borrado

                        if (lista[j] instanceof MyFrame &&
                            ((MyFrame) lista[j]).includeFrm.contains(objeto)) {

                            //Se debe recortar 60 por cada frame incluido el actual y 30 por cada mensaje
                            XYConstraints c = ((MyFrame) lista[j]).getXY();

                            if (objeto.getName().compareTo("alt_else") != 0)
                                c.setHeight(c.getHeight() -
                                            (60 + n_mensajes * 30 +
                                             n_frames * 60 +
                                             n_frames_else * 90));
                            else
                                c.setHeight(c.getHeight() -
                                            (90 + n_mensajes * 30 +
                                             n_frames * 60 +
                                             n_frames_else * 90));

                            ((MyFrame) lista[j]).editXYconstraints(c);

                            //Se debe eliminar el frame de su lista
                            ((MyFrame) lista[j]).includeFrm.remove(objeto);

                            //Subir hacia arriba separadores en caso de tipo "par" o "alt"
                            if (((MyFrame) lista[j]).getName().compareTo(
                                    "par") == 0 ||
                                ((MyFrame) lista[j]).
                                getName().compareTo("alt") == 0) {

                                ArrayList separadores = ((MyFrame) lista[j]).
                                        separadores;

                                for (int k = 0; k < separadores.size(); k++) {

                                    if (((Integer) separadores.get(k)).
                                        intValue() + lista[j].getY() >
                                        objeto.getY()) {

                                        int valor = ((Integer) separadores.
                                                get(k)).intValue();

                                        separadores.remove(k);
                                        if (objeto.getName().compareTo(
                                                "alt_else") != 0)
                                            separadores.add(k,
                                                    new Integer(valor -
                                                    (60 + n_mensajes * 30 +
                                                    n_frames * 60 +
                                                    n_frames_else * 90)));
                                        else
                                            separadores.add(k,
                                                    new Integer(valor -
                                                    (90 + n_mensajes * 30 +
                                                    n_frames * 60 +
                                                    n_frames_else * 90)));

                                    }

                                }

                                //Se deben eliminar aquellos separadores que ya no sean necesarios
                                for (int k = 0; k < separadores.size(); k++) {

                                    //Si el valor es igual a 28 es que ya no queda ningún mensaje por encima
                                    if (((Integer) separadores.get(k)).
                                        intValue() == 28) {

                                        separadores.remove(k);

                                    }

                                    else {

                                        //Si es igual al siguiente
                                        if (k < separadores.size() - 1 &&
                                            ((Integer) separadores.get(k)).
                                            intValue() ==
                                            ((Integer)
                                             separadores.get(k + 1)).
                                            intValue()) {

                                            separadores.remove(k);

                                        }

                                    }
                                }

                            }

                            //Subir hacia arriba el separador si procede en el caso "alt_else"
                            if (((MyFrame) lista[j]).getName().compareTo(
                                    "alt_else") == 0) {

                                ArrayList separadores = ((MyFrame) lista[j]).
                                        separadores;

                                if (((Integer) separadores.get(0)).intValue() +
                                    lista[j].getY() > objeto.getY()) {

                                    int valor = ((Integer) separadores.get(
                                            0)).intValue();

                                    separadores.remove(0);
                                    if (objeto.getName().compareTo(
                                            "alt_else") != 0)
                                        separadores.add(0,
                                                new Integer(valor -
                                                (60 + n_mensajes * 30 +
                                                n_frames * 60 +
                                                n_frames_else * 90)));
                                    else
                                        separadores.add(0,
                                                new Integer(valor -
                                                (90 + n_mensajes * 30 +
                                                n_frames * 60 +
                                                n_frames_else * 90)));

                                }

                            }

                        }

                    }

                    //Se deben recortar las lineas de los actor y los lifelines
                    for (int j = 0; j < lista.length; j++) {

                        if (lista[j] instanceof MyLifeLine) {

                            MyLifeLine lin = ((MyLifeLine) lista[j]);

                            XYConstraints c2 = lin.getXY();

                            if (objeto.getName().compareTo("alt_else") != 0)
                                c2.setHeight(c2.getHeight() -
                                             (60 + n_mensajes * 30 +
                                              n_frames * 60 +
                                              n_frames_else * 90));
                            else
                                c2.setHeight(c2.getHeight() -
                                             (90 + n_mensajes * 30 +
                                              n_frames * 60 +
                                              n_frames_else * 90));

                            lin.editXYconstraints(c2);

                        }

                        if (lista[j] instanceof MyActor) {

                            MyActor lin = ((MyActor) lista[j]);

                            XYConstraints c2 = lin.getXY();

                            if (objeto.getName().compareTo("alt_else") != 0)
                                c2.setHeight(c2.getHeight() -
                                             (60 + n_mensajes * 30 +
                                              n_frames * 60 +
                                              n_frames_else * 90));
                            else
                                c2.setHeight(c2.getHeight() -
                                             (90 + n_mensajes * 30 +
                                              n_frames * 60 +
                                              n_frames_else * 90));

                            lin.editXYconstraints(c2);

                        }

                    }

                }

                //Modificar el color del objeto al inicial
                objeto.setCol(Color.black);

                MyFrame frm = (MyFrame) objeto;

                for (int i = 0; i < frm.includeMsg.size(); i++) {

                    ((MyObjects) frm.includeMsg.get(i)).setCol(Color.black);

                }

                for (int i = 0; i < frm.includeFrm.size(); i++) {

                    ((MyObjects) frm.includeFrm.get(i)).setCol(Color.black);

                }



                //Se debe repintar el panel que contiene a los objetos
                panel.repaint();
                panel.updateUI();


            }

            panel = panel_aux;

        }

        //En caso contrario, cuando hacemos un sólo click sobre el elemento
        //estaremos trabajando con los mensajes o con un frame
        else {
            switch (Shared.state) {
            case WAITSOURCE:

                if(!(e.getComponent() instanceof MyFrame) && !(e.getComponent() instanceof MyMessage)){

                    ((MyObjects) e.getComponent()).addSendMessage(Shared.msg,e.getY());

                    if (Shared.msg.source != null) {
                        Shared.state = Shared.State.WAITDEST;
                        ((TraduccionMarco) (((JPanel) (e.getComponent().
                                getParent())).getRootPane().getParent())).
                                modifyMessage(" Click the second element");
                    } else {
                        Shared.state = Shared.State.DEFAULT;
                        ((TraduccionMarco) (((JPanel) (e.getComponent().
                                getParent())).getRootPane().getParent())).
                                modifyMessage(" Message could not be placed");
                    }
                    break;
                }
            case WAITDEST:

                //Ver que el origen y el destino no coincidan

                if ((MyObjects) e.getComponent() != Shared.msg.source && !(e.getComponent() instanceof MyFrame) && !(e.getComponent() instanceof MyMessage)) {

                    ((MyObjects) e.getComponent()).addReceiveMessage(Shared.msg);

                    Shared.state = Shared.State.DEFAULT;

                    ((TraduccionMarco)(((JPanel)(e.getComponent().getParent())).getRootPane().getParent())).modifyMessage("Message placed");

                }

                break;
            case WAITPOSITION:

                //Llamar al método que lo deje en la posición adecuada
                Shared.frm.addPositionFrame(Shared.frm,e.getY() + e.getComponent().getY());
                Shared.state = Shared.State.DEFAULT;
                if(Shared.frm.colocado)
                    ((TraduccionMarco)(((JPanel)(e.getComponent().getParent())).getRootPane().getParent())).modifyMessage("Frame placed");
                else
                    ((TraduccionMarco)(((JPanel)(e.getComponent().getParent())).getRootPane().getParent())).modifyMessage("Frame could not be placed");
                break;

            //Si no se trata de ninguno de los casos anteriores de estado seleccionar el componente
            default:

                //Dejar marcado que el objeto actual
                ((TraduccionMarco)(((JPanel)(e.getComponent().getParent())).getRootPane().getParent())).setActual((MyObjects) e.getComponent());

                //Dejar el focus actual el frame de la aplicación
                ((TraduccionMarco)(((JPanel)(e.getComponent().getParent())).getRootPane().getParent())).requestFocus();

                objeto = (MyObjects) e.getComponent();
                JPanel jPanelDraw = (JPanel) objeto.getParent();

                //Modificar el color del objeto al inicial
                objeto.setCol(new Color(0, 150, 0));

                //Se debe repintar el panel que contiene a los objetos
                jPanelDraw.repaint();
                jPanelDraw.updateUI();

                //Se deben mostrar sus propiedades en la tabla de propiedades
                if(objeto instanceof MyLifeLine || objeto instanceof MyActor || objeto instanceof MyMessage){

                    Object campos[][] = new Object[1][2];

                    //Fijar el nombre del campo y su valor
                    campos[0][0] = "Name";
                    campos[0][1] = objeto.getName();

                    //Introducir en la tabla de propiedades la fila con el nombre
                    ((TraduccionMarco)(((JPanel)(e.getComponent().getParent())).getRootPane().getParent())).seleccionObjeto(objeto,campos);

                }
                else if(objeto instanceof MyFrame){

                    MyFrame frm = (MyFrame)objeto;

                    //Ver el tipo de frame que se trata
                    if(frm.getName().compareTo("alt_else")==0){

                        Object campos[][] = new Object[1][2];

                        //Fijar el nombre del campo y su valor
                        campos[0][0] = "Guard";
                        campos[0][1] = frm.getGuard();

                        //Introducir en la tabla de propiedades la fila con la guarda
                        ((TraduccionMarco)(((JPanel)(e.getComponent().getParent())).getRootPane().getParent())).seleccionObjeto(objeto,campos);

                    }

                    if(frm.getName().compareTo("Exception")==0){

                        Object campos[][] = new Object[2][2];

                        //Fijar el nombre del campo y su valor
                        campos[0][0] = "Name";
                        campos[0][1] = frm.getException_name();
                        campos[1][0] = "Exception";
                        campos[1][1] = frm.getException();

                        //Introducir en la tabla de propiedades la fila con la excepcion
                        ((TraduccionMarco)(((JPanel)(e.getComponent().getParent())).getRootPane().getParent())).seleccionObjeto(objeto,campos);

                    }


                    if(frm.getName().compareTo("opt")==0){

                        Object campos[][] = new Object[2][2];

                        //Fijar el nombre del campo y su valor
                        campos[0][0] = "Guard";
                        campos[0][1] = frm.getGuard();
                        campos[1][0] = "Block";
                        campos[1][1] = frm.getBlock();

                        //Introducir en la tabla de propiedades la fila con la guarda
                        ((TraduccionMarco)(((JPanel)(e.getComponent().getParent())).getRootPane().getParent())).seleccionObjeto(objeto,campos);

                    }

                    if(frm.getName().compareTo("loop")==0){

                        Object campos[][] = new Object[3][2];

                        //Fijar los nombres de los campos y sus valores
                        campos[0][0] = "Repeat";
                        campos[0][1] = frm.getRepeat();
                        campos[1][0] = "Guard";
                        campos[1][1] = frm.getGuard();
                        campos[2][0] = "Block";
                        campos[2][1] = frm.getBlock();

                        //Introducir en la tabla de propiedades las fila con la guarda y el repeat
                        ((TraduccionMarco)(((JPanel)(e.getComponent().getParent())).getRootPane().getParent())).seleccionObjeto(objeto,campos);

                    }

                }

                break;

            }
        }
    }


    /**
     * Método que se invoca cuando el ratón se mueve por el componente, se
     * pinche o no
     *
     * @param e controla eventos del ratón
     */
    public void mouseMoved(MouseEvent e) {
        //System.out.println("Move");
    }


    /**
     * Método que se invoca cuando se aprieta y arrastra el ratón sobre el
     * componente
     *
     * @param e controla eventos del ratón
     */
    public void mouseDragged(MouseEvent e) {
        //System.out.println("Drag");
        int x = e.getComponent().getLocation().x;
        int y = e.getComponent().getLocation().y;
        if (e.getComponent().getClass() == MyMessage.class) {
            e.getComponent().setLocation(x, y + e.getY() - starty);
        } else {
            e.getComponent().setLocation(x + e.getX() - startx,
                                         y + e.getY() - starty);
            ((MyObjects) e.getComponent()).repaintMessages(e.getX() - startx);
        }
    }

    public void actionPerformed(ActionEvent e) {

        JPanel panel_aux = panel;
        panel = (JPanel) objeto.getParent();

        //Si se ha elegido la opción de borrar
        if (e.getActionCommand().compareTo("Delete") == 0) {

            //Modificar el color del objeto
            objeto.setCol(Color.red);

            //Si se trata de un actor o de un lifeline colorear también los mensajes enviados y recibidos
            if (objeto instanceof MyActor || objeto instanceof MyLifeLine) {

                for (int i = 0; i < objeto.sendedMsg.size(); i++) {

                    ((MyObjects) objeto.sendedMsg.get(i)).setCol(new Color(200, 0,
                            0));

                }

                for (int i = 0; i < objeto.receivedMsg.size(); i++) {

                    ((MyObjects) objeto.receivedMsg.get(i)).setCol(new Color(200, 0,
                            0));

                }

            }

            //Se debe repintar el panel que contiene a los objetos
            panel.repaint();
            panel.updateUI();

            //Si el estado se ha quedado como WAITSOURCE no se ha
            //completado el mensaje y hay que eliminarlo de la lista de componentes
            if (Shared.state.compareTo(Shared.state.WAITSOURCE) == 0) {

                panel.remove(0);

            }

            //Si el estado es WAITPOSITION
            if (Shared.state.compareTo(Shared.state.WAITPOSITION) == 0) {

                //Ver la posicion del ultimo frame que se haya añadido a la lista
                int posicion = 0;
                Component[] lista = panel.getComponents();

                for (int i = 0; i < lista.length; i++) {

                    //Si se trata de un frame
                    if ((lista[i] instanceof MyFrame)) {

                        posicion = i;
                        break;

                    }

                }

                panel.remove(posicion);

                //Devolver el estado al valor por defecto
                Shared.state = Shared.state.DEFAULT;

            }

            //En caso de que el estado sea WAITDEST también se debe eliminar de la lista de mensajes enviados
            //del objeto que corresponda

            if (Shared.state.compareTo(Shared.state.WAITDEST) == 0) {

                //Recoger el mensaje que se va a borrar
                MyMessage mensaje = (MyMessage) panel.getComponent(0);

                //Borrar el mensaje de la lista de componentes
                panel.remove(0);

                //Buscar el componente que lo envíe y borrarlo de su lista
                Component[] lista = panel.getComponents();

                for (int i = 0; i < lista.length; i++) {

                    if (lista[i] instanceof MyActor ||
                        lista[i] instanceof MyLifeLine) {

                        ((MyObjects) lista[i]).deleteSendMessage(mensaje);

                    }

                }

            }

            //Dejar el estado como default
            Shared.state = Shared.State.DEFAULT;

            JOptionPane optionPane = new JOptionPane();

            Object[] options = {"Yes", "No", "Cancel"};

            int ret = optionPane.showOptionDialog(optionPane,
                    "Do you want to delete the selected component?", "Delete",
                                                  optionPane.YES_NO_CANCEL_OPTION,
                                                  optionPane.QUESTION_MESSAGE, null,
                                                  options, null);
            if (ret == JOptionPane.YES_OPTION) {

                //Si se trata de un actor o de un lifeline
                if (objeto instanceof MyActor || objeto instanceof MyLifeLine) {

                    //Se tiene que mirar que no contenga variables que estén en algún frame
                    boolean no_borrar = false;

                    ArrayList variables = objeto.getVariables();

                    Component lista_obj[] = panel.getComponents();

                    //Se deben mirar los objetos que sean frames
                    for (int i = 0; i < lista_obj.length; i++) {

                        if (lista_obj[i] instanceof MyFrame) {

                            ArrayList guarda = ((MyFrame) lista_obj[i]).
                                               getVariablesGuarda();
                            ArrayList repeat = ((MyFrame) lista_obj[i]).
                                               getVariablesRepeat();

                            for (int j = 0; j < guarda.size(); j++) {

                                for (int k = 0; k < variables.size(); k++) {

                                    if (((Object[]) variables.get(k))[0].toString().
                                        compareTo(guarda.get(j).toString()) == 0) {

                                        no_borrar = true;
                                        break;

                                    }

                                }

                                if (no_borrar)
                                    break;

                            }

                            if (!no_borrar) {

                                for (int j = 0; j < repeat.size(); j++) {

                                    for (int k = 0; k < variables.size(); k++) {

                                        if (((Object[]) variables.get(k))[0].
                                            toString().compareTo(repeat.get(j).
                                                toString()) == 0) {

                                            no_borrar = true;
                                            break;

                                        }

                                    }

                                }

                                if (no_borrar)
                                    break;

                            }

                        }

                        if (no_borrar)
                            break;
                    }

                    if (!no_borrar) {
                        panel.remove(objeto);
                        objeto.repaint();

                        //Guardar la coordenada X inicial del objeto
                        int coord_X = objeto.getX();

                        Component lista[] = panel.getComponents();
                        for (int i = 0; i < lista.length; i++) {
                            //el objeto es un mensaje
                            if (lista[i] instanceof MyMessage) {
                                MyMessage mensaje = (MyMessage) lista[i];
                                String destino = mensaje.getDest();
                                String origen = mensaje.getSource();
                                if (ident == destino || ident == origen) {
                                    mensaje.getParent().remove(mensaje);

                                    //También se debe borrar el mensaje de cada objeto que lo tenga
                                    //en su lista de send o receive
                                    for (int j = 0; j < lista.length; j++) {

                                        if (lista[j] instanceof MyActor ||
                                            lista[j] instanceof MyLifeLine) {

                                            ((MyObjects) lista[j]).
                                                    deleteSendMessage(mensaje);
                                            ((MyObjects) lista[j]).
                                                    deleteReceiveMessage(mensaje);

                                        }

                                        //Se deben subir hacia arriba los mensajes posteriores
                                        if (lista[j] instanceof MyMessage &&
                                            ((MyMessage) lista[j]).getY() >
                                            mensaje.getY()) {

                                            XYConstraints c = ((MyMessage) lista[j]).
                                                    getXY();

                                            //Coordenada y en la que se va a dibujar el mensaje
                                            c.setY(c.getY() - 30);

                                            ((MyMessage) lista[j]).
                                                    editXYconstraints(c);

                                        }

                                        //También se deben subir hacia arriba los frames posteriores
                                        if (lista[j] instanceof MyFrame &&
                                            ((MyFrame) lista[j]).getY() >
                                            mensaje.getY()) {

                                            XYConstraints c = ((MyFrame) lista[j]).
                                                    getXY();

                                            //Coordenada y en la que se va a dibujar el mensaje
                                            c.setY(c.getY() - 30);

                                            ((MyFrame) lista[j]).editXYconstraints(
                                                    c);

                                        }

                                        //Se debe borrar de los frames en que este incluido y recortar
                                        //la altura del frame
                                        if (lista[j] instanceof MyFrame &&
                                            ((MyFrame) lista[j]).includeMsg.
                                            contains(mensaje)) {

                                            ((MyObjects) lista[j]).
                                                    deleteIncludeMessage(mensaje);

                                            XYConstraints c = ((MyFrame) lista[j]).
                                                    getXY();

                                            //Coordenada y en la que se va a dibujar el mensaje
                                            c.setHeight(c.getHeight() - 30);

                                            ((MyFrame) lista[j]).editXYconstraints(
                                                    c);

                                            //Subir hacia arriba separadores en caso de tipo "par" o tipo "alt"
                                            if (((MyFrame) lista[j]).getName().
                                                compareTo("par") ==
                                                0 ||
                                                ((MyFrame) lista[j]).getName().
                                                compareTo("alt") == 0) {

                                                ArrayList separadores = ((MyFrame)
                                                        lista[j]).
                                                        separadores;

                                                for (int k = 0;
                                                        k < separadores.size(); k++) {

                                                    if (((Integer) separadores.get(
                                                            k)).intValue() +
                                                            lista[j].getY() >
                                                            mensaje.getY()) {

                                                        int valor = ((Integer)
                                                                separadores.get(k)).
                                                                intValue();

                                                        separadores.remove(k);
                                                        separadores.add(k,
                                                                new
                                                                Integer(valor - 30));

                                                    }

                                                }

                                                //Se deben eliminar aquellos separadores que ya no sean necesarios
                                                for (int k = 0;
                                                        k < separadores.size(); k++) {

                                                    //Si el valor es igual a 28 es que ya no queda ningún mensaje por encima
                                                    if ((((Integer) separadores.get(
                                                            k)).intValue() ==
                                                            28)) {

                                                        separadores.remove(k);

                                                    }

                                                    else {

                                                        //Si es igual al siguiente
                                                        if (k < separadores.size() -
                                                                1 &&
                                                                ((Integer)
                                                                separadores.get(k)).
                                                                intValue() ==
                                                                ((Integer)
                                                                separadores.get(k +
                                                                1)).
                                                                intValue()) {

                                                            separadores.remove(k);

                                                        }

                                                    }
                                                }

                                            }

                                            //Subir hacia arriba el separador si procede en el caso del tipo "alt_else"
                                            if (((MyFrame) lista[j]).getName().
                                                compareTo("alt_else") ==
                                                0) {

                                                ArrayList separadores = ((MyFrame)
                                                        lista[j]).
                                                        separadores;

                                                if (((Integer) separadores.get(0)).
                                                    intValue() +
                                                    lista[j].getY() >
                                                    mensaje.getY()) {

                                                    int valor = ((Integer)
                                                            separadores.get(0)).
                                                            intValue();

                                                    separadores.remove(0);
                                                    separadores.add(0,
                                                            new Integer(valor - 30));

                                                }

                                            }

                                        }

                                    }

                                }

                            }
                            //el objeto es un actor o un lifeline
                            if (lista[i] instanceof MyActor ||
                                lista[i] instanceof MyLifeLine) {

                                //Si se trata de uno posterior al que hemos borrado
                                if (coord_X < lista[i].getX()) {

                                    //Se deben modificar sus coordenadas para que
                                    //ocupe el espacio dejado por el anterior

                                    //Obtener las coordenadas actuales
                                    XYConstraints c = ((MyObjects) lista[i]).getXY();

                                    //Generar las nuevas coordenadas
                                    c.setX(c.getX() - 300);

                                    //Ponerle las nuevas coordenadas al objeto
                                    ((MyObjects) lista[i]).editXYconstraints(c);

                                    //Actualizar la posición de los mensajes
                                    ((MyObjects) lista[i]).updatePosition(coord_X,
                                            i, lista);

                                }

                            }
                            //el objeto es un frame
                            if (lista[i] instanceof MyFrame) {

                                //Se debe recortar su tamaño para ajustarse a un rol menos
                                //Obtener las coordenadas actuales
                                XYConstraints c = ((MyObjects) lista[i]).getXY();

                                //Generar las nuevas coordenadas
                                c.setWidth(c.getWidth() - 300);

                                //Si la anchura queda con un tamaño menor a 0 es
                                //porque ya no quedan roles
                                if (c.getWidth() < 0) {

                                    //Se elimina el frame
                                    panel.remove(lista[i]);

                                }

                                //Ponerle las nuevas coordenadas al objeto
                                ((MyObjects) lista[i]).editXYconstraints(c);

                            }

                        }
                    } else {

                        //Mostrar el aviso de que no se trata de una variable válida
                        JOptionPane optionPane2 = new JOptionPane();
                        Object[] options2 = {"Ok"};
                        optionPane.showOptionDialog(optionPane2,
                                                    "Object can be deleted. A variable defined in this object is being used in a frame",
                                                    "Message",
                                                    optionPane2.YES_NO_OPTION,
                                                    optionPane2.ERROR_MESSAGE, null,
                                                    options2, null);

                    }
                }

                //Si se trata de un mensaje
                if (objeto instanceof MyMessage) {

                    panel.remove(objeto);
                    objeto.repaint();

                    Component lista[] = panel.getComponents();

                    //Se debe borrar el mensaje de cada objeto que lo tenga
                    //en su lista de send o receive
                    for (int j = 0; j < lista.length; j++) {

                        if (lista[j] instanceof MyActor ||
                            lista[j] instanceof MyLifeLine) {

                            MyMessage mensaje = (MyMessage) objeto;

                            ((MyObjects) lista[j]).deleteSendMessage(mensaje);
                            ((MyObjects) lista[j]).deleteReceiveMessage(mensaje);

                        }

                        //También se debe borrar de la lista de incluidos de un frame
                        //y recortar el frame que lo incluye
                        if (lista[j] instanceof MyFrame &&
                            ((MyFrame) lista[j]).getY() <= objeto.getY()
                            &&
                            ((MyFrame) lista[j]).getY() + ((MyFrame) lista[j]).getHeight() >
                            objeto.getY()) {

                            MyMessage mensaje = (MyMessage) objeto;

                            ((MyObjects) lista[j]).deleteIncludeMessage(mensaje);

                            XYConstraints c = ((MyFrame) lista[j]).getXY();

                            //Recortar la altura
                            c.setHeight(c.getHeight() - 30);

                            ((MyFrame) lista[j]).editXYconstraints(c);

                            //Subir hacia arriba separadores en caso de tipo "par" o "alt"
                            if (((MyFrame) lista[j]).getName().compareTo("par") ==
                                0 ||
                                ((MyFrame) lista[j]).getName().compareTo("alt") == 0) {

                                ArrayList separadores = ((MyFrame) lista[j]).
                                        separadores;

                                for (int k = 0; k < separadores.size(); k++) {

                                    if (((Integer) separadores.get(k)).intValue() +
                                        lista[j].getY() > mensaje.getY()) {

                                        int valor = ((Integer) separadores.get(k)).
                                                    intValue();

                                        separadores.remove(k);
                                        separadores.add(k, new Integer(valor - 30));

                                    }

                                }

                                //Se deben eliminar aquellos separadores que ya no sean necesarios
                                for (int k = 0; k < separadores.size(); k++) {

                                    //Si el valor es igual a 28 es que ya no queda ningún mensaje por encima
                                    if ((((Integer) separadores.get(k)).intValue() ==
                                         28)) {

                                        separadores.remove(k);

                                    }

                                    else {

                                        //Si es igual al siguiente
                                        if (k < separadores.size() - 1 &&
                                            ((Integer) separadores.get(k)).intValue() ==
                                            ((Integer) separadores.get(k + 1)).
                                            intValue()) {

                                            separadores.remove(k);

                                        }

                                    }
                                }

                            }

                            //Subir hacia arriba el separador si procede en el caso del tipo "alt_else"
                            if (((MyFrame) lista[j]).getName().compareTo("alt_else") ==
                                0) {

                                ArrayList separadores = ((MyFrame) lista[j]).
                                        separadores;

                                if (((Integer) separadores.get(0)).intValue() +
                                    lista[j].getY() > mensaje.getY()) {

                                    int valor = ((Integer) separadores.get(0)).
                                                intValue();

                                    separadores.remove(0);
                                    separadores.add(0, new Integer(valor - 30));

                                }

                            }

                        }

                        //También se deben subir hacia arriba los mensajes posteriores
                        if (lista[j] instanceof MyMessage &&
                            ((MyMessage) lista[j]).getY() > objeto.getY()) {

                            XYConstraints c = ((MyMessage) lista[j]).getXY();

                            //Coordenada y en la que se va a dibujar el mensaje
                            c.setY(c.getY() - 30);

                            ((MyMessage) lista[j]).editXYconstraints(c);

                        }

                        //También se deben subir hacia arriba los frames posteriores
                        if (lista[j] instanceof MyFrame &&
                            ((MyFrame) lista[j]).getY() > objeto.getY()) {

                            XYConstraints c = ((MyFrame) lista[j]).getXY();

                            //Coordenada y en la que se va a dibujar el mensaje
                            c.setY(c.getY() - 30);

                            ((MyFrame) lista[j]).editXYconstraints(c);

                        }

                    }

                    //Se deben recortar las lineas de los actor y los lifelines
                    for (int j = 0; j < lista.length; j++) {

                        if (lista[j] instanceof MyLifeLine) {

                            MyLifeLine lin = ((MyLifeLine) lista[j]);

                            XYConstraints c2 = lin.getXY();

                            c2.setHeight(c2.getHeight() - 30);

                            lin.editXYconstraints(c2);

                        }

                        if (lista[j] instanceof MyActor) {

                            MyActor lin = ((MyActor) lista[j]);

                            XYConstraints c2 = lin.getXY();

                            c2.setHeight(c2.getHeight() - 30);

                            lin.editXYconstraints(c2);

                        }

                    }

                }

                //Si el panel se ha quedado vacío se debe limpiar la ventana de código
                if (panel.getComponentCount() == 1) {

                    ((TraduccionMarco) panel.getRootPane().getParent()).deleteCode();

                }

            }

            //Modificar el color del objeto al inicial
            objeto.setCol(Color.black);

            //Si se trata de un actor o de un lifeline colorear también los mensajes enviados y recibidos de nuevo de negro
            if (objeto instanceof MyActor || objeto instanceof MyLifeLine) {

                for (int i = 0; i < objeto.sendedMsg.size(); i++) {

                    ((MyObjects) objeto.sendedMsg.get(i)).setCol(Color.black);

                }

                for (int i = 0; i < objeto.receivedMsg.size(); i++) {

                    ((MyObjects) objeto.receivedMsg.get(i)).setCol(Color.black);

                }

            }

            //Se debe repintar el panel que contiene a los objetos
            panel.repaint();
            panel.updateUI();

        }

        //Si se ha elegido la opción de editar variables
        else if (e.getActionCommand().compareTo("Variables") == 0) {

            Frame[] activeframes = Frame.getFrames();

            new VariablesClase(objeto, (Frame) activeframes[0]);

        }

        //Si se ha elegido la opción de actualizar variables
        else if (e.getActionCommand().compareTo("Update variables") == 0) {

            Frame[] activeframes = Frame.getFrames();

            new VarUpdateClase(objeto, (Frame) activeframes[0]);

        }

        //Si se ha elegido la opción de intercambiar variables
        else if (e.getActionCommand().compareTo("Exchange variables") == 0) {

            JOptionPane optionPane= new JOptionPane();
            JTextField send = new JTextField(((MyMessage)objeto).getSend_variable());
            JTextField receive = new JTextField(((MyMessage)objeto).getReceive_variable());

            Object[] camposArray = {"Send variable:",send,"Receive variable:", receive};

            Object[] options = {"Ok", "Cancel"};
            int ret = optionPane.showOptionDialog(optionPane, camposArray,
                                                  "Message Exchange",
                                                  optionPane.YES_NO_OPTION,
                                                  optionPane.QUESTION_MESSAGE, null,
                                                  options, null);

            if (ret==JOptionPane.YES_OPTION){

                //Si tiene reloj y valor asignados
                if (send.getText() != null && send.getText().compareTo("") != 0 && receive.getText() != null && receive.getText().compareTo("") != 0) {

                    //Llamar a la función que se encargue de ver que sea válido
                    boolean valid=true;
                    valid=parseoExchange(send.getText(),receive.getText());

                    if(valid){

                        //Almacenar el send y el receive
                        ((MyMessage)objeto).setSend_variable(send.getText());
                        ((MyMessage)objeto).setReceive_variable(receive.getText());

                        //Mostrar mensaje con el exchange
                        JOptionPane optionPane2 = new JOptionPane();
                        Object[] options2 = {"Ok"};
                        optionPane2.showOptionDialog(optionPane2,
                                                     "Exchange "+receive.getText()+" := "+send.getText(),
                                                     "Message", optionPane2.YES_NO_OPTION,
                                                     optionPane2.INFORMATION_MESSAGE, null,
                                                     options2, null);

                        //Se debe repintar el panel que contiene a los objetos
                        panel.repaint();
                        panel.updateUI();

                    }

                    else{

                        //Mostrar mensaje de que no es válido
                        JOptionPane optionPane2= new JOptionPane();
                        Object[] options2 = {"Ok"};
                        optionPane2.showOptionDialog(optionPane2,
                                    "Invalid exchange",
                                    "Message", optionPane2.YES_NO_OPTION,
                                    optionPane2.ERROR_MESSAGE, null,
                                    options2, null);

                    }
                }

                else if(send.getText().compareTo("") == 0 && receive.getText().compareTo("") == 0){

                    //Almacenar el send y el receive
                    ((MyMessage)objeto).setSend_variable(send.getText());
                    ((MyMessage)objeto).setReceive_variable(receive.getText());


                    //Mostrar mensaje de que no hay exchange
                    JOptionPane optionPane2= new JOptionPane();
                    Object[] options2 = {"Ok"};
                    optionPane2.showOptionDialog(optionPane2,
                                "No exchange",
                                "Message", optionPane2.YES_NO_OPTION,
                                optionPane2.INFORMATION_MESSAGE, null,
                                options2, null);

                    //Se debe repintar el panel que contiene a los objetos
                    panel.repaint();
                    panel.updateUI();



                }
                else{
                    //Mostrar mensaje de que no es válido
                    JOptionPane optionPane2= new JOptionPane();
                    Object[] options2 = {"Ok"};
                    optionPane2.showOptionDialog(optionPane2,
                                "Invalid exchange",
                                "Message", optionPane2.YES_NO_OPTION,
                                optionPane2.ERROR_MESSAGE, null,
                                options2, null);

                }


            }

        }

        //Si se ha elegido la opción de fijar timeout
        else if(e.getActionCommand().compareTo("Time to complete")==0){

            JOptionPane optionPane= new JOptionPane();
            JTextField timeout_clock = new JTextField(((MyMessage)objeto).getTimeout_clock());
            JTextField timeout = new JTextField(((MyMessage)objeto).getTimeout());

            Object[] camposArray = {"Clock",timeout_clock,"Time to complete:", timeout};

            Object[] options = {"Ok", "Cancel"};
            int ret = optionPane.showOptionDialog(optionPane, camposArray,
                                                  "Message Timeout",
                                                  optionPane.YES_NO_OPTION,
                                                  optionPane.QUESTION_MESSAGE, null,
                                                  options, null);

            if (ret==JOptionPane.YES_OPTION){

                //Si tiene reloj y valor asignados
                if (timeout_clock.getText() != null && timeout_clock.getText().compareTo("") != 0 && timeout.getText() != null && timeout.getText().compareTo("") != 0) {

                    //Llamar a la función que se encargue de ver que sea válido
                    boolean valid=true;
                    valid=parseoTimeout(timeout_clock.getText(),timeout.getText());

                    if(valid){

                        //Almacenar el reloj y el valor
                        ((MyMessage)objeto).setTimeout_clock(timeout_clock.getText());
                        ((MyMessage)objeto).setTimeout(timeout.getText());

                        //Mostrar mensaje con el valor del timeout
                        JOptionPane optionPane2 = new JOptionPane();
                        Object[] options2 = {"Ok"};
                        optionPane2.showOptionDialog(optionPane2,
                                                     "Timeout "+timeout_clock.getText()+" <= "+timeout.getText(),
                                                     "Message", optionPane2.YES_NO_OPTION,
                                                     optionPane2.INFORMATION_MESSAGE, null,
                                                     options2, null);

                        //Se debe repintar el panel que contiene a los objetos
                        panel.repaint();
                        panel.updateUI();

                    }

                    else{

                        //Mostrar mensaje de que no es válido
                        JOptionPane optionPane2= new JOptionPane();
                        Object[] options2 = {"Ok"};
                        optionPane2.showOptionDialog(optionPane2,
                                    "Invalid timeout",
                                    "Message", optionPane2.YES_NO_OPTION,
                                    optionPane2.ERROR_MESSAGE, null,
                                    options2, null);

                    }
                }

                else if(timeout_clock.getText().compareTo("") == 0 && timeout.getText().compareTo("") == 0){

                    //Almacenar el reloj y el valor
                    ((MyMessage) objeto).setTimeout_clock(timeout_clock.getText());
                    ((MyMessage) objeto).setTimeout(timeout.getText());

                    //Mostrar mensaje de que es infinito
                    JOptionPane optionPane2= new JOptionPane();
                    Object[] options2 = {"Ok"};
                    optionPane2.showOptionDialog(optionPane2,
                                "No timeout",
                                "Message", optionPane2.YES_NO_OPTION,
                                optionPane2.INFORMATION_MESSAGE, null,
                                options2, null);

                    //Se debe repintar el panel que contiene a los objetos
                    panel.repaint();
                    panel.updateUI();



                }
                else{
                    //Mostrar mensaje de que no es válido
                    JOptionPane optionPane2= new JOptionPane();
                    Object[] options2 = {"Ok"};
                    optionPane2.showOptionDialog(optionPane2,
                                "Invalid timeout",
                                "Message", optionPane2.YES_NO_OPTION,
                                optionPane2.ERROR_MESSAGE, null,
                                options2, null);

                }


            }


        }

        //Si se ha elegido la opción de fijar excepción
        else{
            JOptionPane optionPane= new JOptionPane();
            JTextField exception_type = new JTextField(((MyMessage)objeto).getException_variable());

            Object[] camposArray = {"Exception",exception_type};

            Object[] options = {"Ok", "Cancel"};
            int ret = optionPane.showOptionDialog(optionPane, camposArray,
                                                  "Message Exception",
                                                  optionPane.YES_NO_OPTION,
                                                  optionPane.QUESTION_MESSAGE, null,
                                                  options, null);

            if (ret==JOptionPane.YES_OPTION){

                //Si tiene excepción asignada
                if (exception_type.getText() != null && exception_type.getText().compareTo("") != 0) {

                    //Llamar a la función que se encargue de ver que sea válido
                    boolean valid=true;
                    valid=parseoException(exception_type.getText());

                    if(valid){

                        //Almacenar la excepción
                        ((MyMessage)objeto).setException_variable(exception_type.getText());

                        //Mostrar mensaje con el valor de la variable de excepción
                        JOptionPane optionPane2 = new JOptionPane();
                        Object[] options2 = {"Ok"};
                        optionPane2.showOptionDialog(optionPane2,
                                                     "Cause exception "+exception_type.getText(),
                                                     "Message", optionPane2.YES_NO_OPTION,
                                                     optionPane2.INFORMATION_MESSAGE, null,
                                                     options2, null);

                        //Se debe repintar el panel que contiene a los objetos
                        panel.repaint();
                        panel.updateUI();

                    }

                    else{

                        //Mostrar mensaje de que no es válido
                        JOptionPane optionPane2= new JOptionPane();
                        Object[] options2 = {"Ok"};
                        optionPane2.showOptionDialog(optionPane2,
                                    "Invalid exception",
                                    "Message", optionPane2.YES_NO_OPTION,
                                    optionPane2.ERROR_MESSAGE, null,
                                    options2, null);

                    }
                }

                else if(exception_type.getText().compareTo("") == 0){

                    //Almacenar la excepcion
                    ((MyMessage) objeto).setException_variable(exception_type.getText());

                    //Mostrar mensaje de que no tiene
                    JOptionPane optionPane2= new JOptionPane();
                    Object[] options2 = {"Ok"};
                    optionPane2.showOptionDialog(optionPane2,
                                "No exception",
                                "Message", optionPane2.YES_NO_OPTION,
                                optionPane2.INFORMATION_MESSAGE, null,
                                options2, null);

                    //Se debe repintar el panel que contiene a los objetos
                    panel.repaint();
                    panel.updateUI();



                }
                else{
                    //Mostrar mensaje de que no es válido
                    JOptionPane optionPane2= new JOptionPane();
                    Object[] options2 = {"Ok"};
                    optionPane2.showOptionDialog(optionPane2,
                                "Invalid exception",
                                "Message", optionPane2.YES_NO_OPTION,
                                optionPane2.ERROR_MESSAGE, null,
                                options2, null);

                }


            }

        }

        panel = panel_aux;
    }

    public String parseoGuarda(String guarda_text, boolean es_not){

        //Cadena con las nuevas variables
        String new_var = "";

        //Eliminar todos los espacios en blanco existentes en la cadena
        guarda_text = guarda_text.trim();

        //Variable booleana que indique si nos encontramos dentro de un not
        boolean en_not = es_not;

        //Intentar quitar todos los not que tenga la expresión para analizarla
        //como si fuera sin not
        if(guarda_text.startsWith("not(")){

            //Ver donde se inicia el primer not
            int index = guarda_text.indexOf("not(");

            //Ver donde acaba el not que se ha encontrado
            int index_fin = 0;
            String despues_not = guarda_text.substring(index + 4);
            int index_recorrido = 0;

            while((index_fin == 0) && (despues_not.indexOf(")",index_recorrido + 1) != -1)){

                index_recorrido = despues_not.indexOf(")",index_recorrido + 1);

                //Ver que el número de parentesis que se abren y se cierran
                //entre medias sea igual
                String entre_parentesis = despues_not.substring(0,index_recorrido);
                int n_abre = 0, n_cierra = 0;

                for (int i = 0; i < entre_parentesis.length(); i++){

                    if(entre_parentesis.charAt(i)=='(') n_abre++;
                    if(entre_parentesis.charAt(i)==')') n_cierra++;

                }

                if(n_abre == n_cierra){

                    index_fin = index_recorrido;

                }

            }

            //Quitar el not de la expresión si afecta a toda la expresión
            if((index_fin + 4 == guarda_text.lastIndexOf(")")) && (guarda_text.lastIndexOf(")") == guarda_text.length() - 1)){

                //Dejar marcado que nos encontramos dentro de un not
                en_not = true;

                guarda_text = guarda_text.substring(index + 4, guarda_text.lastIndexOf(")"));

            }
        }

        XPathParser parseo = new XPathParser(new StringReader(guarda_text));

        try{

            NaryExpr ne = (NaryExpr) parseo.OrExpr();

            //El número de expresiones en que se divide debe ser mayor que 2, en caso contrario se toma como no válido
            if (ne.getExprsCount() < 2) {

                return null;

            }

            //Si el número de expresiones en que se divide es justamente 2
            else if (ne.getExprsCount() == 2){

                //Ver si la expresión es relacional

                parseo = new XPathParser(new StringReader(guarda_text));

                try{

                    RelationalExpr re1 = (RelationalExpr) parseo.RelationalExpr();

                    //Se debe mirar que la guarda ya no contenga ningún parentesis
                    if(guarda_text.contains("(") || guarda_text.contains(")")){

                        return null;

                    }

                    else{

                        //Si es relacional se debe mirar que los hijos sean variables y números
                        //y que sean compatibles

                        String hijo1 = ne.getExpr(0).toString();

                        parseo = new XPathParser(new StringReader(hijo1));

                        String tipo_hijo1 = "";

                        try {

                            try {

                                //Ver si es un número
                                Integer.parseInt(hijo1.replaceFirst("\\.0",""));
                                tipo_hijo1 = "numero";

                            } catch (Throwable exh2) {

                                //Si no es un número
                                hijo1 = ne.getExpr(0).toString().substring(7);

                                parseo = new XPathParser(new StringReader(hijo1));

                                //Ver que sea una variable válida
                                String vari = parseo.QName();

                                //Ver que el tamaño de hijo1 y del resultado del parseo coinciden
                                if (vari.length() != hijo1.length()) {

                                    return null;

                                }

                                else {

                                    //Se debe mirar si se trata de true o false
                                    if(hijo1.compareTo("true")==0 || hijo1.compareTo("false")==0){

                                        tipo_hijo1 = "Bool";

                                    }

                                    else{

                                        //Si se trata de una variable válida se debe mirar que
                                        //esté definida en algún Actor o Lifeline
                                        JPanel jPanelDraw = (JPanel) objeto.getParent();
                                        Component[] lista = jPanelDraw.getComponents();
                                        ArrayList al = new ArrayList();

                                        boolean existe = false;

                                        for (int i = 0; i < lista.length; i++) {

                                            if (lista[i] instanceof MyActor ||
                                                lista[i] instanceof MyLifeLine) {

                                                MyObjects mo = (MyObjects) lista[i];

                                                al = mo.getVariables();

                                                for (int j = 0; j < al.size(); j++) {

                                                    if (((Object[]) al.get(j))[0].toString().compareTo(vari) ==
                                                        0) {

                                                        existe = true;
                                                        tipo_hijo1 = ((Object[]) al.get(j))[1].toString();

                                                        //Si la expresion es sobre un or no puede ser de tipo clock
                                                        //Tampoco puede ser en un not
                                                        if((en_not) && tipo_hijo1.compareTo("Clock")==0)
                                                            return null;

                                                        break;

                                                    }

                                                }

                                            }

                                            if (existe)
                                                break;

                                        }

                                        //Si la variable no está definida
                                        if (!existe)
                                            return null;

                                    }

                                }

                            }

                            //Añadirlo a la lista de variables correspondiente
                            //si no se trata de un número
                            if(tipo_hijo1.compareTo("numero")!=0) new_var = hijo1 + " ";
                            String hijo2 = ne.getExpr(1).toString();

                            parseo = new XPathParser(new StringReader(hijo2));

                            String tipo_hijo2 = "";

                            try {
                                //Ver que sea un número
                                Integer.parseInt(hijo2.replaceFirst("\\.0",""));

                                //Ver que además de ser un número lo devuelto por
                                //el parseo no se están descartando caracteres al
                                //final de la expresión

                                String hijo_fin = "";

                                if(guarda_text.contains("<=")){

                                    hijo_fin = guarda_text.substring(guarda_text.indexOf("<=")+2,guarda_text.length()).trim().replaceFirst("\\.0","");

                                }
                                else if (guarda_text.contains("<")){

                                    hijo_fin = guarda_text.substring(guarda_text.indexOf("<")+1,guarda_text.length()).trim().replaceFirst("\\.0","");

                                }
                                else if (guarda_text.contains(">=")){

                                    hijo_fin = guarda_text.substring(guarda_text.indexOf(">=")+2,guarda_text.length()).trim().replaceFirst("\\.0","");

                                }
                                else{

                                    hijo_fin = guarda_text.substring(guarda_text.indexOf(">")+1,guarda_text.length()).trim().replaceFirst("\\.0","");

                                }

                                Integer.parseInt(hijo_fin);

                                tipo_hijo2 = "numero";

                            } catch (Throwable exh2) {

                                //Si no es un número
                                hijo2 = ne.getExpr(1).toString().substring(7);
                                parseo = new XPathParser(new StringReader(hijo2));

                                //Ver que sea una variable válida
                                String vari = parseo.QName();

                                //Ver que el tamaño de hijo1 y del resultado del parseo coinciden
                                if (vari.length() != hijo2.length()) {

                                    return null;

                                }

                                else {

                                    //Se debe mirar si se trata de true o false
                                    if(hijo2.compareTo("true")==0 || hijo2.compareTo("false")==0){

                                        tipo_hijo2 = "Bool";

                                    }

                                    else{

                                        //Si se trata de una variable válida se debe mirar que
                                        //esté definida en algún Actor o Lifeline
                                        JPanel jPanelDraw = (JPanel) objeto.getParent();
                                        Component[] lista = jPanelDraw.getComponents();
                                        ArrayList al = new ArrayList();

                                        boolean existe = false;

                                        for (int i = 0; i < lista.length; i++) {

                                            if (lista[i] instanceof MyActor ||
                                                lista[i] instanceof MyLifeLine) {

                                                MyObjects mo = (MyObjects) lista[i];

                                                al = mo.getVariables();

                                                for (int j = 0; j < al.size(); j++) {

                                                    if (((Object[]) al.get(j))[0].toString().compareTo(vari) ==
                                                        0) {

                                                        existe = true;
                                                        tipo_hijo2 = ((Object[]) al.get(j))[1].toString();

                                                        //Si la expresion es sobre un or no puede ser de tipo clock
                                                        if((en_not) && tipo_hijo2.compareTo("Clock")==0)
                                                            return null;

                                                        break;

                                                    }

                                                }

                                            }

                                            if (existe)
                                                break;

                                        }

                                        //Si la variable no está definida
                                        if (!existe)
                                            return null;
                                    }
                                }

                            }

                            //Añadirlo a la lista de variables correspondiente
                            //si no se trata de un número
                            if(tipo_hijo2.compareTo("numero")!=0) new_var = hijo2 + " ";

                            //La expresión no será válida si una variable es un reloj
                            //y la otra un booleano
                            if((tipo_hijo1.compareTo("Clock")==0 && tipo_hijo2.compareTo("Boolean")==0) ||
                               (tipo_hijo1.compareTo("Boolean")==0 && tipo_hijo2.compareTo("Clock")==0) ||
                               (tipo_hijo1.compareTo("Clock")==0 && tipo_hijo2.compareTo("Bool")==0) ||
                               (tipo_hijo1.compareTo("Bool")==0 && tipo_hijo2.compareTo("Clock")==0)){

                                return null;

                            }


                        } catch (Throwable exh1) {

                            return null;

                        }
                    }
                }

                catch (Throwable ex1) {

                    //Si no es relacional ver si la expresion es de igualdad

                    parseo = new XPathParser(new StringReader(guarda_text));

                    try{

                        EqualityExpr eq1 = (EqualityExpr) parseo.EqualityExpr();

                        //Se debe mirar que la guarda ya no contenga ningún parentesis
                        if (guarda_text.contains("(") || guarda_text.contains(")")) {

                            return null;

                        }

                        else {

                            //Si es una igualdad se debe mirar que los hijos sean números
                            //o variables y que sean compatibles

                            String hijo1 = ne.getExpr(0).toString();

                            parseo = new XPathParser(new StringReader(hijo1));

                            String tipo_hijo1 = "";

                            try {

                                try {

                                    //Ver si es un número
                                    Integer.parseInt(hijo1.replaceFirst("\\.0",""));
                                    tipo_hijo1 = "numero";

                                } catch (Throwable exh2) {

                                    //Si no es un número
                                    hijo1 = ne.getExpr(0).toString().substring(7);

                                    parseo = new XPathParser(new StringReader(hijo1));

                                    //Ver que sea una variable válida
                                    String vari = parseo.QName();

                                    //Ver que el tamaño de hijo1 y del resultado del parseo coinciden
                                    if (vari.length() != hijo1.length()) {

                                        return null;

                                    }

                                    else {

                                        //Se debe mirar si se trata de true o false
                                        if (hijo1.compareTo("true") == 0 ||
                                            hijo1.compareTo("false") == 0) {

                                            tipo_hijo1 = "Bool";

                                        }

                                        else {

                                            //Si se trata de una variable válida se debe mirar que
                                            //esté definida en algún Actor o Lifeline
                                            JPanel jPanelDraw = (JPanel) objeto.getParent();
                                            Component[] lista = jPanelDraw.getComponents();
                                            ArrayList al = new ArrayList();

                                            boolean existe = false;

                                            for (int i = 0; i < lista.length; i++) {

                                                if (lista[i] instanceof MyActor ||
                                                    lista[i] instanceof MyLifeLine) {

                                                    MyObjects mo = (MyObjects) lista[i];

                                                    al = mo.getVariables();

                                                    for (int j = 0; j < al.size(); j++) {

                                                        if (((Object[]) al.get(j))[0].toString().
                                                            compareTo(vari) ==
                                                            0) {

                                                            existe = true;
                                                            tipo_hijo1 = ((Object[]) al.get(j))[1].
                                                                         toString();
                                                            //Si la expresion es sobre un or no puede ser de tipo clock
                                                            if ((en_not) && tipo_hijo1.compareTo("Clock") == 0)
                                                                return null;

                                                            break;

                                                        }

                                                    }

                                                }

                                                if (existe)
                                                    break;

                                            }

                                            //Si la variable no está definida
                                            if (!existe)
                                                return null;

                                        }

                                    }

                                }

                                //Añadirlo a la lista de variables correspondiente
                                //si no se trata de un número
                                if (tipo_hijo1.compareTo("numero") != 0)
                                    new_var = hijo1 + " ";
                                String hijo2 = ne.getExpr(1).toString();

                                parseo = new XPathParser(new StringReader(hijo2));

                                String tipo_hijo2 = "";

                                try {

                                    //Ver que sea un número
                                    Integer.parseInt(hijo2.replaceFirst("\\.0",""));

                                    //Ver que además de ser un número lo devuelto por
                                    //el parseo no se están descartando caracteres al
                                    //final de la expresión

                                    String hijo_fin = "";

                                    if (guarda_text.contains("!=")) {

                                        hijo_fin = guarda_text.substring(guarda_text.indexOf("!=") + 2,
                                                                         guarda_text.length()).trim().
                                                                         replaceFirst("\\.0", "");


                                    } else {

                                        hijo_fin = guarda_text.substring(guarda_text.indexOf("=") + 1,
                                                                         guarda_text.length()).trim().
                                                                         replaceFirst("\\.0", "");

                                    }

                                    Integer.parseInt(hijo_fin);

                                    tipo_hijo2 = "numero";

                                } catch (Throwable exh2) {

                                    //Si no es un número
                                    hijo2 = ne.getExpr(1).toString().substring(7);
                                    parseo = new XPathParser(new StringReader(hijo2));

                                    //Ver que sea una variable válida
                                    String vari = parseo.QName();

                                    //Ver que el tamaño de hijo1 y del resultado del parseo coinciden
                                    if (vari.length() != hijo2.length()) {

                                        return null;

                                    }

                                    else {

                                        //Se debe mirar si se trata de true o false
                                        if (hijo2.compareTo("true") == 0 ||
                                            hijo2.compareTo("false") == 0) {

                                            tipo_hijo2 = "Bool";

                                        }

                                        else {

                                            //Si se trata de una variable válida se debe mirar que
                                            //esté definida en algún Actor o Lifeline
                                            JPanel jPanelDraw = (JPanel) objeto.getParent();
                                            Component[] lista = jPanelDraw.getComponents();
                                            ArrayList al = new ArrayList();

                                            boolean existe = false;

                                            for (int i = 0; i < lista.length; i++) {

                                                if (lista[i] instanceof MyActor ||
                                                    lista[i] instanceof MyLifeLine) {

                                                    MyObjects mo = (MyObjects) lista[i];

                                                    al = mo.getVariables();

                                                    for (int j = 0; j < al.size(); j++) {

                                                        if (((Object[]) al.get(j))[0].toString().
                                                            compareTo(vari) ==
                                                            0) {

                                                            existe = true;
                                                            tipo_hijo2 = ((Object[]) al.get(j))[1].
                                                                         toString();

                                                            //Si la expresion es sobre un or no puede ser de tipo clock
                                                            if ((en_not) && tipo_hijo2.compareTo("Clock") == 0)
                                                                return null;

                                                            break;

                                                        }

                                                    }

                                                }

                                                if (existe)
                                                    break;

                                            }

                                            //Si la variable no está definida
                                            if (!existe)
                                                return null;
                                        }
                                    }

                                }

                                //Añadirlo a la lista de variables correspondiente
                                //si no se trata de un número
                                if (tipo_hijo2.compareTo("numero") != 0)
                                    new_var = hijo2 + " ";

                                //La expresión no será válida si una variable es un reloj
                                //y la otra un booleano. Tampoco será válida si uno de los dos
                                //hijos es un reloj y es una expresión de desigualdad
                                if ((tipo_hijo1.compareTo("Clock") == 0 && tipo_hijo2.compareTo("Boolean") == 0) ||
                                    (tipo_hijo1.compareTo("Boolean") == 0 && tipo_hijo2.compareTo("Clock") == 0) ||
                                    (tipo_hijo1.compareTo("Clock") == 0 && tipo_hijo2.compareTo("Bool") == 0) ||
                                    (tipo_hijo1.compareTo("Bool") == 0 && tipo_hijo2.compareTo("Clock") == 0) ||
                                    (guarda_text.contains("!=") && (tipo_hijo1.compareTo("Clock") == 0 || tipo_hijo2.compareTo("Clock") == 0))) {

                                    return null;

                                }

                            } catch (Throwable exh1) {

                                return null;

                            }

                        }
                    }

                    catch (Throwable ex2) {

                        //Si no es de igualdad ver si la expresion es un and
                        parseo = new XPathParser(new StringReader(guarda_text));

                        try {

                            AndExpr and1 = (AndExpr) parseo.AndExpr();

                            //Llamar recursivamente a la función para cada uno de los hijos

                            String hijo1;

                            if(ne.getExpr(0).toString().startsWith("not("))
                                hijo1 = ne.getExpr(0).toString().replaceAll("child::","").replaceAll("AND","and").replaceAll("OR","or");
                            else
                                hijo1 = ne.getExpr(0).toString().substring(1,ne.getExpr(0).toString().length()-1).replaceAll("child::","").replaceAll("AND","and").replaceAll("OR","or");
                            if(parseoGuarda(hijo1,en_not)==null) return null;
                            String var1 = parseoGuarda(hijo1,en_not);

                            String hijo2;

                            if(ne.getExpr(1).toString().startsWith("not("))
                                hijo2 = ne.getExpr(1).toString().replaceAll("child::","").replaceAll("AND","and").replaceAll("OR","or");
                            else
                                hijo2 = ne.getExpr(1).toString().substring(1,ne.getExpr(1).toString().length()-1).replaceAll("child::","").replaceAll("AND","and").replaceAll("OR","or");
                            if(parseoGuarda(hijo2,en_not)==null) return null;
                            String var2 = parseoGuarda(hijo2,en_not);

                            //El resultado debe ser una combinación de ambas cadenas
                            new_var = var1 + var2;


                        }

                        catch (Throwable ex3) {

                            //Si no es un and ver si la expresion es un or
                            parseo = new XPathParser(new StringReader(guarda_text));

                            try {

                                OrExpr or1 = (OrExpr) parseo.OrExpr();

                                //Llamar recursivamente a la función para cada uno de los hijos

                                String hijo1;

                                if (ne.getExpr(0).toString().startsWith("not("))
                                    hijo1 = ne.getExpr(0).toString().replaceAll("child::",
                                            "").replaceAll("AND", "and").replaceAll("OR", "or");
                                else
                                    hijo1 = ne.getExpr(0).toString().substring(1,
                                            ne.getExpr(0).toString().length() - 1).replaceAll("child::", "").
                                            replaceAll("AND", "and").replaceAll("OR", "or");
                                if(parseoGuarda(hijo1,en_not)==null) return null;
                                String var1 = parseoGuarda(hijo1,en_not);

                                String hijo2;

                                if (ne.getExpr(1).toString().startsWith("not("))
                                    hijo2 = ne.getExpr(1).toString().replaceAll("child::",
                                            "").replaceAll("AND", "and").replaceAll("OR", "or");
                                else
                                    hijo2 = ne.getExpr(1).toString().substring(1,
                                            ne.getExpr(1).toString().length() - 1).replaceAll("child::", "").
                                            replaceAll("AND", "and").replaceAll("OR", "or");
                                if(parseoGuarda(hijo2,en_not)==null) return null;
                                String var2 = parseoGuarda(hijo2,en_not);


                                //El resultado debe ser una combinación de ambas cadenas
                                if (var1.compareTo("") != 0 && var2.compareTo("") != 0) {

                                    new_var = var1 + var2;

                                }
                                else return null;



                            }

                            catch (Throwable ex4) {

                                return null;

                            }

                        }

                    }

                }

            }

            //Si el número de expresiones en que se divide es mayor que 2
            else{

                int n_hijos = ne.getExprsCount();

                //Ver si la expresion es un and
                parseo = new XPathParser(new StringReader(guarda_text));

                try {

                    AndExpr and1 = (AndExpr) parseo.AndExpr();

                    //Llamar recursivamente a la función para cada uno de los hijos

                    for(int i = 0; i < n_hijos; i++){

                        String hijo;

                        if (ne.getExpr(i).toString().startsWith("not("))
                            hijo = ne.getExpr(i).toString().replaceAll(
                                    "child::", "").replaceAll("AND", "and").
                                    replaceAll("OR", "or");
                        else
                            hijo = ne.getExpr(i).toString().substring(1,
                                    ne.getExpr(i).toString().length() - 1).
                                    replaceAll("child::", "").replaceAll("AND",
                                    "and").replaceAll("OR", "or");
                         if(parseoGuarda(hijo,en_not)==null) return null;
                         String var_hijo = parseoGuarda(hijo,en_not);

                         //El resultado debe ser la cadena de todos los hijos
                         new_var = new_var + var_hijo;

                    }

                }

                catch (Throwable ex3) {

                    //Si no es un and ver si la expresion es un or
                    parseo = new XPathParser(new StringReader(guarda_text));

                    try {

                        OrExpr or1 = (OrExpr) parseo.OrExpr();

                        //Llamar recursivamente a la función para cada uno de los hijos

                        for (int i = 0; i < n_hijos; i++) {

                            String hijo;

                            if (ne.getExpr(i).toString().startsWith("not("))
                                hijo = ne.getExpr(i).toString().replaceAll(
                                        "child::", "").replaceAll("AND", "and").
                                       replaceAll("OR", "or");
                            else
                                hijo = ne.getExpr(i).toString().substring(1,
                                        ne.getExpr(i).toString().length() - 1).
                                       replaceAll("child::", "").replaceAll("AND",
                                        "and").replaceAll("OR", "or");
                            if(parseoGuarda(hijo,en_not)==null) return null;
                            String var_hijo = parseoGuarda(hijo,en_not);

                            //El resultado debe ser la cadena de todos los hijos
                            if (var_hijo.compareTo("") != 0) {

                                new_var = new_var + var_hijo;

                            }
                            else return null;

                        }

                    }

                    catch (Throwable ex4) {

                        return null;

                    }

                }


            }

        }
        catch (Throwable ex) {

            return null;
        }

        //Devolver las variables
        return new_var;

    }

    public boolean parseoTimeout(String clock, String timeout){

        //clock debe ser una variable de tipo reloj ya definida
        JPanel jPanelDraw = (JPanel) objeto.getParent();
        Component[] lista = jPanelDraw.getComponents();
        ArrayList al = new ArrayList();

        boolean existe = false;

        for (int i = 0; i < lista.length; i++) {

            if (lista[i] instanceof MyActor ||
                lista[i] instanceof MyLifeLine) {

                MyObjects mo = (MyObjects) lista[i];

                al = mo.getVariables();

                for (int j = 0; j < al.size(); j++) {

                    if (((Object[]) al.get(j))[0].toString().compareTo(clock) ==
                        0) {

                        //Debe ser de tipo reloj
                        if(((Object[]) al.get(j))[1].toString().compareTo("Clock")==0){
                            existe = true;
                            break;
                        }
                    }
                }
            }

            if (existe)
                break;

        }

        //Si la variable no está definida
        if (!existe) return false;

        //timeout debe ser un entero positivo
        try {

            if(Integer.parseInt(timeout)<=0)
                return false;

        } catch (Throwable exh2) {return false;}

        return true;

    }

    public boolean parseoException(String exception){

        //exception debe ser una variable de tipo Exception ya definida
        JPanel jPanelDraw = (JPanel) objeto.getParent();
        Component[] lista = jPanelDraw.getComponents();
        ArrayList al = new ArrayList();

        boolean existe = false;

        for (int i = 0; i < lista.length; i++) {

            if (lista[i] instanceof MyActor ||
                lista[i] instanceof MyLifeLine) {

                MyObjects mo = (MyObjects) lista[i];

                al = mo.getVariables();

                for (int j = 0; j < al.size(); j++) {

                    if (((Object[]) al.get(j))[0].toString().compareTo(exception) ==
                        0) {

                        //Debe ser de tipo exception
                        if(((Object[]) al.get(j))[1].toString().compareTo("Exception")==0){
                            existe = true;
                            break;
                        }
                    }
                }
            }

            if (existe)
                break;

        }

        //Si la variable no está definida
        if (!existe) return false;
        else return true;
    }

    public boolean parseoExchange(String send, String receive){

        /***Ahora mismo no se tiene en cuenta en que rol se definen las variables***/

        //send y recieve deben ser dos variable ya definidas del mismo tipo
        //que no sean de tipo clock o exception
        JPanel jPanelDraw = (JPanel) objeto.getParent();
        Component[] lista = jPanelDraw.getComponents();
        ArrayList al = new ArrayList();

        String tipo_send="";
        String tipo_receive="";
        boolean existe_send=false;
        boolean existe_receive=false;

        for (int i = 0; i < lista.length; i++) {

            if (lista[i] instanceof MyActor ||
                lista[i] instanceof MyLifeLine) {

                MyObjects mo = (MyObjects) lista[i];

                al = mo.getVariables();

                for (int j = 0; j < al.size(); j++) {

                    if (((Object[]) al.get(j))[0].toString().compareTo(send) ==
                        0) {

                        tipo_send=((Object[]) al.get(j))[1].toString();
                        existe_send=true;

                    }

                    if (((Object[]) al.get(j))[0].toString().compareTo(receive) ==
                        0) {

                        tipo_receive=((Object[]) al.get(j))[1].toString();
                        existe_receive=true;

                    }


                }
            }

            if(existe_send && existe_receive) break;

        }

        //Si una de las dos variables no está definida
        if (!existe_send || !existe_receive) return false;


        //Ver que el tipo de ambas variables coincide y no es clock o exception
        else if(tipo_send.compareTo(tipo_receive)==0 && tipo_send.compareTo("Clock")!=0 && tipo_send.compareTo("Exception")!=0)
          return true;
        //En cualquier otro caso retornar false
        else return false;
    }

    public String cambiarIguales(String guarda_text){

        for(int i = 0; i < guarda_text.length(); i++){

            if(guarda_text.charAt(i)=='=' && guarda_text.charAt(i - 1)!='!'
                    && guarda_text.charAt(i - 1)!='<'
                    && guarda_text.charAt(i - 1)!='>'){

                //Añadir otro = justo después
                guarda_text = guarda_text.substring(0,i+1) + "=" + guarda_text.substring(i+1,guarda_text.length());

                //Desplazar al siguiente carácter para que no mire justo el que se acaba de añadir
                i++;

            }

        }

        return guarda_text;

    }

    public String guardaNegada(String guarda_text){

        //Eliminar todos los espacios en blanco existentes en la cadena
        guarda_text = guarda_text.trim();

        //Dejar los iguales dobles como iguales simples para poder parsear las
        //expresiones de igualdad
        guarda_text = guarda_text.replaceAll("==","=");

        //Si lo primero que se encuentra es un not que afecta a toda la expresión
        //se devuelve la expresión sin el not
        if(guarda_text.startsWith("not(")){

            //Ver donde se inicia el primer not
            int index = guarda_text.indexOf("not(");

            //Ver donde acaba el not que se ha encontrado
            int index_fin = 0;
            String despues_not = guarda_text.substring(index + 4);
            int index_recorrido = 0;

            while((index_fin == 0) && (despues_not.indexOf(")",index_recorrido + 1) != -1)){

                index_recorrido = despues_not.indexOf(")",index_recorrido + 1);

                //Ver que el número de parentesis que se abren y se cierran
                //entre medias sea igual
                String entre_parentesis = despues_not.substring(0,index_recorrido);
                int n_abre = 0, n_cierra = 0;

                for (int i = 0; i < entre_parentesis.length(); i++){

                    if(entre_parentesis.charAt(i)=='(') n_abre++;
                    if(entre_parentesis.charAt(i)==')') n_cierra++;

                }

                if(n_abre == n_cierra){

                    index_fin = index_recorrido;

                }

            }

            //Si afecta a toda la expresión
            if((index_fin + 4 == guarda_text.lastIndexOf(")")) && (guarda_text.lastIndexOf(")") == guarda_text.length() - 1)){

                guarda_text = guarda_text.substring(index + 4, guarda_text.lastIndexOf(")"));
                return guarda_text;

            }
        }

        XPathParser parseo = new XPathParser(new StringReader(guarda_text));

        try{

            NaryExpr ne = (NaryExpr) parseo.OrExpr();

            //Si el número de expresiones en que se divide es justamente 2
            if (ne.getExprsCount() == 2){

                //Ver si la expresión es relacional

                parseo = new XPathParser(new StringReader(guarda_text));

                try{

                    RelationalExpr re1 = (RelationalExpr) parseo.RelationalExpr();

                    //Si es relacional se debe cambiar la comparación realizada
                    //por la complementaria

                    if(guarda_text.contains("<") && !guarda_text.contains("<=")){

                        return guarda_text.replaceAll("<",">=");

                    }
                    else if(guarda_text.contains("<=")){

                        return guarda_text.replaceAll("<=",">");

                    }
                    else if(guarda_text.contains(">") && !guarda_text.contains(">=")){

                        return guarda_text.replaceAll(">","<=");

                    }
                    else{

                        return guarda_text.replaceAll(">=","<");

                    }

                }

                catch (Throwable ex1) {

                    //Si no es relacional ver si la expresion es de igualdad

                    parseo = new XPathParser(new StringReader(guarda_text));
                    try{

                        EqualityExpr eq1 = (EqualityExpr) parseo.EqualityExpr();

                        //Se debe poner la expresión complementaria a la expresión
                        //de igualdad actual
                        if(guarda_text.contains("!=")){

                            return guarda_text.replaceAll("!=","==");

                        }
                        //Si la expresión es una igualdad se debe mirar si alguna
                        //de las variables es un reloj
                        else{

                            int index = guarda_text.indexOf("=");

                            String hijo1 = guarda_text.substring(0,index).trim();
                            String hijo2 = guarda_text.substring(index+1,guarda_text.length()).trim();

                            String tipo_hijo1 = "";
                            String tipo_hijo2 = "";

                            boolean hay_reloj = false;
                            boolean comprobado_hijo1 = false;
                            boolean comprobado_hijo2 = false;

                            //Si se trata de una variable válida se debe mirar que
                            //esté definida en algún Actor o Lifeline
                            JPanel jPanelDraw = (JPanel) objeto.getParent();
                            Component[] lista = jPanelDraw.getComponents();
                            ArrayList al = new ArrayList();

                            for (int i = 0; i < lista.length; i++) {

                                if (lista[i] instanceof MyActor ||
                                    lista[i] instanceof MyLifeLine) {

                                    MyObjects mo = (MyObjects) lista[i];

                                    al = mo.getVariables();

                                    for (int j = 0; j < al.size(); j++) {

                                        if (((Object[]) al.get(j))[0].toString().
                                            compareTo(hijo1) ==
                                            0) {

                                            tipo_hijo1 = ((Object[]) al.get(j))[1].
                                                         toString();
                                            comprobado_hijo1 = true;

                                            //Si es de tipo clock
                                            if (tipo_hijo1.compareTo("Clock") == 0)

                                               hay_reloj = true;

                                            break;

                                        }

                                        if (((Object[]) al.get(j))[0].toString().
                                            compareTo(hijo2) ==
                                            0) {

                                            tipo_hijo2 = ((Object[]) al.get(j))[1].
                                                         toString();
                                            comprobado_hijo2 = true;

                                            //Si es de tipo clock
                                            if (tipo_hijo2.compareTo("Clock") == 0)

                                               hay_reloj = true;

                                            break;

                                        }

                                    }

                                }

                                if (comprobado_hijo1 && comprobado_hijo2)
                                    break;

                            }

                            //Si existe un reloj en la expresión
                            if (hay_reloj){

                                return "("+hijo1+"<"+hijo2+")"+"or"+"("+hijo1+">"+hijo2+")";

                            }
                            else{

                                return guarda_text.replaceAll("=","!=");

                            }

                        }

                    }

                    catch (Throwable ex2) {

                        //Si no es de igualdad ver si la expresion es un and
                        parseo = new XPathParser(new StringReader(guarda_text));

                        try {

                            AndExpr and1 = (AndExpr) parseo.AndExpr();

                            //Llamar recursivamente a la función para cada uno de los hijos

                            String hijo1;

                            if(ne.getExpr(0).toString().startsWith("not("))
                                hijo1 = ne.getExpr(0).toString().replaceAll("child::","").replaceAll("AND","and").replaceAll("OR","or");
                            else
                                hijo1 = ne.getExpr(0).toString().substring(1,ne.getExpr(0).toString().length()-1).replaceAll("child::","").replaceAll("AND","and").replaceAll("OR","or");

                            String hijo2;

                            //Se debe mantener el not
                            if(ne.getExpr(1).toString().startsWith("not("))
                                hijo2 = ne.getExpr(1).toString().replaceAll("child::","").replaceAll("AND","and").replaceAll("OR","or");
                            else
                                hijo2 = ne.getExpr(1).toString().substring(1,ne.getExpr(1).toString().length()-1).replaceAll("child::","").replaceAll("AND","and").replaceAll("OR","or");

                            //Se debe devolver el or de las expresiones negadas
                            return "("+guardaNegada(hijo1)+") or ("+guardaNegada(hijo2)+")";

                        }

                        catch (Throwable ex3) {

                            //Si no es un and ver si la expresion es un or
                            parseo = new XPathParser(new StringReader(guarda_text));

                            try {

                                OrExpr or1 = (OrExpr) parseo.OrExpr();

                                //Llamar recursivamente a la función para cada uno de los hijos

                                String hijo1;

                                if (ne.getExpr(0).toString().startsWith("not("))
                                    hijo1 = ne.getExpr(0).toString().replaceAll("child::",
                                            "").replaceAll("AND", "and").replaceAll("OR", "or");
                                else
                                    hijo1 = ne.getExpr(0).toString().substring(1,
                                            ne.getExpr(0).toString().length() - 1).replaceAll("child::", "").
                                            replaceAll("AND", "and").replaceAll("OR", "or");

                                String hijo2;

                                if (ne.getExpr(1).toString().startsWith("not("))
                                    hijo2 = ne.getExpr(1).toString().replaceAll("child::",
                                            "").replaceAll("AND", "and").replaceAll("OR", "or");
                                else
                                    hijo2 = ne.getExpr(1).toString().substring(1,
                                            ne.getExpr(1).toString().length() - 1).replaceAll("child::", "").
                                            replaceAll("AND", "and").replaceAll("OR", "or");

                                //Se debe devolver el and de las expresiones negadas
                                return "("+guardaNegada(hijo1)+") and ("+guardaNegada(hijo2)+")";

                            }

                            catch (Throwable ex4) {

                                return null;

                            }

                        }

                    }

                }

            }

            //Si el número de expresiones en que se divide es mayor que 2
            else{

                //Ver si la expresion es un and
                parseo = new XPathParser(new StringReader(guarda_text));

                try {

                    AndExpr and1 = (AndExpr) parseo.AndExpr();

                    //Llamar recursivamente a la función para los dos hijos
                    //Al ser asociativo por la izquierda se toman como los dos hijos
                    //lo que hay a la izquierda del último and y lo que hay a la derecha

                    int index = guarda_text.lastIndexOf("and");

                    String hijo1 = guarda_text.substring(0,index).trim();
                    String hijo2 = guarda_text.substring(index+3,guarda_text.length()).trim();

                    //Se deben eliminar también los paréntesis de la expresión
                    hijo2 = hijo2.substring(1,hijo2.length()-1);

                    //Se debe devolver el or de las expresiones negadas
                    return "("+guardaNegada(hijo1)+") or ("+guardaNegada(hijo2)+")";

                }

                catch (Throwable ex3) {

                    //Si no es un and ver si la expresion es un or
                    parseo = new XPathParser(new StringReader(guarda_text));

                    //Llamar recursivamente a la función para los dos hijos
                    //Al ser asociativo por la izquierda se toman como los dos hijos
                    //lo que hay a la izquierda del último or y lo que hay a la derecha

                    int index = guarda_text.lastIndexOf("or");

                    String hijo1 = guarda_text.substring(0,index).trim();
                    String hijo2 = guarda_text.substring(index+2,guarda_text.length()).trim();

                    //Se debe devolver el and de las expresiones negadas
                    return "("+guardaNegada(hijo1)+") and ("+guardaNegada(hijo2)+")";

                }


            }

        }
        catch (Throwable ex) {

            return null;
        }

    }


}

