/**
 *  Copyright (c)2020 CEA LIST, Committer Name, and others.
 * 
 *  All rights reserved. This program and the accompanying materials
 *  are made available under the terms of the Eclipse Public License 2.0
 *  which accompanies this distribution, and is available at
 *  https://www.eclipse.org/legal/epl-2.0/
 * 
 *  SPDX-License-Identifier: EPL-2.0
 * 
 *  Contributors:
 *  CEA LIST - Initial API and implementation
 *  Gabriel Pedroza (CEA LIST) gabriel.pedroza@cea.fr
 * 
 */
package org.eclipse.papyrus.pdp4eng.designer.processstrategies.command;

import java.util.Iterator;

import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.transaction.RecordingCommand;
import org.eclipse.emf.transaction.TransactionalEditingDomain;

import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.window.Window;
import org.eclipse.papyrus.pdp4eng.designer.controller.api.*;
import org.eclipse.papyrus.pdp4eng.designer.controller.internal.processcreation.ProcessBuilder;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.swt.widgets.Display;

import org.eclipse.uml2.uml.Action;
import org.eclipse.uml2.uml.Activity;
import org.eclipse.uml2.uml.ActivityEdge;
import org.eclipse.uml2.uml.ActivityNode;
import org.eclipse.uml2.uml.ActivityParameterNode;
import org.eclipse.uml2.uml.CallBehaviorAction;
import org.eclipse.uml2.uml.Classifier;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.InputPin;
import org.eclipse.uml2.uml.NamedElement;
import org.eclipse.uml2.uml.ObjectFlow;
import org.eclipse.uml2.uml.OutputPin;
import org.eclipse.uml2.uml.Package;
import org.eclipse.uml2.uml.PackageableElement;
import org.eclipse.uml2.uml.Pin;
import org.eclipse.uml2.uml.Profile;
import org.eclipse.uml2.uml.ProfileApplication;
import org.eclipse.uml2.uml.Stereotype;
import org.eclipse.uml2.uml.Type;
import org.eclipse.uml2.uml.UMLFactory;
import org.eclipse.uml2.uml.UMLPackage;
import org.eclipse.uml2.uml.util.UMLUtil;
import org.eclipse.ui.dialogs.ElementListSelectionDialog;

import org.eclipse.papyrus.pdp4eng.designer.profile.pdp4engDesign.CallProcess;
import org.eclipse.papyrus.pdp4eng.designer.profile.pdp4engDesign.Entity;
import org.eclipse.papyrus.pdp4eng.designer.profile.pdp4engDesign.ExternalEntity;
import org.eclipse.papyrus.pdp4eng.designer.utils.ModelPackageNames;
import org.eclipse.papyrus.pdp4eng.designer.utils.ModelProfileNames;
import org.eclipse.papyrus.pdp4eng.common.profile.pdp4engCommonGDPR.Consent;
import org.eclipse.papyrus.pdp4eng.common.profile.pdp4engCommonGDPR.Controller;
import org.eclipse.papyrus.pdp4eng.common.profile.pdp4engCommonGDPR.DataSubject;
import org.eclipse.papyrus.pdp4eng.common.profile.pdp4engCommonGDPR.PersonalData;
import org.eclipse.papyrus.pdp4eng.common.profile.pdp4engCommonGDPR.Processor;
import org.eclipse.papyrus.pdp4eng.common.profile.pdp4engCommonGDPR.Purpose;
import org.eclipse.papyrus.pdp4eng.common.profile.pdp4engCommonGDPR.Process;

public class InstantiateGDPRConsentPatternCommand extends RecordingCommand {

	protected Activity activityDFD;

	public InstantiateGDPRConsentPatternCommand(TransactionalEditingDomain domain, Activity activityDFD) {
		super(domain, "Instantiate a Consent Pattern based upon the information provided by the engineer");
		this.activityDFD = activityDFD;
	}

	@Override
	protected void doExecute() {

		String title = "1. Consent Pattern - Select the Controller";
		String message = "1. Select the Controller responsible for processing Personal Data";
		ExternalEntity selectedController = selectExternalEntityFromActivityDFD(title,message);
		Entity controllerEntity = createEntity(selectedController.getBase_ActivityParameterNode().getName());
		Entity processorEntity = createEntity(selectedController.getBase_ActivityParameterNode().getName()+"_Processor");
		applyStereotypeToNamedElement(controllerEntity.getBase_NamedElement(), ModelProfileNames.commonGDPRProfileName, ModelProfileNames.commonGDPR_Controller);
		applyStereotypeToNamedElement(processorEntity.getBase_NamedElement(), ModelProfileNames.commonGDPRProfileName, ModelProfileNames.commonGDPR_Processor);
		selectedController.setEntity(controllerEntity);

		title = "2. Consent Pattern - Select the Data Subject";
		message = "2. Select the Data Subject to ask for Consent";
		ExternalEntity selectedDataSubject = selectExternalEntityFromActivityDFD(title, message);
		Entity dataSubjectEntity = createEntity(selectedDataSubject.getBase_ActivityParameterNode().getName());
		applyStereotypeToNamedElement(dataSubjectEntity.getBase_NamedElement(), ModelProfileNames.commonGDPRProfileName, ModelProfileNames.commonGDPR_DataSubject);
		selectedDataSubject.setEntity(dataSubjectEntity);

		title = "3. Consent Pattern - Select the Process";
		message = "3. Select the Process concerned by the Consent";
		CallProcess selectedCallProcess = selectCallProcessFromActivityDFD(title, message);
		applyStereotypeToAction(selectedCallProcess.getBase_CallBehaviorAction(), ModelProfileNames.commonGDPRProfileName, ModelProfileNames.commonGDPR_Process);

		title = "4. Consent Pattern - Declare the Purpose";
		message = "4. Declare the Purpose for which Data is processed";
		InputDialog dialog = new InputDialog(Display.getCurrent().getActiveShell(),
				title, message, "", null);
		dialog.open();
		String purposeTxt = dialog.getValue();
		Purpose purpose = createPurpose(purposeTxt);

		title = "5. Consent Pattern - Select the Personal Data";
		message = "5. Select the Personal Data involved in "+ selectedCallProcess.getBase_CallBehaviorAction().getName();
		PersonalData selectedPersonalData = selectPersonalDataFromActivityDFD(title, message);

		/** Start to instantiate the Consent Pattern by completing and filling the model **/

		/** 1st. Controller (and Processor) **/
		Controller controller = getController(controllerEntity.getBase_NamedElement());
		Processor processor = getProcessor(processorEntity.getBase_NamedElement());

		if ((controller!=null) && (processor!=null) && (selectedPersonalData!=null)) {
			controller.getPersonalData().add(selectedPersonalData);
			controller.getProcessor().add(processor);
		}

		/** 2nd. Data Subject and Consent **/

		Consent consent = createConsent("Consent("+selectedPersonalData.getBase_NamedElement().getName()+"_"+purpose.getBase_NamedElement().getName()+")");
		DataSubject dataSubject = getDataSubject(dataSubjectEntity.getBase_NamedElement());

		if (dataSubject!=null && selectedPersonalData!=null && consent!=null) {	
			dataSubject.getPersonalData().add(selectedPersonalData);
			dataSubject.getGivenConsent().add(consent);
		}


		/** 3rd. Process **/
		Process process = getProcess(selectedCallProcess.getBase_CallBehaviorAction());
		if (process!=null) {
			processor.getProcess().add(process);
			process.getPersonaldata().add(selectedPersonalData);
		}

		/** 4th. Purpose **/ 
		if (process!=null && consent!=null) {
			purpose.getProcesses().add(process);
			purpose.setConsent(consent);
		}

		/** INSTANTIATE THE CONSENT PATTERN **/

		/** Create a CallProcess **/
		Activity newProcess= UMLFactory.eINSTANCE.createActivity();
		String consentName = "GDPRConsent_"+process.getBase_NamedElement().getName();
		newProcess.setName(consentName);
		Package DFDL1_Pkg = this.activityDFD.getModel().getNestedPackage(ModelPackageNames.DFD_L1_PackageName);
		if (DFDL1_Pkg!=null && newProcess!=null) {
			//System.err.printf(DFDL1_Pkg.toString()+"\n\n\n");
			//System.err.printf(newProcess.toString()+"\n\n\n");
			DFDL1_Pkg.getPackagedElements().add(newProcess);
			CallBehaviorAction consentCallBehaviorAction=UMLFactory.eINSTANCE.createCallBehaviorAction();
			activityDFD.getOwnedNodes().add(consentCallBehaviorAction);
			consentCallBehaviorAction.setName("GDPRConsent_"+process.getBase_NamedElement().getName());
			consentCallBehaviorAction.setBehavior(newProcess);
			applyStereotypeToAction(consentCallBehaviorAction, ModelProfileNames.PDPbDProfileName, ModelProfileNames.PDPbD_CallProcess);

			/** Add DataInput and DataOutput pins **/
			InputPin inPin = UMLFactory.eINSTANCE.createInputPin();
			OutputPin outPin = UMLFactory.eINSTANCE.createOutputPin();
			if (inPin != null && outPin!=null) {
				inPin.setType((Type) consent.getBase_NamedElement());
				outPin.setType((Type) consent.getBase_NamedElement());
				inPin.setName("InputPin1");
				outPin.setName("OutputPin2");
				consentCallBehaviorAction.getArguments().add(inPin);
				consentCallBehaviorAction.getResults().add(outPin);
				applyStereotypeToPin(inPin, ModelProfileNames.PDPbDProfileName, ModelProfileNames.PDPbD_DataInput);
				applyStereotypeToPin(outPin, ModelProfileNames.PDPbDProfileName, ModelProfileNames.PDPbD_DataOutput);

				/** Connect DataSubject entity to the DataInput pin **/
				ObjectFlow dataFlowEdge1 = UMLFactory.eINSTANCE.createObjectFlow();
				if (dataFlowEdge1 !=null) {
					dataFlowEdge1.setName("Consent_"+selectedDataSubject.getBase_ActivityParameterNode().getName());
					dataFlowEdge1.setSource(selectedDataSubject.getBase_ActivityParameterNode());
					dataFlowEdge1.setTarget(inPin);
					activityDFD.getEdges().add(dataFlowEdge1);

					/** Connect DataOutput pin to Controller entity **/
					ObjectFlow dataFlowEdge2 = UMLFactory.eINSTANCE.createObjectFlow();
					if (dataFlowEdge2!=null) {
						dataFlowEdge2.setName("Consent_"+selectedController.getBase_ActivityParameterNode().getName());
						dataFlowEdge2.setSource(outPin);
						dataFlowEdge2.setTarget(selectedController.getBase_ActivityParameterNode());
						activityDFD.getEdges().add(dataFlowEdge2);

						/** Completing Behavior Process **/
						ActivityParameterNode parameterIn=UMLFactory.eINSTANCE.createActivityParameterNode();
						if (parameterIn!=null) {
							parameterIn.setName(inPin.getName());
							parameterIn.setType(inPin.getType());
							newProcess.getOwnedNodes().add(parameterIn);	
						}

						ActivityParameterNode parameterOut=UMLFactory.eINSTANCE.createActivityParameterNode();
						if (parameterOut!=null) {
							parameterOut.setName(outPin.getName());
							parameterOut.setType(outPin.getType());
							newProcess.getOwnedNodes().add(parameterOut);	
						}
					}
				}
			}	
		}
	}


	/**
	 * Verify whether the needed profiles have been already loaded in the model
	 * @param profileList
	 * @return
	 */
	public boolean verifyProfilesApplied(EList<Profile> profileList) {
		boolean found = false; 
		int noProfiles = 0;
		for (Iterator<Profile> profileListIt = profileList.iterator(); profileListIt.hasNext() && noProfiles!=2;) {
			Profile profile = profileListIt.next();
			if (profile!=null) {
				String profileName = profile.getName(); 
				switch (profileName) {
				case "pdp4engDesign": 
					noProfiles++;
					break;

				case "pdp4engCommonGDPR":
					noProfiles++;
					break;

				}
			}
		}
		if (noProfiles==2) {
			found=true;
		}
		return found;
	}

	/**
	 * Return the profile with the given name or null elsewhere
	 * @param profileName
	 * @return
	 */
	public Profile getProfile(String profileName) {
		Profile profile = null;
		for (ProfileApplication profileApplication : this.activityDFD.getModel().getProfileApplications()) {
			profile = profileApplication.getAppliedProfile();
			if (profile.getName().equals(profileName)){
				return profile;
			}
		}
		return profile;
	}

	/**
	 * Create a Package with the given name.
	 * @param packageName
	 */
	public void createIfMissingPackage(String packageName){
		PackageableElement targetPackage = this.activityDFD.getModel().getPackagedElement(packageName);
		if (targetPackage==null || !targetPackage.getName().equals(packageName)){
			this.activityDFD.getModel().createPackagedElement(packageName, UMLPackage.eINSTANCE.getPackage());
		}
	}


	/**
	 * Shows all the Call Process associated to an Activity DFD. Returns the CallProcess selected by the user.
	 * @return
	 */
	CallProcess selectCallProcessFromActivityDFD(String title, String message) {
		CallProcess selectedCallProcess  = null;
		EList<Action> selectedCallProcList = new BasicEList<Action>();
		EList<Profile> profileList = this.activityDFD.getModel().getAppliedProfiles();
		if (verifyProfilesApplied(profileList)) {
			Profile PDPbDprofile = getProfile(ModelProfileNames.PDPbDProfileName);
			EList<Element> elementList = this.activityDFD.getNearestPackage().allOwnedElements();
			if (elementList!=null && PDPbDprofile!=null) {
				for (Iterator<Element> elementListIt = elementList.iterator(); elementListIt.hasNext();) {
					Element element = elementListIt.next();
					EList<Stereotype> elementStypesList = element.getAppliedStereotypes();
					for (Iterator<Stereotype> elementStypeListIt = elementStypesList.iterator(); elementStypeListIt.hasNext();) {
						Stereotype stype = elementStypeListIt.next();
						if (stype!=null && stype.getName().equals(ModelProfileNames.PDPbD_CallProcess)) {
							if (element instanceof org.eclipse.uml2.uml.Action) {
								Action actionElmt = (Action) element;
								System.out.printf("CallProcess Name: "+actionElmt.getName()+"\n");
								if (!selectedCallProcList.contains(actionElmt)) {
									selectedCallProcList.add(actionElmt);	
								}	
							}
						}	
					}
				}
			}
		}

		Object[] objList = new Object[selectedCallProcList.size()];
		Iterator<Action> selectedElementListIt = selectedCallProcList.iterator();
		for  (int i=0; selectedElementListIt.hasNext()&& i<objList.length; i++) {
			Action callProc = selectedElementListIt.next();
			objList[i] = callProc.getName();
		}

		ElementListSelectionDialog dialog = new ElementListSelectionDialog(Display.getCurrent().getActiveShell(), new LabelProvider()); 
		dialog.setElements(objList);
		dialog.setTitle(title);
		dialog.setMessage(message);
		dialog.setHelpAvailable(true);

		if (dialog.open() != Window.OK) {
			System.out.printf(">> A problem opening the CallProcess Window");
		}

		Object[] resultList = dialog.getResult();
		if (resultList!=null && resultList.length>0) {
			Object result = resultList[0];
			for  (Iterator<Action> selectedElementListIt1 = selectedCallProcList.iterator(); selectedElementListIt1.hasNext();) {
				Action callProc = selectedElementListIt1.next();
				if (callProc.getName().equals(result)){
					selectedCallProcess = UMLUtil.getStereotypeApplication(callProc,CallProcess.class) ;
				}
			}
		}
		return selectedCallProcess;
	}

	/**
	 * Shows all the External Entities associated to an Activity DFD. Returns the ExternalEntity selected by the user.
	 * @return
	 */
	ExternalEntity selectExternalEntityFromActivityDFD(String title, String message) {
		ExternalEntity selectedEEntity  = null;
		EList<ActivityParameterNode> selectedEEntityList = new BasicEList<ActivityParameterNode>();
		EList<Profile> profileList = this.activityDFD.getModel().getAppliedProfiles();
		if (verifyProfilesApplied(profileList)) {
			Profile PDPbDprofile = getProfile(ModelProfileNames.PDPbDProfileName);
			EList<Element> elementList = this.activityDFD.getNearestPackage().allOwnedElements();
			if (elementList!=null && PDPbDprofile!=null) {
				for (Iterator<Element> elementListIt = elementList.iterator(); elementListIt.hasNext();) {
					Element element = elementListIt.next();
					EList<Stereotype> elementStypesList = element.getAppliedStereotypes();
					for (Iterator<Stereotype> elementStypeListIt = elementStypesList.iterator(); elementStypeListIt.hasNext();) {
						Stereotype stype = elementStypeListIt.next();
						if (stype!=null && stype.getName().equals(ModelProfileNames.PDPbD_ExternalEntity)) {
							if (element instanceof org.eclipse.uml2.uml.ActivityParameterNode) {
								ActivityParameterNode activityParameterNodeElmt = (ActivityParameterNode) element;
								System.out.printf("ExternalEntity Name: "+activityParameterNodeElmt.getName()+"\n");
								if (!selectedEEntityList.contains(activityParameterNodeElmt)) {
									selectedEEntityList.add(activityParameterNodeElmt);	
								}	
							}
						}	
					}
				}
			}
		}

		Object[] objList = new Object[selectedEEntityList.size()];
		Iterator<ActivityParameterNode> selectedEEntityListIt = selectedEEntityList.iterator();
		for  (int i=0; selectedEEntityListIt.hasNext()&& i<objList.length; i++) {
			ActivityParameterNode extEntity = selectedEEntityListIt.next();
			objList[i] = extEntity.getName();
		}

		ElementListSelectionDialog dialog = new ElementListSelectionDialog(Display.getCurrent().getActiveShell(), new LabelProvider()); 
		dialog.setElements(objList);
		dialog.setTitle(title);
		dialog.setMessage(message);
		dialog.setHelpAvailable(true);

		if (dialog.open() != Window.OK) {
			System.out.printf(">> A problem opening the ExternalEntity Window");
		}

		Object[] resultList = dialog.getResult();
		if (resultList!=null && resultList.length>0) {
			Object result = resultList[0];
			for  (Iterator<ActivityParameterNode> selectedEEntityListIt1 = selectedEEntityList.iterator(); selectedEEntityListIt1.hasNext();) {
				ActivityParameterNode activityParamNode = selectedEEntityListIt1.next();
				if (activityParamNode.getName().equals(result)){
					selectedEEntity = UMLUtil.getStereotypeApplication(activityParamNode,ExternalEntity.class);
				}
			}
		}
		return selectedEEntity;
	}

	/**
	 * hows all the Data associated to an Activity DFD. Stereotypes the selected Data as Personal and returns them.
	 * @param title
	 * @param message
	 * @return
	 */
	PersonalData selectPersonalDataFromActivityDFD(String title, String message) {
		PersonalData selectedPersonalData  = null;
		EList<Classifier> selectedPersonalDataList = new BasicEList<Classifier>();
		EList<Profile> profileList = this.activityDFD.getModel().getAppliedProfiles();
		if (verifyProfilesApplied(profileList)) {
			Profile PDPbDprofile = getProfile(ModelProfileNames.PDPbDProfileName);
			EList<Element> elementList = this.activityDFD.getModel().getNestedPackage(ModelPackageNames.Data_PackageName).allOwnedElements();
			if (elementList!=null && PDPbDprofile!=null) {
				for (Iterator<Element> elementListIt = elementList.iterator(); elementListIt.hasNext();) {
					Element element = elementListIt.next();
					EList<Stereotype> elementStypesList = element.getAppliedStereotypes();
					for (Iterator<Stereotype> elementStypeListIt = elementStypesList.iterator(); elementStypeListIt.hasNext();) {
						Stereotype stype = elementStypeListIt.next();
						if (stype!=null && stype.getName().equals(ModelProfileNames.commonGDPR_PersonalData)) {
							if (element instanceof org.eclipse.uml2.uml.Classifier) {
								Classifier classElmt = (Classifier) element;
								System.out.printf("PersonalData Name: "+classElmt.getName()+"\n");
								if (!selectedPersonalDataList.contains(classElmt)) {
									selectedPersonalDataList.add(classElmt);	
								}	
							}
						}	
					}
				}
			}
		}

		Object[] objList = new Object[selectedPersonalDataList.size()];
		Iterator<Classifier> selectedPersonalDataListIt = selectedPersonalDataList.iterator();
		for  (int i=0; selectedPersonalDataListIt.hasNext()&& i<objList.length; i++) {
			Classifier extEntity = selectedPersonalDataListIt.next();
			objList[i] = extEntity.getName();
		}

		ElementListSelectionDialog dialog = new ElementListSelectionDialog(Display.getCurrent().getActiveShell(), new LabelProvider()); 
		dialog.setElements(objList);
		dialog.setTitle(title);
		dialog.setMessage(message);
		dialog.setHelpAvailable(true);

		if (dialog.open() != Window.OK) {
			System.out.printf(">> A problem opening the PersonalData Window");
		}

		Object[] resultList = dialog.getResult();
		if (resultList!=null && resultList.length>0) {
			Object result = resultList[0];
			for  (Iterator<Classifier> selectedPersonalDataListIt1 = selectedPersonalDataList.iterator(); selectedPersonalDataListIt1.hasNext();) {
				Classifier activityParamNode = selectedPersonalDataListIt1.next();
				if (activityParamNode.getName().equals(result)){
					selectedPersonalData = UMLUtil.getStereotypeApplication(activityParamNode,PersonalData.class);
				}
			}
		}
		return selectedPersonalData;
	}

	/**
	 * Create a Purpose with the given name within the Stakeholders package
	 * @param name
	 * @return
	 */
	Purpose createPurpose(String name) {
		Purpose purpose = null;
		createIfMissingPackage(ModelPackageNames.Stakeholder_PackageName);
		Classifier purposeCls = this.activityDFD.getModel().getNestedPackage(ModelPackageNames.Stakeholder_PackageName).
				createOwnedClass(name, false);
		EList<Profile> profileList = this.activityDFD.getModel().getAppliedProfiles();
		if (verifyProfilesApplied(profileList)) {
			Profile commonProfile = getProfile(ModelProfileNames.commonGDPRProfileName);
			if (commonProfile!=null){
				Stereotype purposeStype = commonProfile.getOwnedStereotype(ModelProfileNames.commonGDPR_Purpose);
				if (purposeStype!=null){
					UMLUtil.safeApplyStereotype(purposeCls, purposeStype);
					purpose = UMLUtil.getStereotypeApplication(purposeCls, Purpose.class);
				}
			}
		}
		return purpose;
	}

	/**
	 * Create an Entity with the given name within the Stakeholders package
	 * @param name
	 * @return
	 */
	Entity createEntity(String name) {
		Entity entity = null;
		createIfMissingPackage(ModelPackageNames.Stakeholder_PackageName);
		Classifier entityCls = this.activityDFD.getModel().getNestedPackage(ModelPackageNames.Stakeholder_PackageName).
				createOwnedClass(name, false);
		EList<Profile> profileList = this.activityDFD.getModel().getAppliedProfiles();
		if (verifyProfilesApplied(profileList)) {
			Profile commonProfile = getProfile(ModelProfileNames.PDPbDProfileName);
			if (commonProfile!=null){
				Stereotype entityStype = commonProfile.getOwnedStereotype(ModelProfileNames.PDPbD_Entity);
				if (entityStype!=null){
					UMLUtil.safeApplyStereotype(entityCls, entityStype);
					entity = UMLUtil.getStereotypeApplication(entityCls, Entity.class);
				}
			}
		}
		return entity;
	}

	/**
	 * Create a Consent with the given name within the Data package
	 * @param name
	 * @return
	 */
	Consent createConsent(String name) {
		Consent consent = null;
		createIfMissingPackage(ModelPackageNames.Data_PackageName);
		Classifier entityCls = this.activityDFD.getModel().getNestedPackage(ModelPackageNames.Data_PackageName).
				createOwnedClass(name, false);
		EList<Profile> profileList = this.activityDFD.getModel().getAppliedProfiles();
		if (verifyProfilesApplied(profileList)) {
			Profile commonProfile = getProfile(ModelProfileNames.commonGDPRProfileName);
			if (commonProfile!=null){
				Stereotype entityStype = commonProfile.getOwnedStereotype(ModelProfileNames.commonGDPR_Consent);
				if (entityStype!=null){
					UMLUtil.safeApplyStereotype(entityCls, entityStype);
					consent = UMLUtil.getStereotypeApplication(entityCls, Consent.class);
				}
			}
		}
		return consent;
	}

	/**
	 * Get the controller of an Entity
	 * @param entityCls
	 * @return
	 */
	Controller getController(NamedElement entityCls) {
		Controller controller = null;
		EList<Profile> profileList = this.activityDFD.getModel().getAppliedProfiles();
		if (verifyProfilesApplied(profileList)) {
			Profile commonProfile = getProfile(ModelProfileNames.commonGDPRProfileName);
			if (commonProfile!=null){
				Stereotype entityStype = commonProfile.getOwnedStereotype(ModelProfileNames.commonGDPR_Controller);
				if (entityStype!=null){
					UMLUtil.safeApplyStereotype(entityCls, entityStype);
					controller = UMLUtil.getStereotypeApplication(entityCls, Controller.class);
				}
			}
		}
		return controller;
	}

	/**
	 * Get the processor of an Entity
	 * @param entityCls
	 * @return
	 */
	Processor getProcessor(NamedElement entityCls) {
		Processor processor = null;
		EList<Profile> profileList = this.activityDFD.getModel().getAppliedProfiles();
		if (verifyProfilesApplied(profileList)) {
			Profile commonProfile = getProfile(ModelProfileNames.commonGDPRProfileName);
			if (commonProfile!=null){
				Stereotype entityStype = commonProfile.getOwnedStereotype(ModelProfileNames.commonGDPR_Processor);
				if (entityStype!=null){
					UMLUtil.safeApplyStereotype(entityCls, entityStype);
					processor = UMLUtil.getStereotypeApplication(entityCls, Processor.class);
				}
			}
		}
		return processor;
	}

	/**
	 * Get the Data Subject of an Entity
	 * @param entityCls
	 * @return
	 */
	DataSubject getDataSubject(NamedElement entityCls) {
		DataSubject dataSubject = null;
		EList<Profile> profileList = this.activityDFD.getModel().getAppliedProfiles();
		if (verifyProfilesApplied(profileList)) {
			Profile commonProfile = getProfile(ModelProfileNames.commonGDPRProfileName);
			if (commonProfile!=null){
				Stereotype entityStype = commonProfile.getOwnedStereotype(ModelProfileNames.commonGDPR_DataSubject);
				if (entityStype!=null){
					UMLUtil.safeApplyStereotype(entityCls, entityStype);
					dataSubject = UMLUtil.getStereotypeApplication(entityCls, DataSubject.class);
				}
			}
		}
		return dataSubject;
	}

	/**
	 * Get the process of a CallBehaviorAction
	 * @param entityCls
	 * @return
	 */
	Process getProcess(CallBehaviorAction callBehaviorAction) {
		Process process = null;
		EList<Profile> profileList = this.activityDFD.getModel().getAppliedProfiles();
		if (verifyProfilesApplied(profileList)) {
			Profile commonProfile = getProfile(ModelProfileNames.commonGDPRProfileName);
			if (commonProfile!=null){
				Stereotype entityStype = commonProfile.getOwnedStereotype(ModelProfileNames.commonGDPR_Process);
				if (entityStype!=null){
					UMLUtil.safeApplyStereotype(callBehaviorAction, entityStype);
					process = UMLUtil.getStereotypeApplication(callBehaviorAction, Process.class);
				}
			}
		}
		return process;
	}

	/**
	 * Safely apply the a stereotype to an ActivityParameterNode
	 * @param classifier
	 * @param stereotype
	 */
	public void applyStereotypeToActivityParameterNode(ActivityParameterNode activityPNode, String profileName, String stereotypeName) {
		EList<Profile> profileList = this.activityDFD.getModel().getAppliedProfiles();
		EList<Stereotype> appliedStypes = activityPNode.getAppliedStereotypes();
		if (verifyProfilesApplied(profileList) && profileName!=null && stereotypeName!=null && activityPNode!=null) {
			Profile profile = getProfile(profileName);
			if (profile!=null){
				Stereotype stereotype = profile.getOwnedStereotype(stereotypeName);
				if (stereotype!=null && !appliedStypes.contains(stereotype)){
					UMLUtil.safeApplyStereotype(activityPNode, stereotype);
				}
			}
		}
	}

	/**
	 * Safely apply the a stereotype to a Classifier
	 * @param classifier
	 * @param profileName
	 * @param stereotypeName
	 */
	public void applyStereotypeToClassifier(Classifier classifier, String profileName, String stereotypeName) {
		EList<Profile> profileList = this.activityDFD.getModel().getAppliedProfiles();
		EList<Stereotype> appliedStypes = classifier.getAppliedStereotypes();
		if (verifyProfilesApplied(profileList) && profileName!=null && stereotypeName!=null && classifier!=null) {
			Profile profile = getProfile(profileName);
			if (profile!=null){
				Stereotype stereotype = profile.getOwnedStereotype(stereotypeName);
				if (stereotype!=null && !appliedStypes.contains(stereotype)){
					UMLUtil.safeApplyStereotype(classifier, stereotype);
				}
			}
		}
	}

	/**
	 * Safely apply the a stereotype to a NamedElement
	 * @param namedElement
	 * @param profileName
	 * @param stereotypeName
	 */
	public void applyStereotypeToNamedElement(NamedElement namedElement, String profileName, String stereotypeName) {
		EList<Profile> profileList = this.activityDFD.getModel().getAppliedProfiles();
		EList<Stereotype> appliedStypes = namedElement.getAppliedStereotypes();
		if (verifyProfilesApplied(profileList) && profileName!=null && stereotypeName!=null && namedElement!=null) {
			Profile profile = getProfile(profileName);
			if (profile!=null){
				Stereotype stereotype = profile.getOwnedStereotype(stereotypeName);
				if (stereotype!=null && !appliedStypes.contains(stereotype)){
					UMLUtil.safeApplyStereotype(namedElement, stereotype);
				}
			}
		}
	}

	/**
	 * Safely apply the a stereotype to an Action node
	 * @param action
	 * @param profileName
	 * @param stereotypeName
	 */
	public void applyStereotypeToAction(Action action, String profileName, String stereotypeName) {
		EList<Profile> profileList = this.activityDFD.getModel().getAppliedProfiles();
		EList<Stereotype> appliedStypes = action.getAppliedStereotypes();
		if (verifyProfilesApplied(profileList) && profileName!=null && stereotypeName!=null && action!=null) {
			Profile profile = getProfile(profileName);
			if (profile!=null){
				Stereotype stereotype = profile.getOwnedStereotype(stereotypeName);
				if (stereotype!=null && !appliedStypes.contains(stereotype)){
					UMLUtil.safeApplyStereotype(action, stereotype);
				}
			}
		}
	}

	public void applyStereotypeToPin(Pin pin, String profileName, String stereotypeName) {
		EList<Profile> profileList = this.activityDFD.getModel().getAppliedProfiles();
		EList<Stereotype> appliedStypes = pin.getAppliedStereotypes();
		if (verifyProfilesApplied(profileList) && profileName!=null && stereotypeName!=null && pin!=null) {
			Profile profile = getProfile(profileName);
			if (profile!=null){
				Stereotype stereotype = profile.getOwnedStereotype(stereotypeName);
				if (stereotype!=null && !appliedStypes.contains(stereotype)){
					UMLUtil.safeApplyStereotype(pin, stereotype);
				}
			}
		}
	}
}
