package org.wontovlab.tool;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.wontovlab.exception.IncompatibleSizeException;
import org.wontovlab.model.Experiment;
import org.wontovlab.model.Material;
import org.wontovlab.model.MaterialWrapper;
import org.wontovlab.model.Property;
import org.wontovlab.model.Step;
import org.wontovlab.model.Task;
import org.wontovlab.model.TO.StepTO;

public class XPDLParserBean {

	private List<String> differentStepsList = null;
	private List<String> similarOrEqualStepListButWithDifferentPropertiesValues = null;
	
	private String authorshipXPDL;
	private List<Step> authorshipStepListNotOrdened = null;
	private List<Step> authorshipStepListOrdened = null;
	
	private String executionXPDL;
	private List<Step> executionStepListNotOrdened = null;
	private List<Step> executionStepListOrdened = null;
	
	private String comparingWorkflowsAssessment = null;
	
	/*
	 * @param xpdlPath Path to the authorship XPDL file
	 * Load authorshipStepListNotOrdened and authorshipStepListOrdened variables from the XPDL structure
	 */
	public Experiment readAuthorshipXPDL(String xpdlPath) throws Exception {

		Experiment experiment = new Experiment();
		
		System.out.println();
		System.out.println("READING AUTHORSHIP WORKFLOW");
		System.out.println("===========================");
		
		
		//getting XPDL String from file
	    authorshipXPDL = getXPDLStringFromFile(xpdlPath); 
	    
		SAXReader reader = new SAXReader();
		Document document = null;
		document = reader.read(new StringReader(authorshipXPDL));
	    Element root = document.getRootElement();
	    
	    List<Node> workflowProcessList = root.selectNodes("//xpdl:WorkflowProcess");
	    for (int i=0; i < workflowProcessList.size(); i++) {
	    	experiment.setExperimentId(new Long((((Element) workflowProcessList.get(i)).attributeValue("Id"))));
	    	experiment.setName((((Element) workflowProcessList.get(i)).attributeValue("Name")));
	    	Element description = (Element) workflowProcessList.get(i).selectSingleNode(workflowProcessList.get(i).getUniquePath() + "/xpdl:Description");
	    	if (description != null) 
	    		experiment.setDescription(description.getText());
	    }
	    
	    //getting all the experiment's activities (XPDL activity = Experiment step) 
	    List<Node> activityNodeList = root.selectNodes("//xpdl:Activity");
	    
	    
	    //for each activity, get id, name and description. Take also the materials needed and its features (if there is)
	    for (int i=0; i < activityNodeList.size(); i++) {
	    	if (authorshipStepListNotOrdened == null)
	    		authorshipStepListNotOrdened = new ArrayList<Step>();
	    	
	    	Step step = new Step();
	    	//step.setName(((Element) activityNodeList.get(i)).attributeValue("Name"));
	    	step.setId(((Element) activityNodeList.get(i)).attributeValue("Id"));
	    	System.out.println();
	    	System.out.println(((Element) activityNodeList.get(i)).attributeValue("Id"));
	    	System.out.println("========");
	    	Element description = (Element) activityNodeList.get(i).selectSingleNode(activityNodeList.get(i).getUniquePath() + "/xpdl:Description");
	    	if (description != null)
	    		step.setDescription(description.getText());

	    	System.out.println("Descrição: " + step.getDescription());
	    	
	    	//getting all materials used in this activity
	    	List<Element> activityMaterials = getActivityMaterials((Element) activityNodeList.get(i));

	    	//setting the application ontology reference for the current step
	    	step.setApplicationOntologyReference(getApplicationOntologyReference((Element) activityNodeList.get(i)));
	    	
	    	//System.out.println("     Qtde Materiais: " + activityMaterials.size());
	    	
    		System.out.println("Materiais utilizados:");
	    	
	    	//adding each material found
	    	List<Material> materialList = new ArrayList<Material>();
	    	for (int j=0; j < activityMaterials.size(); j++) {
	    		Material material = new Material();
	    		material.setOntologyReference(((Element) activityMaterials.get(j)).attributeValue("Value"));
	    		System.out.println("                      " + ((Element) activityMaterials.get(j)).attributeValue("Value"));
	    		material.setName(OntologyMethodsBean.getInstance().doGetMaterialLabel(material.getOntologyReference()));
	    		
	    		//getting all properties/features from the material (if there is)
	    		List<Element> materialProperties = getMaterialProperties((Element) activityMaterials.get(j));
	    		
	    		if (materialProperties != null) {
		    		List<Property> properties = null;
		    		for (int k=0; k < materialProperties.size(); k++) {
		    			if (properties == null)
		    				properties = new ArrayList<Property>();
		    			
		    			Property property = new Property();
		    			property.setPropertyOntologyReference(((Element) materialProperties.get(k)).attributeValue("Name"));
		    			property.setValue(((Element) materialProperties.get(k)).attributeValue("Value"));
		    			System.out.print("                        |--> Property: " + ((Element) materialProperties.get(k)).attributeValue("Name"));
		    			System.out.println(" = " + ((Element) materialProperties.get(k)).attributeValue("Value"));
		    			properties.add(property);
		    		}
		    		material.setProperties(properties);
	    		}
	    		materialList.add(material);
	    	}
	    	step.setMaterials(materialList);

	    	
	    	
	    	//Finally, adding the activity (Step) to the list
	    	authorshipStepListNotOrdened.add(step);
	    	
	    	
    	}

	    //Ordering the stepList. Populating the authorshipStepListOrdenedvariable
	    toOrderAuthorshipStepList(root);
	    System.out.println();
	    
	    experiment.setStepList(authorshipStepListOrdened);
	    return experiment;
	}
	/*
	 * @param xpdlPath Path to the authorship XPDL file in the file system
	 * Load executionStepListNotOrdened and executionStepListOrdened variables from the XPDL structure 
	 */
	public Experiment readExecutionXPDL(String xpdlPath) throws Exception {

		Experiment experiment = new Experiment();
		
		System.out.println("READING EXECUTION WORKFLOW");
		System.out.println("==========================");
		
		//getting XPDL String from file
	    executionXPDL = getXPDLStringFromFile(xpdlPath); 
	    
		SAXReader reader = new SAXReader();
		Document document = null;
		document = reader.read(new StringReader(executionXPDL));
	    Element root = document.getRootElement();
	    
	    List<Node> workflowProcessList = root.selectNodes("//xpdl:WorkflowProcess");
	    for (int i=0; i < workflowProcessList.size(); i++) {
	    	experiment.setExperimentId(new Long((((Element) workflowProcessList.get(i)).attributeValue("Id"))));
	    	experiment.setName((((Element) workflowProcessList.get(i)).attributeValue("Name")));
	    	Element description = (Element) workflowProcessList.get(i).selectSingleNode(workflowProcessList.get(i).getUniquePath() + "/xpdl:Description");
	    	if (description != null) 
	    		experiment.setDescription(description.getText());
	    }
	    
	    //getting all the experiment's activities (XPDL activity = Experiment step) 
	    List<Node> activityNodeList = root.selectNodes("//xpdl:Activity");
	    
	    //for each activity, get id, name and description. Take also the materials needed and its features (if there is)
	    for (int i=0; i < activityNodeList.size(); i++) {
	    	if (executionStepListNotOrdened == null)
	    		executionStepListNotOrdened = new ArrayList<Step>();
	    	
	    	Step step = new Step();
	    	//step.setName(((Element) activityNodeList.get(i)).attributeValue("Name"));
	    	step.setId(((Element) activityNodeList.get(i)).attributeValue("Id"));
	    	System.out.println();
	    	System.out.println(((Element) activityNodeList.get(i)).attributeValue("Id"));
	    	System.out.println("========");
	    	Element description = (Element) activityNodeList.get(i).selectSingleNode(activityNodeList.get(i).getUniquePath() + "/xpdl:Description");
	    	if (description != null)
	    		step.setDescription(description.getText());
	    	
	    	//getting all materials used in this activity
	    	List<Element> activityMaterials = getActivityMaterials((Element) activityNodeList.get(i));
	    	
	    	System.out.println("Materiais utilizados:");
	    	
	    	//adding each material found
	    	List<Material> materialList = new ArrayList<Material>();
	    	for (int j=0; j < activityMaterials.size(); j++) {
	    		Material material = new Material();
	    		material.setOntologyReference(((Element) activityMaterials.get(j)).attributeValue("Value"));
	    		System.out.println("                      " + ((Element) activityMaterials.get(j)).attributeValue("Value"));
	    		material.setName(OntologyMethodsBean.getInstance().doGetMaterialLabel(material.getOntologyReference()));
	    		
	    		//getting all properties/features from the material (if there is)
	    		List<Element> materialProperties = getMaterialProperties((Element) activityMaterials.get(j));
	    		
	    		if (materialProperties != null) {
		    		List<Property> properties = null;
		    		for (int k=0; k < materialProperties.size(); k++) {
		    			if (properties == null)
		    				properties = new ArrayList<Property>();
		    			
		    			Property property = new Property();

		    			property.setName(OntologyMethodsBean.getInstance().getApplicationOntologyPropertyLabel(((Element) materialProperties.get(k)).attributeValue("Name")));
		    			
		    			property.setPropertyOntologyReference(((Element) materialProperties.get(k)).attributeValue("Name"));
		    			property.setValue(((Element) materialProperties.get(k)).attributeValue("Value"));
		    			System.out.print("                        |--> Property: " + ((Element) materialProperties.get(k)).attributeValue("Name"));
		    			System.out.println(" = " + ((Element) materialProperties.get(k)).attributeValue("Value"));
		    			properties.add(property);
		    		}
		    		material.setProperties(properties);
	    		}
	    		materialList.add(material);
	    	}
	    	step.setMaterials(materialList);

	    	
	    	
	    	//Finally, adding the activity (Step) to the list
	    	executionStepListNotOrdened.add(step);
	    	
	    	
    	}

	    //Ordering the stepList. Populating the authorshipStepListOrdenedvariable
	    toOrderExecutionStepList(root);
	    System.out.println();
	    
	    experiment.setStepList(authorshipStepListOrdened);
	    return experiment;
	}

	/*
	 * @param rootElement The XPDL's root element
	 * This method gets the variable authorshipStepListNotOrdened's content and put them in order in the variable stepListOrdened
	 */
	private void toOrderAuthorshipStepList(Element rootElement) {
		
		Element startEventElement = (Element) rootElement.selectSingleNode("//xpdl:ExtendedAttribute[@Name='StartEvent']");
		Element endEventElement = (Element) rootElement.selectSingleNode("//xpdl:ExtendedAttribute[@Name='EndEvent']");
		
		String startEventId = startEventElement.attributeValue("Value");
		String endEventId = endEventElement.attributeValue("Value");
		
		List<Element> transitionList = rootElement.selectNodes("//xpdl:Transition");

		authorshipStepListOrdened= new ArrayList<Step>();
		
		//Adding the first step (Getting the correct step from the authorshipStepListNotOrdened and adding on the authorshipStepListOrdened)
		//authorshipStepListOrdened.add(authorshipStepListNotOrdened.get(authorshipStepListNotOrdened.indexOf(new Step(startEventId))));
		authorshipStepListOrdened.add(getStepFromListByStepId(authorshipStepListNotOrdened, startEventId));

		//Adding the remnant steps
		String from = null;
		String to = null;
		do {
			for (int i=0; i < transitionList.size(); i++) {
				//The FROM and TO (transition's Activity Id) 
				from = (transitionList.get(i).attributeValue("From"));
				to = (transitionList.get(i).attributeValue("To"));

				//getting the lastest step on the list to find the next one
				if (from.equals(authorshipStepListOrdened.get(authorshipStepListOrdened.size()-1).getId())) {
					//authorshipStepListOrdened.add(authorshipStepListNotOrdened.get(authorshipStepListNotOrdened.indexOf(new Step(to))));
					authorshipStepListOrdened.add(getStepFromListByStepId(authorshipStepListNotOrdened, to));
					break;
				}
			}
		} while(!to.equals(endEventId)); //When the current step point to the endEventId, so it is the last one
		
		
	}
	/*
	 * @param rootElement The XPDL's root element
	 * This method gets the variable executionStepListNotOrdened's content and put them in order in the variable executionStepListOrdened
	 */
	private void toOrderExecutionStepList(Element rootElement) {
		
		Element startEventElement = (Element) rootElement.selectSingleNode("//xpdl:ExtendedAttribute[@Name='StartEvent']");
		Element endEventElement = (Element) rootElement.selectSingleNode("//xpdl:ExtendedAttribute[@Name='EndEvent']");
		
		String startEventId = startEventElement.attributeValue("Value");
		String endEventId = endEventElement.attributeValue("Value");
		
		List<Element> transitionList = rootElement.selectNodes("//xpdl:Transition");

		executionStepListOrdened= new ArrayList<Step>();
		
		//Adding the first step (Getting the correct step from the executionStepListNotOrdened and adding on the executionStepListOrdened)
		//executionStepListOrdened.add(executionStepListNotOrdened.get(executionStepListNotOrdened.indexOf(new Step(startEventId))));
		executionStepListOrdened.add(getStepFromListByStepId(executionStepListNotOrdened, startEventId));

		//Adding the remnant steps
		String from = null;
		String to = null;
		do {
			for (int i=0; i < transitionList.size(); i++) {
				//The FROM and TO (transition's Activity Id) 
				from = (transitionList.get(i).attributeValue("From"));
				to = (transitionList.get(i).attributeValue("To"));

				//getting the lastest step on the list to find the next one
				if (from.equals(executionStepListOrdened.get(executionStepListOrdened.size()-1).getId())) {
					//executionStepListOrdened.add(executionStepListNotOrdened.get(executionStepListNotOrdened.indexOf(new Step(to))));
					executionStepListOrdened.add(getStepFromListByStepId(executionStepListNotOrdened, to));
					break;
				}
			}
		} while(!to.equals(endEventId)); //When the current step point to the endEventId, so it is the last one
		
		
	}
	
	//**************Comparing workflows 
	protected String comparingWorkflows() throws Exception {
		
		comparingWorkflowsAssessment = "";
		
		boolean isWorkflowsIdentical = false; 
		//Checking if the workflows are identical.
		try {
			isWorkflowsIdentical = isAuthorshipAndExecutionWorkflowsIndentical();	
		} catch (RuntimeException e) {
			System.out.println(e.getMessage());
			comparingWorkflowsAssessment = comparingWorkflowsAssessment + e.getMessage();
			if (e.getClass() == IncompatibleSizeException.class) {
				//se tiver tamanhos diferentes, deverá fazer outra comparacao. Nao devo deixar passar essa exception
				//devo retornar true ou false nesta parte
				System.out.println("FATAL ERROR - THIS WPF VERSION IS ABLE TO COMPARE JUST WORKFLOWS WITH SAME SIZE");
				comparingWorkflowsAssessment = comparingWorkflowsAssessment + "FATAL ERROR - THIS WPF VERSION IS ABLE TO COMPARE JUST WORKFLOWS WITH SAME SIZE";
			}
		}
		
		if (isWorkflowsIdentical == true) {
			comparingWorkflowsAssessment = comparingWorkflowsAssessment + "\n\nO experimento foi executado de forma idêntica à prevista pelo projetista";
			System.out.println("Both workflows are identical");
			return comparingWorkflowsAssessment;
		}
		
		if (isWorkflowsIdentical == false) {
			//using domain ontology to verify different steps
			checkingIfDifferentMaterialsHaveSimilarOnesInTheDomainOntology();
		}
		
		
		//Printing the different steps after use the domain ontology to verify similar materials
		System.out.println();
		System.out.println("Após a avaliação dos passos executados através do auxílio da ontologia de domínio, seguem os passos que permanecem incorretos");
		comparingWorkflowsAssessment = comparingWorkflowsAssessment + "\n\nApós a avaliação dos passos executados através do auxílio da ontologia de domínio, seguem os passos que permanecem incorretos";
		if (differentStepsList.size() == 0) {
			System.out.println("NENHUM");
			comparingWorkflowsAssessment = comparingWorkflowsAssessment + "\nNENHUM";
		}
		for (int i=0; i < differentStepsList.size(); i++) {
			System.out.println("--> " + differentStepsList.get(i));
			comparingWorkflowsAssessment = comparingWorkflowsAssessment + "\n--> " + differentStepsList.get(i);
		}
		System.out.println();
		comparingWorkflowsAssessment = comparingWorkflowsAssessment + "\n";
		
		//comparing different steps using the application ontology after using domain ontology
		if (differentStepsList.size() != 0)
			checkingDifferentStepsUsingApplicationOntology();
			
		
		return comparingWorkflowsAssessment;
		
	}
	
	/*
	 * Comparing the authorship and execution workflows. Comparing if the structure is identical.
	 * It will return true if both lists are identical. It will set the variable differentStepsList with all execution  
	 * workflow's stepIds wich are different from the authorship workflow.  
	 * This comparison analises just the content, i.e. the step's materials. As the StepId and Description are  
	 * personal, they aren't compared.  
	 * In this version, just workflows with the same number of steps are compared. For the further versions, workflows
	 * with different number of steps must be compared.
	 */
	protected boolean isAuthorshipAndExecutionWorkflowsIndentical() throws RuntimeException{
		System.out.println("VERIFICANDO OS PASSOS DIFERENTES");
		System.out.println("================================");
		System.out.println();
		comparingWorkflowsAssessment = comparingWorkflowsAssessment + "\nVERIFICANDO OS PASSOS DIFERENTES\n================================\n\n";
		
		if (authorshipStepListOrdened == null) {
			throw new NullPointerException("Please, run readAuthorshipXPDL method first");
		}
		
		if (executionStepListOrdened == null) {
			throw new NullPointerException("Please, run readExecutionXPDL method first"); 
		}
		
		//First, verify if both workflows have the same size
		if (authorshipStepListOrdened.size() != executionStepListOrdened.size()) {
			throw new IncompatibleSizeException("The workflows have different sizes, so they are differents");
		}

		//Verifying if each position from executionStepList is equal to the correspondent position from authorShipStepList
		for (int i=0; i < executionStepListOrdened.size();i++) {
			if (executionStepListOrdened.get(i).getMaterials().containsAll(authorshipStepListOrdened.get(i).getMaterials()) &&
					authorshipStepListOrdened.get(i).getMaterials().containsAll(executionStepListOrdened.get(i).getMaterials())) { 
			//if (!executionStepListOrdened.get(i).getMaterials().retainAll(authorshipStepListOrdened.get(i).getMaterials())) {
				System.out.println("OK --> " + executionStepListOrdened.get(i).getId());
				comparingWorkflowsAssessment = comparingWorkflowsAssessment + "\nOK --> " + executionStepListOrdened.get(i).getId();
			} else {
				//System.out.println("FALSE --------> " + executionStepListOrdened.get(i).getId());
				System.out.println("Passo diferente encontrado: " + executionStepListOrdened.get(i).getId());
				comparingWorkflowsAssessment = comparingWorkflowsAssessment + "\nPasso diferente encontrado: " + executionStepListOrdened.get(i).getId();
				if (differentStepsList == null) {
					differentStepsList = new ArrayList<String>();
				}
				differentStepsList.add(executionStepListOrdened.get(i).getId());
			}
		}
		
		if (differentStepsList == null)
			return true;
		
		return false;
		
		
	}

	/*
	 * This method will check if the different steps referenced in the differentStepsList variable has some similar material in the ontology
	 * If there is, this method will delete the differentStepsList's records. So it will rest only the steps which has not similarity with
	 * another material. Finishing to perform this method, check the variable differentStepsList to see if rest some different step
	 * MISSING: it is missing to check if the step which has a similar material found, has the same properties that the original has.
	 */
	protected void checkingIfDifferentMaterialsHaveSimilarOnesInTheDomainOntology() throws Exception {
		//comecar verificando se há passos diferentes.
		if (differentStepsList == null)
			return;
		
		System.out.println();
		System.out.println("VERIFICANDO SE OS PASSOS DIFERENTES POSSUEM MATERIAIS SIMILARES NA ONTOLOGIA DE DOMINIO");
		System.out.println("=======================================================================================");
		comparingWorkflowsAssessment = comparingWorkflowsAssessment + "\n\nVERIFICANDO SE OS PASSOS DIFERENTES POSSUEM MATERIAIS SIMILARES NA ONTOLOGIA DE DOMINIO\n";
		comparingWorkflowsAssessment = comparingWorkflowsAssessment + "=======================================================================================\n";
		
		
		List<String> differentStepsListToBeDeleted = null;
		
		//creating 2 variables which I will set a flag in each situation where I found a different material
		List<MaterialWrapper> authorshipDifferentStepMaterials;
		List<MaterialWrapper> executionDifferentStepMaterials;
		
		for (int i=0; i < differentStepsList.size(); i++) {
			System.out.println();
			System.out.println("Passo diferente: " + differentStepsList.get(i));
			comparingWorkflowsAssessment = comparingWorkflowsAssessment + "\nPasso diferente: " + differentStepsList.get(i)+ "\n";
			Step differentStep = getStepFromListByStepId(executionStepListOrdened, differentStepsList.get(i));
			
			//if the different step from the authorship and execution has different number of materials, so it cant be analised 
			if (getStepFromListByStepId(authorshipStepListOrdened, differentStep.getId()).getMaterials().size() != getStepFromListByStepId(executionStepListOrdened, differentStep.getId()).getMaterials().size()) {
				System.out.println("Este passo possui um número diferente de aparatos em relação aos propostos pelo projetista, \n" +
						"logo, não será utilizada a ontologia de domínio para analisar este passo");
				comparingWorkflowsAssessment = comparingWorkflowsAssessment + "Este passo possui um número diferente de aparatos em relação aos propostos pelo projetista, \n" +
				"logo, não será utilizada a ontologia de domínio para analisar este passo";
				//throw new Exception("The differentStep has a different number os materials from the same authorship workflow step. So it cant be compared");
			} else {
			

				authorshipDifferentStepMaterials = new ArrayList<MaterialWrapper>();
				executionDifferentStepMaterials = new ArrayList<MaterialWrapper>();
				//Filling out both variables with the current different step
				for (int x=0; x < getStepFromListByStepId(authorshipStepListOrdened, differentStep.getId()).getMaterials().size(); x++) {
					authorshipDifferentStepMaterials.add(new MaterialWrapper(getStepFromListByStepId(authorshipStepListOrdened, differentStep.getId()).getMaterials().get(x)));
				}				
				for (int y=0; y < getStepFromListByStepId(executionStepListOrdened, differentStep.getId()).getMaterials().size(); y++) {
					executionDifferentStepMaterials.add(new MaterialWrapper(getStepFromListByStepId(executionStepListOrdened, differentStep.getId()).getMaterials().get(y)));
				}
	
				//for each material found on the other variable, set it as verified:true. So, it will rest just the different materials
				for (int x=0; x < authorshipDifferentStepMaterials.size(); x++) {
					for (int y=0; y < executionDifferentStepMaterials.size(); y++) {
						if (authorshipDifferentStepMaterials.get(x).getMaterial().getOntologyReference().equals(executionDifferentStepMaterials.get(y).getMaterial().getOntologyReference())) {
						//if (authorshipDifferentStepMaterials.get(x).getMaterial().equals(executionDifferentStepMaterials.get(y).getMaterial())) {
							authorshipDifferentStepMaterials.get(x).setVerified(true);
							executionDifferentStepMaterials.get(y).setVerified(true);
							
							if ( 	authorshipDifferentStepMaterials.get(x).getMaterial().getProperties() != null &&
									executionDifferentStepMaterials.get(y).getMaterial().getProperties() != null &&
									!(authorshipDifferentStepMaterials.get(x).getMaterial().getProperties().containsAll(executionDifferentStepMaterials.get(y).getMaterial().getProperties()) &&
											executionDifferentStepMaterials.get(y).getMaterial().getProperties().containsAll(authorshipDifferentStepMaterials.get(x).getMaterial().getProperties())) ) {
								System.out.println("Materiais idênticos utilizados neste passo, no entanto com propriedades configuradas de formas diferentes. Passo incorreto.");
								comparingWorkflowsAssessment = comparingWorkflowsAssessment + "Materiais idênticos utilizados neste passo, no entanto com propriedades configuradas de formas diferentes. Passo incorreto.\n";
								authorshipDifferentStepMaterials.get(x).setVerified(false);
								executionDifferentStepMaterials.get(y).setVerified(false);
							}
						}
					}
				}
				
				
				//Selecting just the non verified materials to check on the domain ontology if they are similar between each other
				for (int x=0; x < authorshipDifferentStepMaterials.size(); x++) {
					for (int y=0; y < executionDifferentStepMaterials.size(); y++) {
						if (authorshipDifferentStepMaterials.get(x).isVerified() == false && executionDifferentStepMaterials.get(y).isVerified() == false) {
	
							List<Material> similarMaterials = OntologyMethodsBean.getInstance().doGetInstancesSimilarTo(authorshipDifferentStepMaterials.get(x).getMaterial());
							
							//if the different material is a similar material, so it is right.. setting the variable verified as true
							if (similarMaterials != null)
								for (int a=0; a < similarMaterials.size(); a++) {
									if (similarMaterials.get(a).getOntologyReference().equals(executionDifferentStepMaterials.get(y).getMaterial().getOntologyReference())) { 

										authorshipDifferentStepMaterials.get(x).setVerified(true);
										executionDifferentStepMaterials.get(y).setVerified(true);
										System.out.println("Material utilizado (nao esperado): " + similarMaterials.get(a).getOntologyReference());
										System.out.println("Material esperado................: " + authorshipDifferentStepMaterials.get(x).getMaterial().getOntologyReference());
										System.out.println("O material utilizado é similar ao previsto pelo projetista!");
										comparingWorkflowsAssessment = comparingWorkflowsAssessment + "Material utilizado (nao esperado): " + similarMaterials.get(a).getOntologyReference();
										comparingWorkflowsAssessment = comparingWorkflowsAssessment + "\nMaterial esperado................: " + authorshipDifferentStepMaterials.get(x).getMaterial().getOntologyReference();
										comparingWorkflowsAssessment = comparingWorkflowsAssessment + "\nO material utilizado é similar ao previsto pelo projetista!\n";
										
										//PRECISO VERIFICAR AS PROPRIEDADES AQUI TAMBÉM. NAO ESQUECER DE VERIFICAR SE SAO NULL
										
										if ( 	authorshipDifferentStepMaterials.get(x).getMaterial().getProperties() != null &&
												executionDifferentStepMaterials.get(y).getMaterial().getProperties() != null &&
												!(authorshipDifferentStepMaterials.get(x).getMaterial().getProperties().containsAll(executionDifferentStepMaterials.get(y).getMaterial().getProperties()) &&
														executionDifferentStepMaterials.get(y).getMaterial().getProperties().containsAll(authorshipDifferentStepMaterials.get(x).getMaterial().getProperties())) ) {
											System.out.println("Materiais idênticos utilizados neste passo, no entanto com propriedades configuradas de formas diferentes. Passo incorreto.");
											comparingWorkflowsAssessment = comparingWorkflowsAssessment + "\nMateriais idênticos utilizados neste passo, no entanto com propriedades configuradas de formas diferentes. Passo incorreto.\n";
											authorshipDifferentStepMaterials.get(x).setVerified(false);
											executionDifferentStepMaterials.get(y).setVerified(false);
										}
										
										
/*										if ( (authorshipDifferentStepMaterials.get(x).getMaterial().getProperties() != null &&
												executionDifferentStepMaterials.get(y).getMaterial().getProperties() != null &&
												!authorshipDifferentStepMaterials.get(x).getMaterial().getProperties().equals(executionDifferentStepMaterials.get(y).getMaterial().getProperties())) ||
												
												(authorshipDifferentStepMaterials.get(x).getMaterial().getProperties() == null &&
												executionDifferentStepMaterials.get(y).getMaterial().getProperties() == null) ) {
											
											System.out.println("Embora os materiais estejam corretos, suas propriedades não condizem com o proposto na autoria. Este passso encontra-se parcialmente incorreto.\nSerá utilizada ontologia de aplicação para avaliar se mesmo com propriedades diferentes, o passo está correto!");
											authorshipDifferentStepMaterials.get(x).setVerified(false);
											executionDifferentStepMaterials.get(y).setVerified(false);
										}*/
										
									}
								}
						}
					}
				}	
				
				
				//verifying if there is no variable verified=false. If dont, so it is necessary to delete this step from the differentStepsList
				//variable, because it was verified that it is similiar
				boolean isThereDifferentMaterial = false;
				for (int x=0; x < authorshipDifferentStepMaterials.size(); x++)
					if (authorshipDifferentStepMaterials.get(x).isVerified() == false)
						isThereDifferentMaterial = true;
				
				for (int y=0; y < executionDifferentStepMaterials.size(); y++)
					if (executionDifferentStepMaterials.get(y).isVerified() == false)
						isThereDifferentMaterial = true;
				

				
				
				
				//VERIFICAR SE O PASSO ESTÁ COM TODAS AS FLAGS COMO TRUE. SE SIM, AINDA RESTA VERIFICAR AS SUAS PROPRIEDADES E VALORES, PARA VER
				//SE O PROPOSTO NA AUTORIA ESTÁ IGUAL O DA EXECUCAO. CASO ESTEJAM DIFERENTES, MANTER ESSE PASSO COMO INCORRETO PARA QUE ELE
				//VÁ PARA O TESTE COM A ONTOLOGIA DE APLICACAO.
				//SE NAO, ACHO QUE NAO PRECISO ME PREOCUPAR, PQ ELE VAI SER TESTADO PELA ONTOLOGIA DE APLICACAO DE QUALQUER JEITO
				//****** POSSO SABER SE SOBROU ALGUM MATERIAL INCORRETO VERIFICANDO O VALOR DA VARIAVEL "isThereDifferentMaterial"

				
				//Verifing if there is no different material. If the materials are equal, so it is still necessary to verify if all the 
				//properties are similar as well
/*				boolean isThereJustDifferentPropertyValues = false;
				if (isThereDifferentMaterial == false)
					for (int x=0; x < authorshipDifferentStepMaterials.size(); x++) {
						for (int y=0; y < executionDifferentStepMaterials.size(); y++) {
							if (authorshipDifferentStepMaterials.get(x).getMaterial().equals(executionDifferentStepMaterials.get(y).getMaterial())) {
								//System.out.println("Passo contem os mesmos aparatos, porem utiliza valores diferentes do previsto em suas propriedades.");
								isThereJustDifferentPropertyValues = true;
								
								if (differentStepsListToBeDeleted == null) 
									differentStepsListToBeDeleted = new ArrayList<String>();
								
								if (similarOrEqualStepListButWithDifferentPropertiesValues == null)
									similarOrEqualStepListButWithDifferentPropertiesValues = new ArrayList<String>();
								
								differentStepsListToBeDeleted.add(differentStepsList.get(i));
								System.out.println("Este passo utiliza aparatos idênticos ou similares ao previsto pelo projetista, no entanto \n" +
										"os valores de suas propriedades não condizem com os propostos no workflow de autoria. O mesmo não será \n" +
										"verificado na ontologia de aplicação. Este passo encontra-se incorreto.");
								similarOrEqualStepListButWithDifferentPropertiesValues.add(differentStepsList.get(i));
								break;
							}
						}
					}*/
				
				
				

				//if (isThereJustDifferentPropertyValues == false) {
					//if (isThereDifferentMaterial == true)
						//System.out.println("Não há referências similares para os materiais utilizados neste passo. Passo permanece diferente do esperado!");
		
					if (isThereDifferentMaterial == false && differentStepsListToBeDeleted == null) 
						differentStepsListToBeDeleted = new ArrayList<String>();
					
					if (isThereDifferentMaterial == false )
						differentStepsListToBeDeleted.add(differentStepsList.get(i));
				//}
			} //else	
		}
		//now, after set verified=true for the elements which the domain ontology inference "said" that the materials were similar,
		//it is necessary to delete these elements in the variable differentStepsList
		if (differentStepsListToBeDeleted != null) {
			for (int k=0; k < differentStepsListToBeDeleted.size(); k++) {
				differentStepsList.remove(differentStepsListToBeDeleted.get(k));
			}
		}
		
		
	}
	
	@SuppressWarnings("unchecked")
	/*
	 * This method verifies if the steps from the execution workflow and that are different from the authorship workflow are
	 * identical, through the inferences over the application ontology. This inference can found id there are alternative
	 * steps represented on the application ontology and that can be used in the same step.
	 */
	private void checkingDifferentStepsUsingApplicationOntology() {
		//It will be used to get the application ontology step reference (URI)
		String stepOntologyReference = null;
		
		//each step that is wrong and that needs to be compared with the application ontology
		Step differentExecutionStep = new Step();
		
		//All alternative steps to the step that is wrong.
		List<Step> alternativeSteps = new ArrayList<Step>();
		
		System.out.println("VERIFICANDO SE PASSOS QUE PERMANECEM INCORRETOS POSSUEM REFERENCIA ALTERNATIVA NA ONTOLOGIA DE APLICACAO");
		System.out.println("========================================================================================================");
		comparingWorkflowsAssessment = comparingWorkflowsAssessment + "\nVERIFICANDO SE PASSOS QUE PERMANECEM INCORRETOS POSSUEM REFERENCIA ALTERNATIVA NA ONTOLOGIA DE APLICACAO";
		comparingWorkflowsAssessment = comparingWorkflowsAssessment + "\n========================================================================================================\n";
		
		List<String> stepsToBeDeleted = null;
		for (int i=0; i< differentStepsList.size(); i++) {
			
			System.out.println("Passo a ser verificado: " + differentStepsList.get(i));
			comparingWorkflowsAssessment = comparingWorkflowsAssessment + "\n\nPasso a ser verificado: " + differentStepsList.get(i);

			//getting the step URI in the application ontology. Thus, it can be possible to get the alternative steps
			for (int x=0; x < authorshipStepListOrdened.size(); x++) {
				if (authorshipStepListOrdened.get(x).getId().equals(differentStepsList.get(i))) {
					stepOntologyReference = authorshipStepListOrdened.get(x).getApplicationOntologyReference();
					System.out.println("Referencia na ontologia de aplicacao: " + stepOntologyReference);
					comparingWorkflowsAssessment = comparingWorkflowsAssessment + "\nReferencia na ontologia de aplicacao: " + stepOntologyReference;
					break;
				}
			}

			//getting the step that was executed differently from the authorship step
			for (int x=0; x < executionStepListOrdened.size(); x++) {
				if (executionStepListOrdened.get(x).getId().equals(differentStepsList.get(i))) {
					differentExecutionStep = executionStepListOrdened.get(x);
					break;
				}
			}

			List<Task> similarTasks = OntologyMethodsBean.getInstance().aoGetTasksSimilarTo(stepOntologyReference);
			for (int q=0; q < similarTasks.size(); q++) {
				alternativeSteps.add(new Step(similarTasks.get(q)));
			}
			
			boolean foundAlternativeStep = false;
			for (int j=0; j < alternativeSteps.size(); j++) {
				if (alternativeSteps.get(j).getMaterials().containsAll(differentExecutionStep.getMaterials()) && 
						differentExecutionStep.getMaterials().containsAll(alternativeSteps.get(j).getMaterials())) {
					//If found a alternative step that match with the step executed differently from the authorship, so it is necessary
					//to delete this step from the differentStepList variable
					System.out.println("---> Encontrado passo alternativo na ontologia de aplicação! Este passo encontra-se CORRETO.\n");
					comparingWorkflowsAssessment = comparingWorkflowsAssessment + "\n---> Encontrado passo alternativo na ontologia de aplicação! Este passo encontra-se CORRETO.";
					
					if (stepsToBeDeleted == null)
						stepsToBeDeleted = new ArrayList<String>();
					
					stepsToBeDeleted.add(differentStepsList.get(i));
					foundAlternativeStep = true;
					break;
				}
			}
			
			if (foundAlternativeStep == false) {
				System.out.println("---> Não foi encontrado passo alternativo");
				comparingWorkflowsAssessment = comparingWorkflowsAssessment + "\n---> Não foi encontrado passo alternativo";
			}

		}
		
		if (stepsToBeDeleted != null)
			for (int i=0; i < stepsToBeDeleted.size(); i++) {
				differentStepsList.remove(stepsToBeDeleted.get(i));
			}
		
		System.out.println();
		System.out.println("AVALIAÇÃO FINAL");
		System.out.println("===============");
		System.out.println("Após a verificação de passos alternativos com auxílio da ontologia de aplicação, seguem os passos que permanecem incorretos");
		
		comparingWorkflowsAssessment = comparingWorkflowsAssessment + "\n\nAVALIAÇÃO FINAL\n===============\n";
		comparingWorkflowsAssessment = comparingWorkflowsAssessment + "\nApós a verificação de passos alternativos com auxílio da ontologia de aplicação, seguem os passos que permanecem incorretos\n";
		
		if (differentStepsList.size() == 0) {
			System.out.println("NENHUM");
			comparingWorkflowsAssessment = comparingWorkflowsAssessment + "\nNENHUM\n";
		} else { 
			for (int k=0; k < differentStepsList.size(); k++) {
				System.out.println(differentStepsList.get(k));
				comparingWorkflowsAssessment = comparingWorkflowsAssessment + "\n" + differentStepsList.get(k);  
			}
		}
		System.out.println();
		comparingWorkflowsAssessment = comparingWorkflowsAssessment + "\n";

		
		
	}
	//**************Comparing workflows
	
	
	
	/* 
	 * @param material Material that you want to get all features/configurations (if there is)
	 * This method returns all properties from a material
	 */
	private List<Element> getMaterialProperties(Element material) {
		List<Element> allFeaturesList = material.selectNodes(material.getUniquePath() + "/xpdl:ExtendedAttribute");
		List<Element> featureList = null;
		
		for (int i=0; i < allFeaturesList.size(); i++) {
			//System.out.println(((Element) allExtendedAttributeList.get(i)).attributeValue("Name"));
			
			if (featureList == null)
				featureList = new ArrayList<Element>();
			
			featureList.add(allFeaturesList.get(i));
		}

		return featureList;		
	}
	/* 
	 * @param activity 	The activity (step) that you want to get all materials
	 * This method returns all materials from an activity (step)
	 */
	private List<Element> getActivityMaterials(Element activity) { 
		
		List<Element> allExtendedAttributeList = activity.selectNodes(activity.getUniquePath() + "/xpdl:ExtendedAttributes/xpdl:ExtendedAttribute");
		List<Element> materialList = null;
		
		for (int i=0; i < allExtendedAttributeList.size(); i++) {
			//System.out.println(((Element) allExtendedAttributeList.get(i)).attributeValue("Name"));
			
			if (materialList == null)
				materialList = new ArrayList<Element>();
			
			if (((Element) allExtendedAttributeList.get(i)).attributeValue("Name").equals("Material")) {
					materialList.add(allExtendedAttributeList.get(i));
				}
		}

		return materialList;
	}
	
	/* 
	 * @param activity 	The activity (step) that you want to get the application ontology reference
	 * This method returns application ontology reference from an activity (step)
	 */
	private String getApplicationOntologyReference(Element activity) { 
		
		List<Element> allExtendedAttributeList = activity.selectNodes(activity.getUniquePath() + "/xpdl:ExtendedAttributes/xpdl:ExtendedAttribute");
		
		for (int i=0; i < allExtendedAttributeList.size(); i++) {
			if (((Element) allExtendedAttributeList.get(i)).attributeValue("Name").equals("ApplicationOntologyReference")) {
				System.out.println("Referência na Ontologia de aplicação: " + allExtendedAttributeList.get(i).attributeValue("Value"));
				return allExtendedAttributeList.get(i).attributeValue("Value");
			}
		}

		return null;
	}

	/*
	 * @param list The list that you want to get the step
	 * @param stepId The stepId which will be use as the key to return the step from the list
	 * Get a Step from a List<Step>, based on the stepId passed as parameter
	 */
	private Step getStepFromListByStepId(List<Step> list, String stepId) {
		for (int i=0; i < list.size(); i++) {
			if (list.get(i).getId().equals(stepId))
				return list.get(i);
		}
		return null;
	}
	
	/*
	 * Return the XPDL string from an specific file
	 * @param xpdlPath Path to a XPDL file in the file system
	 */
	private String getXPDLStringFromFile(String xpdlPath) throws Exception {
		StringBuilder contents = new StringBuilder();
	    
	    try {
	      BufferedReader input =  new BufferedReader(new FileReader(new File(xpdlPath)));
	      String line = null;
	      while (( line = input.readLine()) != null){
	    	  contents.append(line);
	          //contents.append(System.getProperty("line.separator"));
	          
	      }
	    }catch (IOException ex){
	      throw new Exception(ex.getMessage());
	    }
	    return contents.toString();
	}
	
	/*
	 * This method save a file on the file system
	 * @param path It is a path where the file will be saved
	 * @param content It is a string that will be saved in a file
	 */
	private void saveFile(String path, String content) throws Exception {
	    
	    try {
	        FileWriter fstream = new FileWriter(path);
	        BufferedWriter out = new BufferedWriter(fstream);
	        out.write(content);
	        out.close();
	    	
	    }catch (IOException ex){
	      throw new Exception(ex.getMessage());
	    }

	}
	
	
	
	
	//*************************** Creating Authorship and Execution Workflows ******************************
	
	/*
	 * It creates the XPDL authorship workflow string and save it on the hard disk
	 * @param experiment The experiment object which will be read and written in a XPDL file 
	 * @param xpdlFilePath Path where the XPDL file will be created (on the file system)
	 */
	protected void creatingAuthorshipWorkflow(Experiment experiment, String xpdlFilePath) {
		
		if (experiment == null) {
			System.out.println("Experiment is null");
			return;
		}
		
		String xpdlAuthorship = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> \n"
		+ "<xpdl:Package xmlns:xpdl=\"http://www.wfmc.org/2002/XPDL1.0\" xmlns=\"http://www.wfmc.org/2002/XPDL1.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" Id=\"MyPackage_id\" Name=\"MyPackage_name\" xsi:schemaLocation=\"http://www.wfmc.org/2002/XPDL1.0 http://wfmc.org/standards/docs/TC-1025_schema_10_xpdl.xsd\"> \n"
		+ "<xpdl:PackageHeader> \n"
		+ "\t<xpdl:XPDLVersion>1.0</xpdl:XPDLVersion> \n"
		+ "</xpdl:PackageHeader> \n"
		+ "<xpdl:WorkflowProcesses> \n\n"
		+ "\t<xpdl:WorkflowProcess Id=\"" + experiment.getExperimentId() + "\" Name=\"" + experiment.getName() + "\"> \n"
		+ "\t\t<xpdl:Description>" + experiment.getDescription() + "</xpdl:Description> \n"
		+ "\t\t<xpdl:Activities> \n";
		
		//Step
		for (int i=0; i < experiment.getStepList().size(); i++) {
			xpdlAuthorship = xpdlAuthorship
			+ "\t\t\t<xpdl:Activity Id=\"Step_" + (i+1) + "\"> \n"
			+ "\t\t\t\t<xpdl:Description>" + experiment.getStepList().get(i).getDescription() + "</xpdl:Description> \n"
			+ "\t\t\t\t<xpdl:ExtendedAttributes> \n\n";
			
			//Its Materials
			for (int j=0; j < experiment.getStepList().get(i).getMaterials().size(); j++) {
				xpdlAuthorship = xpdlAuthorship
				+ "\t\t\t\t\t<xpdl:ExtendedAttribute Name=\"Material\" Value=\"" + experiment.getStepList().get(i).getMaterials().get(j).getOntologyReference() + "\">";
				
				//Its Properties
				if (experiment.getStepList().get(i).getMaterials().get(j).getProperties() != null) {
					for (int k=0; k < experiment.getStepList().get(i).getMaterials().get(j).getProperties().size(); k++) {
						xpdlAuthorship = xpdlAuthorship
						+ "\n \t\t\t\t\t\t<xpdl:ExtendedAttribute Name=\"" +  experiment.getStepList().get(i).getMaterials().get(j).getProperties().get(k).getPropertyOntologyReference() + "\" Value=\"" + experiment.getStepList().get(i).getMaterials().get(j).getProperties().get(k).getValue() + "\"/>";
					}
					xpdlAuthorship = xpdlAuthorship
					+ "\n\t\t\t\t\t";
				} 
				
				xpdlAuthorship = xpdlAuthorship
				+ "\t</xpdl:ExtendedAttribute> \n\n";
				
			}

			xpdlAuthorship = xpdlAuthorship
			+ "\t\t\t\t\t<xpdl:ExtendedAttribute Name=\"ApplicationOntologyReference\" Value=\"" + experiment.getStepList().get(i).getApplicationOntologyReference() + "\"/> \n\n"
			+ "\t\t\t\t</xpdl:ExtendedAttributes> \n"
			+ "\t\t\t</xpdl:Activity> \n\n";
		}
		
		xpdlAuthorship = xpdlAuthorship
		+ "\t\t</xpdl:Activities> \n\n" 
		+ "\t\t<xpdl:Transitions>";
		
		for (int i=0; i < (experiment.getStepList().size()-1); i++) {
			xpdlAuthorship = xpdlAuthorship
			+ "\n\t\t\t<xpdl:Transition From=\"" + experiment.getStepList().get(i).getId() + "\" Id=\"MyProcess_" + experiment.getStepList().get(i).getId() + "\" To=\"" + experiment.getStepList().get(i+1).getId() + "\" /> ";
		}
		
		xpdlAuthorship = xpdlAuthorship
		+ "\n\t\t</xpdl:Transitions> \n\n"
		+ "\t\t<xpdl:ExtendedAttributes> \n"
		+ "\t\t\t<xpdl:ExtendedAttribute Name=\"StartEvent\" Value=\"" + experiment.getStepList().get(0).getId() + "\"/> \n" 
		+ "\t\t\t<xpdl:ExtendedAttribute Name=\"EndEvent\" Value=\"" + experiment.getStepList().get((experiment.getStepList().size()-1)).getId() + "\"/> \n"
		
		+ "\t\t</xpdl:ExtendedAttributes> \n\n"
		+ "\t</xpdl:WorkflowProcess> \n"
		+ "</xpdl:WorkflowProcesses> \n"
		+ "</xpdl:Package>";
		
		System.out.println(xpdlAuthorship);
		
		try {
			saveFile(xpdlFilePath, xpdlAuthorship);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
	}
	
	/*
	 * It creates the XPDL execution workflow string and save it on the hard disk
	 * @param experiment The experiment object which will be read and written in a XPDL file 
	 * @param xpdlFilePath Path where the XPDL file will be created (on the file system)
	 */
	protected void creatingExecutionWorkflow(Experiment experiment, String xpdlFilePath) {
		
		if (experiment == null) {
			System.out.println("Experiment is null");
			return;
		}
		
		String xpdlAuthorship = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> \n"
		+ "<xpdl:Package xmlns:xpdl=\"http://www.wfmc.org/2002/XPDL1.0\" xmlns=\"http://www.wfmc.org/2002/XPDL1.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" Id=\"MyPackage_id\" Name=\"MyPackage_name\" xsi:schemaLocation=\"http://www.wfmc.org/2002/XPDL1.0 http://wfmc.org/standards/docs/TC-1025_schema_10_xpdl.xsd\"> \n"
		+ "<xpdl:PackageHeader> \n"
		+ "\t<xpdl:XPDLVersion>1.0</xpdl:XPDLVersion> \n"
		+ "</xpdl:PackageHeader> \n"
		+ "<xpdl:WorkflowProcesses> \n\n"
		+ "\t<xpdl:WorkflowProcess Id=\"" + experiment.getExperimentId() + "\" Name=\"" + experiment.getName() + "\"> \n"
		+ "\t\t<xpdl:Description>" + experiment.getDescription() + "</xpdl:Description> \n"
		+ "\t\t<xpdl:Activities> \n";
		
		//Step
		for (int i=0; i < experiment.getStepList().size(); i++) {
			xpdlAuthorship = xpdlAuthorship
			+ "\t\t\t<xpdl:Activity Id=\"Step_" + (i+1) + "\"> \n"
			+ "\t\t\t\t<xpdl:Description>" + experiment.getStepList().get(i).getDescription() + "</xpdl:Description> \n"
			+ "\t\t\t\t<xpdl:ExtendedAttributes> \n\n";
			
			//Its Materials
			for (int j=0; j < experiment.getStepList().get(i).getMaterials().size(); j++) {
				xpdlAuthorship = xpdlAuthorship
				+ "\t\t\t\t\t<xpdl:ExtendedAttribute Name=\"Material\" Value=\"" + experiment.getStepList().get(i).getMaterials().get(j).getOntologyReference() + "\">";
				
				//Its Properties
				if (experiment.getStepList().get(i).getMaterials().get(j).getProperties() != null) {
					for (int k=0; k < experiment.getStepList().get(i).getMaterials().get(j).getProperties().size(); k++) {
						xpdlAuthorship = xpdlAuthorship
						+ "\n \t\t\t\t\t\t<xpdl:ExtendedAttribute Name=\"" +  experiment.getStepList().get(i).getMaterials().get(j).getProperties().get(k).getPropertyOntologyReference() + "\" Value=\"" + experiment.getStepList().get(i).getMaterials().get(j).getProperties().get(k).getValue() + "\"/>";
					}
					xpdlAuthorship = xpdlAuthorship
					+ "\n\t\t\t\t\t";
				} 
				
				xpdlAuthorship = xpdlAuthorship
				+ "\t</xpdl:ExtendedAttribute> \n\n";
				
			}

			xpdlAuthorship = xpdlAuthorship
			+ "\t\t\t\t</xpdl:ExtendedAttributes> \n"
			+ "\t\t\t</xpdl:Activity> \n\n";
		}
		
		xpdlAuthorship = xpdlAuthorship
		+ "\t\t</xpdl:Activities> \n\n" 
		+ "\t\t<xpdl:Transitions>";
		
		for (int i=0; i < (experiment.getStepList().size()-1); i++) {
			xpdlAuthorship = xpdlAuthorship
			+ "\n\t\t\t<xpdl:Transition From=\"" + experiment.getStepList().get(i).getId() + "\" Id=\"MyProcess_" + experiment.getStepList().get(i).getId() + "\" To=\"" + experiment.getStepList().get(i+1).getId() + "\" /> ";
		}
		
		xpdlAuthorship = xpdlAuthorship
		+ "\n\t\t</xpdl:Transitions> \n\n"
		+ "\t\t<xpdl:ExtendedAttributes> \n"
		+ "\t\t\t<xpdl:ExtendedAttribute Name=\"StartEvent\" Value=\"" + experiment.getStepList().get(0).getId() + "\"/> \n" 
		+ "\t\t\t<xpdl:ExtendedAttribute Name=\"EndEvent\" Value=\"" + experiment.getStepList().get((experiment.getStepList().size()-1)).getId() + "\"/> \n"
		
		+ "\t\t</xpdl:ExtendedAttributes> \n\n"
		+ "\t</xpdl:WorkflowProcess> \n"
		+ "</xpdl:WorkflowProcesses> \n"
		+ "</xpdl:Package>";
		
		System.out.println(xpdlAuthorship);
		
		try {
			saveFile(xpdlFilePath, xpdlAuthorship);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
	}

 
}
