/*
 *                                                                            
 *  Copyright (c) 2011 - 2017 - Loetz GmbH & Co KG, 69115 Heidelberg, Germany 
 *                                                                            
 *  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                                 
 *                                                                            
 *  Initial contribution:                                                      
 *     Loetz GmbH & Co. KG                              
 * 
 */
package org.eclipse.osbp.vaaclipse.addons.softwarefactory.perspective;

import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;
import javax.inject.Named;

import org.eclipse.bpmn2.Bpmn2Package;
import org.eclipse.bpmn2.Process;
import org.eclipse.bpmn2.Task;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.core.di.annotations.Optional;
import org.eclipse.e4.core.services.events.IEventBroker;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.e4.ui.model.application.ui.MElementContainer;
import org.eclipse.e4.ui.model.application.ui.MUIElement;
import org.eclipse.e4.ui.model.application.ui.advanced.MAdvancedFactory;
import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective;
import org.eclipse.e4.ui.model.application.ui.advanced.MPerspectiveStack;
import org.eclipse.e4.ui.model.application.ui.advanced.MPlaceholder;
import org.eclipse.e4.ui.model.application.ui.advanced.impl.AdvancedFactoryImpl;
import org.eclipse.e4.ui.model.application.ui.advanced.impl.AdvancedPackageImpl;
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
import org.eclipse.e4.ui.model.application.ui.basic.MPartSashContainer;
import org.eclipse.e4.ui.model.application.ui.basic.MPartSashContainerElement;
import org.eclipse.e4.ui.model.application.ui.basic.MPartStack;
import org.eclipse.e4.ui.model.application.ui.basic.MStackElement;
import org.eclipse.e4.ui.model.application.ui.basic.MTrimmedWindow;
import org.eclipse.e4.ui.model.application.ui.basic.MWindowElement;
import org.eclipse.e4.ui.model.application.ui.basic.impl.BasicFactoryImpl;
import org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl;
import org.eclipse.e4.ui.model.application.ui.impl.UiPackageImpl;
import org.eclipse.e4.ui.workbench.modeling.EModelService;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.osbp.bpm.api.BPMOperation;
import org.eclipse.osbp.bpm.api.BPMTaskClientPerspectiveListener;
import org.eclipse.osbp.bpm.api.BPMTaskEventType;
import org.eclipse.osbp.bpm.api.BPMTaskSummary;
import org.eclipse.osbp.bpm.api.BPMTaskUserEvent;
import org.eclipse.osbp.bpm.api.IBPMTaskClient;
import org.eclipse.osbp.bpm.api.IBPMTaskEventNotification;
import org.eclipse.osbp.bpm.api.IBlipBPMConstants;
import org.eclipse.osbp.bpm.api.IBlipBPMFunctionProvider;
import org.eclipse.osbp.bpm.api.IBlipBPMStartInfo;
import org.eclipse.osbp.bpm.api.IBlipBPMWorkloadModifiableItem;
import org.eclipse.osbp.dsl.common.datatypes.IDto;
import org.eclipse.osbp.ecview.core.extension.model.extension.ExtensionModelPackage;
import org.eclipse.osbp.eventbroker.EventBrokerMsg;
import org.eclipse.osbp.preferences.ProductConfiguration;
import org.eclipse.osbp.runtime.common.event.EventDispatcherEvent;
import org.eclipse.osbp.runtime.common.event.EventDispatcherEvent.EventDispatcherCommand;
import org.eclipse.osbp.runtime.common.event.EventDispatcherEvent.EventDispatcherDataTag;
import org.eclipse.osbp.runtime.common.event.IEventDispatcher;
import org.eclipse.osbp.ui.api.metadata.IDSLMetadataService;
import org.eclipse.osbp.ui.api.organization.IOrganizationViewPartProvider;
import org.eclipse.osbp.ui.api.perspective.IPerspectiveProvider;
import org.eclipse.osbp.ui.api.themes.IThemeResourceService;
import org.eclipse.osbp.ui.api.themes.IThemeResourceService.ThemeResourceType;
import org.eclipse.osbp.ui.api.user.IUser;
import org.eclipse.osbp.ui.api.useraccess.IUserAccessService;
import org.eclipse.osbp.utils.vaadin.bpmn.BpmnView;
import org.eclipse.osbp.utils.vaadin.saiku.SaikuView;
import org.eclipse.osbp.vaaclipse.addons.softwarefactory.maintoolbar.IMainToolbarProvider;
import org.eclipse.osbp.vaaclipse.addons.softwarefactory.welcome.WelcomeView;
import org.eclipse.osbp.vaaclipse.publicapi.authentication.AuthenticationConstants;
import org.eclipse.osbp.vaadin.emf.api.IModelingContext;
import org.eclipse.osbp.xtext.action.ActionDSLPackage;
import org.eclipse.osbp.xtext.action.ActionToolbar;
import org.eclipse.osbp.xtext.action.TaskActionEnum;
import org.eclipse.osbp.xtext.blip.BlipItem;
import org.eclipse.osbp.xtext.blip.BlipUserTask;
import org.eclipse.osbp.xtext.chart.Chart;
import org.eclipse.osbp.xtext.chart.ChartDSLPackage;
import org.eclipse.osbp.xtext.chart.ChartPackage;
import org.eclipse.osbp.xtext.datainterchange.DataDSLPackage;
import org.eclipse.osbp.xtext.datainterchange.DataInterchangeGroup;
import org.eclipse.osbp.xtext.datainterchange.DataInterchangePackage;
import org.eclipse.osbp.xtext.dialogdsl.Dialog;
import org.eclipse.osbp.xtext.dialogdsl.DialogDSLPackage;
import org.eclipse.osbp.xtext.dialogdsl.DialogPackage;
import org.eclipse.osbp.xtext.organizationdsl.Organization;
import org.eclipse.osbp.xtext.organizationdsl.OrganizationDSLPackage;
import org.eclipse.osbp.xtext.organizationdsl.OrganizationPackage;
import org.eclipse.osbp.xtext.perspective.Perspective;
import org.eclipse.osbp.xtext.perspective.PerspectiveBPMN;
import org.eclipse.osbp.xtext.perspective.PerspectiveBrowser;
import org.eclipse.osbp.xtext.perspective.PerspectiveChart;
import org.eclipse.osbp.xtext.perspective.PerspectiveDataInterchange;
import org.eclipse.osbp.xtext.perspective.PerspectiveDialog;
import org.eclipse.osbp.xtext.perspective.PerspectiveDslPackage;
import org.eclipse.osbp.xtext.perspective.PerspectiveElement;
import org.eclipse.osbp.xtext.perspective.PerspectiveEvent;
import org.eclipse.osbp.xtext.perspective.PerspectiveGrid;
import org.eclipse.osbp.xtext.perspective.PerspectiveKanban;
import org.eclipse.osbp.xtext.perspective.PerspectiveOrganization;
import org.eclipse.osbp.xtext.perspective.PerspectivePackage;
import org.eclipse.osbp.xtext.perspective.PerspectivePart;
import org.eclipse.osbp.xtext.perspective.PerspectivePartStack;
import org.eclipse.osbp.xtext.perspective.PerspectiveReport;
import org.eclipse.osbp.xtext.perspective.PerspectiveSaiku;
import org.eclipse.osbp.xtext.perspective.PerspectiveSashContainer;
import org.eclipse.osbp.xtext.perspective.PerspectiveSearch;
import org.eclipse.osbp.xtext.perspective.PerspectiveSelection;
import org.eclipse.osbp.xtext.perspective.PerspectiveTable;
import org.eclipse.osbp.xtext.perspective.PerspectiveTopology;
import org.eclipse.osbp.xtext.perspective.PerspectiveView;
import org.eclipse.osbp.xtext.perspective.PerspectiveWelcome;
import org.eclipse.osbp.xtext.reportdsl.Report;
import org.eclipse.osbp.xtext.reportdsl.ReportDSLPackage;
import org.eclipse.osbp.xtext.reportdsl.ReportPackage;
import org.eclipse.osbp.xtext.table.Table;
import org.eclipse.osbp.xtext.table.TableDSLPackage;
import org.eclipse.osbp.xtext.table.TablePackage;
import org.eclipse.osbp.xtext.topologydsl.Topology;
import org.eclipse.osbp.xtext.topologydsl.TopologyDSLPackage;
import org.eclipse.osbp.xtext.topologydsl.TopologyPackage;
import org.osgi.framework.Bundle;
import org.osgi.framework.FrameworkUtil;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.vaadin.server.Page;

/**
 * The Class PerspectiveProvider. Available as injectable service to create and
 * maintain perspectives coming from the perspective DSL model.
 */
@SuppressWarnings("restriction")
public class PerspectiveProvider implements IPerspectiveProvider, IBPMTaskEventNotification, IEventDispatcher.Receiver,
		BPMTaskClientPerspectiveListener {

	/** The log. */
	private static Logger log = LoggerFactory.getLogger(PerspectiveProvider.class);

	/** The event broker. */
	@Inject
	private IEventBroker eventBroker;
	
	/** The app model. */
	@Inject
	private MApplication appModel;

	/** The eclipse context. */
	@Inject
	private IEclipseContext eclipseContext;

	@Inject
	private IModelingContext modelingContext;

	/** The theme resource service. */
	@Inject
	private IThemeResourceService themeResourceService;

	/** The current user. */
	@Inject
	private IUser user;

	/** The task client. */
	@Inject
	@Optional
	private IBPMTaskClient taskClient;

	/** The task provider */
	@Inject
	@Optional
	private IBlipBPMFunctionProvider taskProvider;

	/** The dsl metadata service. */
	@Inject
	private IDSLMetadataService dslMetadataService;

	/** The toolbar provider. */
	@Inject
	@Named("MainToolbar")
	private IMainToolbarProvider toolbarProvider;

	/** The optional org URI provider. */
	@Inject
	@Optional
	private IOrganizationViewPartProvider optionalOrgURIProvider;

	/** The event dispatcher. */
	@Inject
	private IEventDispatcher eventDispatcher;

	/** The do logout. */
	private EventHandler doLogout;

	/** The trimmed window. */
	private MTrimmedWindow trimmedWindow = null;

	/** The model service. */
	private EModelService modelService;

	/** The perspectives. */
	private Map<String, MPerspective> perspectives = new HashMap<>();

	/** The perspective tasks. */
	private Map<BPMTaskSummary, String> perspectiveTasks = new HashMap<>();

	@Inject
	private IUserAccessService userAccessService;

	/**
	 * Inits the PerspectiveSupport.
	 */
	@PostConstruct
	protected void init() {
		perspectives.clear();
		perspectiveTasks.clear();
		modelService = eclipseContext.get(EModelService.class);
		eventDispatcher.addEventReceiver(this);
		subscribe();
	}

	/**
	 * Inits the perspective stack.
	 *
	 * @return the current perspective stack or null
	 */
	private MPerspectiveStack initPerspectiveStack() {
		log.trace("{}","analyze app model");
		trimmedWindow = (MTrimmedWindow) appModel.getChildren().get(0);
		for (MWindowElement element : trimmedWindow.getChildren()) {
			if (element instanceof MPerspectiveStack) {
				return addToolbarAdapter((MPerspectiveStack) element);
			}
		}
		return null;
	}

	private MPerspectiveStack addToolbarAdapter(MPerspectiveStack stack) {
		// handle toolbar
		((EObject) stack).eAdapters().add(new AdapterImpl() {
			@Override
			public void notifyChanged(Notification notification) {
				if (notification.getEventType() == Notification.SET && notification.getFeatureID(
						MElementContainer.class) == AdvancedPackageImpl.PERSPECTIVE_STACK__SELECTED_ELEMENT) {
					log.trace("{}","perspective stack changed selection");
					if (notification.getNewValue() == null && notification.getOldValue() != null && PerspectiveProvider
							.isPerspectiveElementId(((MPerspective) notification.getOldValue()).getElementId())) {
						closePerspective(PerspectiveProvider
								.fromPerspectiveElementId(((MPerspective) notification.getOldValue()).getElementId()));
					}
					// perspective changed
					if (notification.getNewValue() == null && notification.getOldValue() != null) {
						// deactivate old perspective - hide its toolBar
						String perspectiveId = PerspectiveProvider
								.fromPerspectiveElementId(((MPerspective) notification.getOldValue()).getElementId());
						toolbarProvider.setActive(perspectiveId, false);
					}
					if (notification.getNewValue() != null && notification.getOldValue() == null) {
						// activate new perspective - show its toolbar
						String perspectiveId = PerspectiveProvider
								.fromPerspectiveElementId(((MPerspective) notification.getNewValue()).getElementId());
						toolbarProvider.setActive(perspectiveId, true);
					}
				}
			}
		});
		return stack;
	}

	/**
	 * Checks if is our perspective element id.
	 *
	 * @param elementId
	 *            the element id
	 * @return true, if is perspective element id
	 */
	protected static boolean isPerspectiveElementId(String perspectiveId) {
		return perspectiveId.startsWith(IPerspectiveProvider.E4Constants.PERSPECTIVE_PREFIX);
	}

	/**
	 * converts a name to a perspective element id.
	 *
	 * @param perspectiveId
	 *            the perspective id
	 * @return the string
	 */
	protected static String toPerspectiveElementId(String perspectiveId) {
		return IPerspectiveProvider.E4Constants.PERSPECTIVE_PREFIX + perspectiveId;
	}

	/**
	 * converts from perspective element id to a name.
	 *
	 * @param elementId
	 *            the element id
	 * @return the string
	 */
	protected static String fromPerspectiveElementId(String elementId) {
		return elementId.substring(IPerspectiveProvider.E4Constants.PERSPECTIVE_PREFIX.length());
	}

	/**
	 * Add the perspective identified by perspectiveId to PerspectiveStack.
	 *
	 * @param perspectiveModel
	 *            - the model everything is based on
	 * @param perspectiveId
	 *            - unique identifier for a perspective in the model
	 * @return the m perspective
	 */
	private MPerspective createPerspective(MPerspectiveStack stack, Perspective perspectiveModel,
			String perspectiveId) {
		MPerspective perspective = AdvancedFactoryImpl.eINSTANCE.createPerspective();

		perspective.getTags().add(IPerspectiveProvider.E4Constants.TAG_REMOVE_ON_CLOSE);
		perspective.getTags().add(IPerspectiveProvider.E4Constants.TAG_NOT_IN_OPEN_PERSPECTIVE_DIALOG);

		String newPerspectiveId = toPerspectiveElementId(perspectiveId);
		int offset = 0;
		while(isPerspectiveIdAlreadyInUse(stack, newPerspectiveId)){
			newPerspectiveId = toPerspectiveElementId(perspectiveId + offset++);
		}
		
		perspective.setElementId(newPerspectiveId);
		perspective.setLabel(perspectiveModel.getName());
		perspective.setVisible(true);
		perspective.setToBeRendered(true);
		perspective.setIconURI(themeResourceService.getThemeURI(perspectiveModel.getIconURI(), ThemeResourceType.ICON));
		perspective.setAccessibilityPhrase(perspectiveModel.getAccessibilityPhrase());
		if (perspectiveModel.isDescription()) {
			perspective.setTooltip(perspectiveModel.getDescriptionValue().replace("\"", ""));
		}

		// iterate over all elements
		traverseModel(perspective, perspectiveModel);
		if (!perspective.getChildren().isEmpty()) {
			MPartSashContainerElement firstElement = perspective.getChildren().get(0);
			if (firstElement instanceof MPartSashContainer) {
				// create placeholder for designer
				//
				MPlaceholder designerPH = MAdvancedFactory.INSTANCE.createPlaceholder();
				MUIElement area = modelService.find("org.eclipse.osbp.model.area.designer", stack);
				designerPH.setRef(area);
				designerPH.setContainerData("40");
				designerPH.setVisible(modelingContext.isDesignMode());
				designerPH.setToBeRendered(modelingContext.isDesignMode());
				designerPH.getTags().add("designer:autoVisible");

				((MPartSashContainer) firstElement).getChildren().add(designerPH);
			}
		}
		return perspective;
	}
	
	private boolean isPerspectiveIdAlreadyInUse(MPerspectiveStack stack, String perspectiveId){
		if(stack != null && stack.getChildren() != null && !stack.getChildren().isEmpty() 
		&& perspectiveId != null && !perspectiveId.isEmpty()){
			for(MPerspective perspective : stack.getChildren()){
				if(perspective.getElementId().equals(perspectiveId)){
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * Register context.
	 *
	 * @param map
	 *            the map
	 * @param task
	 *            the task
	 */
	private void registerContext(Map<String, Object> map, PerspectiveFound perspectiveFound) {
		String workloadDtoFqn = null;
		IDto workloadDto = null;
		IBlipBPMStartInfo startInfo = null;
		IBlipBPMWorkloadModifiableItem task = null;
		Class<?> operativeDtoClass = null;
		String operativeDtoFqn = null;
		List<IDto> operativeDtos = null;

		if (taskClient != null && perspectiveFound.blipTask != null) {
			startInfo = taskProvider.getStartInfo(perspectiveFound.taskSummary);
			if (startInfo != null) {
				task = startInfo.getWorkloadMofifiableBpmItemForBlipId(perspectiveFound.blipTask.getName());
				if (task != null) {
					workloadDtoFqn = taskClient.getWorkloadDtoFqn(perspectiveFound.taskSummary);
					workloadDto = taskClient.getWorkloadDto(perspectiveFound.taskSummary);
					if(workloadDtoFqn == null || workloadDto == null) {
						workloadDtoFqn = startInfo.getWorkloadDtoFqn();
						workloadDto = startInfo.createWorkloadDto();
						taskClient.setWorkloadDtoFqn(perspectiveFound.taskSummary, workloadDtoFqn);
						taskClient.setWorkloadDto(perspectiveFound.taskSummary, workloadDto);
					}
					operativeDtos = task.getOperativeDtos(workloadDto);
					operativeDtoClass = task.getOperativeDtoClass();
					if (operativeDtoClass != null) {
						operativeDtoFqn = operativeDtoClass.getCanonicalName();
					} else {
						operativeDtoClass = null;
					}
				}
			}
		}
		map.put(IBlipBPMConstants.VARIABLE_PROCESS_START_INFO, startInfo);
		map.put(IBlipBPMConstants.VARIABLE_PROCESS_WORKLOAD_DTO_FQN, workloadDtoFqn);
		map.put(IBlipBPMConstants.VARIABLE_PROCESS_WORKLOAD_DTO, workloadDto);
		map.put(IBlipBPMConstants.VARIABLE_TASK_JBPM_SUMMARY, perspectiveFound.taskSummary);
		map.put(IBlipBPMConstants.VARIABLE_TASK_BLIP_ITEM, perspectiveFound.blipTask);
		map.put(IBlipBPMConstants.VARIABLE_TASK_BPM2_ITEM, perspectiveFound.bpmTask);
		map.put(IBlipBPMConstants.VARIABLE_TASK_START_INFO, task);
		map.put(IBlipBPMConstants.VARIABLE_TASK_OPERATIVE_DTO_CLASS, operativeDtoClass);
		map.put(IBlipBPMConstants.VARIABLE_TASK_OPERATIVE_DTO_FQN, operativeDtoFqn);
		map.put(IBlipBPMConstants.VARIABLE_TASK_OPERATIVE_DTOS, operativeDtos);
	}

	/**
	 * for every model element that can hold children, traverse recursively the
	 * model.
	 * 
	 * @param parent
	 *            - the parent e4 node to which the next child is added
	 * @param modelElement
	 *            - the current element which is traversed
	 */
	private void traverseModel(MElementContainer<?> parent, EObject modelElement) {
		if (modelElement instanceof Perspective) {
			log.trace("{}","traverse model perspective");
			Perspective perspectiveModel = (Perspective) modelElement;
			for (PerspectiveElement element : perspectiveModel.getElements()) {
				addElement(parent, element);
			}
		} else if (modelElement instanceof PerspectiveSashContainer) {
			log.trace("{}","traverse model sashcontainer");
			PerspectiveSashContainer sashModel = (PerspectiveSashContainer) modelElement;
			for (PerspectiveElement element : sashModel.getElements()) {
				addElement(parent, element);
			}
		} else if (modelElement instanceof PerspectivePartStack) {
			log.trace("{}","traverse model perspectivestack");
			PerspectivePartStack stackModel = (PerspectivePartStack) modelElement;
			for (PerspectiveElement element : stackModel.getElements()) {
				addElement(parent, element);
			}
		}
		log.trace("{}","traverse finished");
	}

	/**
	 * for PerspectiveSashContainer create an e4 element by it's factory.
	 * 
	 * @param parent
	 *            - the parent e4 node to which the next child is added
	 * @param element
	 *            - the current element which is traversed
	 */
	@SuppressWarnings("unchecked")
	private void addElementPerspectiveSashContainer(MElementContainer<?> parent, EObject element) {
		PerspectiveSashContainer sashModel = (PerspectiveSashContainer) element;
		MPartSashContainer sashContainer = BasicFactoryImpl.eINSTANCE.createPartSashContainer();
		sashContainer.setAccessibilityPhrase(sashModel.getAccessibilityPhrase());
		addAdapter(sashContainer);
		sashContainer.setElementId(sashModel.getElementId());

		sashContainer.setHorizontal("HORIZONTAL".equals(sashModel.getOrientation().getName()));
		sashContainer.setVisible(true);
		sashContainer.setParent((MElementContainer<MUIElement>) parent);
		if (parent instanceof MPerspective) {
			((MPerspective) parent).getChildren().add(sashContainer);
		} else if (parent instanceof MPartSashContainer) {
			((MPartSashContainer) parent).getChildren().add(sashContainer);
		}

		// go deeper
		traverseModel(sashContainer, element);
		// set selected references
		for (MPartSashContainerElement child : sashContainer.getChildren()) {
			if (sashModel.getSelectedElement() != null
					&& child.getElementId().equals(sashModel.getSelectedElement().getElementId())) {
				sashContainer.setSelectedElement(child);
				break;
			}
		}

		// DON´T MOVE THE FOLLOWING CODE LINES !!!!
		// The reading of the container data from the user properties in
		// 'getElementContainerData' below
		// requires the element id and the parent information set to the part
		// above.
		String elementContainerData = getElementContainerData(sashContainer);
		if (elementContainerData != null) {
			sashContainer.setContainerData(elementContainerData);
		} else {
			sashContainer.setContainerData(
					sashModel.getContainerData() != null ? sashModel.getContainerData().replace("\"", "") : "50");
		}

	}

	/**
	 * for addElementPerspectivePartStack create an e4 element by it's factory.
	 * 
	 * @param parent
	 *            - the parent e4 node to which the next child is added
	 * @param element
	 *            - the current element which is traversed
	 */
	@SuppressWarnings("unchecked")
	private void addElementPerspectivePartStack(MElementContainer<?> parent, EObject element) {
		PerspectivePartStack stackModel = (PerspectivePartStack) element;
		MPartStack stack = BasicFactoryImpl.eINSTANCE.createPartStack();
		stack.setAccessibilityPhrase(stackModel.getAccessibilityPhrase());
		addAdapter(stack);
		stack.setElementId(stackModel.getElementId());
		stack.setVisible(true);
		stack.setParent((MElementContainer<MUIElement>) parent);
		if(stackModel.getSynchronize() != null) {
			stack.getTransientData().put(IPerspectiveProvider.EventDispatcherConstants.SYNCHRONIZE_WITH, stackModel.getSynchronize().getElementId());
		}
		if (parent instanceof MPerspective) {
			((MPerspective) parent).getChildren().add(stack);
		} else if (parent instanceof MPartSashContainer) {
			((MPartSashContainer) parent).getChildren().add(stack);
		}
		// go deeper
		traverseModel(stack, element);
		// set selected references
		for (MStackElement child : stack.getChildren()) {
			if (stackModel.getSelectedElement() != null
					&& child.getElementId().equals(stackModel.getSelectedElement().getElementId())) {
				stack.setSelectedElement(child);
				break;
			}
		}

		// DON´T MOVE THE FOLLOWING CODE LINES !!!!
		// The reading of the container data from the user properties in
		// 'getElementContainerData' below
		// requires the element id and the parent information set to the part
		// above.
		String elementContainerData = getElementContainerData(stack);
		if (elementContainerData != null) {
			stack.setContainerData(elementContainerData);
		} else {
			stack.setContainerData(
					stackModel.getContainerData() != null ? stackModel.getContainerData().replace("\"", "") : "50");
		}

	}

	private String getElementContainerData(MUIElement element) {
		return (String) user.getProperty(getFQNKey(element));
	}

	/**
	 * for addElementPerspectivePart create an e4 element by it's factory.
	 * 
	 * @param parent
	 *            - the parent e4 node to which the next child is added
	 * @param element
	 *            - the current element which is traversed
	 */
	@SuppressWarnings("unchecked")
	private void addElementPerspectivePart(MElementContainer<?> parent, EObject element) {
		PerspectivePart partModel = (PerspectivePart) element;
		MPart part = BasicFactoryImpl.eINSTANCE.createPart();
		part.setAccessibilityPhrase(partModel.getAccessibilityPhrase());
		addAdapter(part);
		part.setElementId(partModel.getElementId());

		part.setIconURI(partModel.getIconURI());
		part.setLabel(partModel.getElementId());
		part.setVisible(true);
		part.setCloseable(partModel.isIsClosable());

		part.getPersistedState().put(IPerspectiveProvider.E4Constants.OSBP_NS_URI, getNsURI(partModel.getView()));
		part.getPersistedState().put(IPerspectiveProvider.E4Constants.OSBP_FQN, getFQN(partModel.getView()));

		EObject container = partModel.eContainer();
		while (!(container instanceof Perspective)) {
			container = container.eContainer();
		}
		Perspective perspective = (Perspective) container;
		supplyAcceptedSenders(partModel, part, perspective);

		String flavor = getFlavor(partModel.getView());
		if (flavor != null) {
			part.getPersistedState().put(IPerspectiveProvider.E4Constants.OSBP_FLAVOR, flavor);
		}

		part.setParent((MElementContainer<MUIElement>) parent);
		if (parent instanceof MPerspective) {
			((MPerspective) parent).getChildren().add(part);
		} else if (parent instanceof MPartSashContainer) {
			((MPartSashContainer) parent).getChildren().add(part);
		} else if (parent instanceof MPartStack) {
			((MPartStack) parent).getChildren().add(part);
		}
		if (partModel.getView() != null) {
			String contributionURI = getContributionURI(part, partModel);
			log.trace("set contribution URI for part {} to {} ", part.getElementId(),
					contributionURI);
			part.setContributionURI(contributionURI);
		}

		// DON´T MOVE THE FOLLOWING CODE LINES !!!!
		// The reading of the container data from the user properties in
		// 'getElementContainerData' below
		// requires the element id and the parent information set to the part
		// above.
		String elementContainerData = getElementContainerData(part);
		if (elementContainerData != null) {
			part.setContainerData(elementContainerData);
		} else {
			part.setContainerData(
					partModel.getContainerData() != null ? partModel.getContainerData().replace("\"", "") : "50");
		}

	}

	private void supplyAcceptedSenders(PerspectivePart partModel, MPart part, Perspective perspective) {
		if (perspective.getEventmanager() != null && perspective.getEventmanager().getEvents() != null
				&& !perspective.getEventmanager().getEvents().isEmpty()) {
			for (PerspectiveEvent event : perspective.getEventmanager().getEvents()) {
				if (event.getTarget().getElementId().equals(partModel.getElementId())) {
					ArrayList<String> senders = new ArrayList<>();
					senders.add(getViewPartID(partModel.getView()));
					for(PerspectivePart source : event.getAllowedsources()){
						senders.add(getViewPartID(source.getView()));
					}
					part.getTransientData().put(IPerspectiveProvider.EventDispatcherConstants.ACCEPTED_SENDERS,senders);
					break;
				}
			}
		}
	}

	/**
	 * Returns the corresponding viewid or fully qualified name of a PerspectivePart, which is needed
	 * for EventDispatcherEvent's recognition within a perspective.
	 * @param viewModel the {@link PerspectiveView} view model of the PerspectivePart 
	 * @return {@link String} the view id or fully qualified name
	 */
	private String getViewPartID(PerspectiveView viewModel) {
		log.trace("{}","get viewpart id");
		if (viewModel instanceof PerspectiveDialog) {
			return dslMetadataService.getECViewId(((PerspectiveDialog) viewModel).getRef());
		}
		else if (viewModel instanceof PerspectiveTable) {
			return dslMetadataService.getFullyQualifiedName(((PerspectiveTable) viewModel).getRef());
		}
		else if (viewModel instanceof PerspectiveSelection) {
			return dslMetadataService.getFullyQualifiedName(((PerspectiveSelection) viewModel).getRef());
		} else if (viewModel instanceof PerspectiveGrid) {
			return dslMetadataService.getFullyQualifiedName(((PerspectiveGrid) viewModel).getRef());
		} else if (viewModel instanceof PerspectiveChart) {
			return dslMetadataService.getFullyQualifiedName(((PerspectiveChart) viewModel).getRef());
		} else if (viewModel instanceof PerspectiveReport) {
			return dslMetadataService.getFullyQualifiedName(((PerspectiveReport) viewModel).getRef());
		} else if (viewModel instanceof PerspectiveOrganization) {
			return dslMetadataService.getFullyQualifiedName(((PerspectiveOrganization) viewModel).getRef());
		} else if (viewModel instanceof PerspectiveTopology) {
			return dslMetadataService.getFullyQualifiedName(((PerspectiveTopology) viewModel).getRef());
		} else if (viewModel instanceof PerspectiveDataInterchange) {
			return getFQN(viewModel);
		} else if (viewModel instanceof PerspectiveBPMN) {
			String className = BpmnView.class.getCanonicalName();
			return dslMetadataService.getClassURI(className, IPerspectiveProvider.PerspectiveViewType.BPMN);
		} else if (viewModel instanceof PerspectiveWelcome) {
			String className = WelcomeView.class.getCanonicalName();
			Bundle bundle = FrameworkUtil.getBundle(WelcomeView.class);
			return E4Constants.BUNDLE_PROTOCOL_SCHEME + "://" + bundle.getSymbolicName() + "/" + className;
		} else if (viewModel instanceof PerspectiveSearch) {
			String className = SearchView.class.getCanonicalName();
			Bundle bundle = FrameworkUtil.getBundle(SearchView.class);
			return E4Constants.BUNDLE_PROTOCOL_SCHEME + "://" + bundle.getSymbolicName() + "/" + className;
		} else if (viewModel instanceof PerspectiveKanban) {
			String className = KanbanView.class.getCanonicalName();
			Bundle bundle = FrameworkUtil.getBundle(KanbanView.class);
			return E4Constants.BUNDLE_PROTOCOL_SCHEME + "://" + bundle.getSymbolicName() + "/" + className;
		} else if (viewModel instanceof PerspectiveBrowser) {
			String className = BrowserView.class.getCanonicalName();
			Bundle bundle = FrameworkUtil.getBundle(BrowserView.class);
			return E4Constants.BUNDLE_PROTOCOL_SCHEME + "://" + bundle.getSymbolicName() + "/" + className;
		} else if (viewModel instanceof PerspectiveSaiku) {
			String className = SaikuView.class.getCanonicalName();
			Bundle bundle = FrameworkUtil.getBundle(SaikuView.class);
			return E4Constants.BUNDLE_PROTOCOL_SCHEME + "://" + bundle.getSymbolicName() + "/" + className;
		}
		else {
			return null;
		}
	}

	/**
	 * for every model element create an e4 element by it's factory.
	 * 
	 * @param parent
	 *            - the parent e4 node to which the next child is added
	 * @param element
	 *            - the current element which is traversed
	 */
	private void addElement(MElementContainer<?> parent, EObject element) {
		if(dslMetadataService.isPerspectiveElementAuthorized(element, userAccessService)) {
			if (element instanceof PerspectiveSashContainer) {
				log.trace("{}","add sashcontainer");
				addElementPerspectiveSashContainer(parent, element);
			} else if (element instanceof PerspectivePartStack) {
				log.trace("{}","add partstack");
				addElementPerspectivePartStack(parent, element);
			} else if (element instanceof PerspectivePart) {
				log.trace("{}","add part");
				addElementPerspectivePart(parent, element);
			}
		}
	}

	/**
	 * create the view connected to a part.
	 * 
	 * @param viewModel
	 *            - the model of the view
	 * @return null or the classURI
	 */
	private String getContributionURI(MPart part, PerspectivePart partModel) { // NOSONAR
		log.trace("{}","get contributionURI");
		PerspectiveView viewModel = partModel.getView();
		if (viewModel instanceof PerspectiveTable) {
			String className = getFQN(viewModel)+"Table";
			return dslMetadataService.getClassURI(className, IPerspectiveProvider.PerspectiveViewType.TABLE);
		} else if (viewModel instanceof PerspectiveSelection) {
			String className = getFQN(viewModel)+"Select";
			return dslMetadataService.getClassURI(className, IPerspectiveProvider.PerspectiveViewType.TABLE);
		} else if (viewModel instanceof PerspectiveGrid) {
			String className = getFQN(viewModel)+"Grid";
			return dslMetadataService.getClassURI(className, IPerspectiveProvider.PerspectiveViewType.TABLE);
		} else if (viewModel instanceof PerspectiveChart) {
			String className = getFQN(viewModel)+"Chart";
			return dslMetadataService.getClassURI(className, IPerspectiveProvider.PerspectiveViewType.CHART);
		} else if (viewModel instanceof PerspectiveReport) {
			String className = getFQN(viewModel)+"Report";
			return dslMetadataService.getClassURI(className, IPerspectiveProvider.PerspectiveViewType.REPORT);
		} else if (viewModel instanceof PerspectiveOrganization) {
			if (optionalOrgURIProvider != null) {
				return optionalOrgURIProvider.getViewPartURI();
			} else {
				return null;
			}
		} else if (viewModel instanceof PerspectiveTopology) {
			String className = getFQN(viewModel)+"Topology";
			return dslMetadataService.getClassURI(className, IPerspectiveProvider.PerspectiveViewType.TOPOLOGY);
		} else if (viewModel instanceof PerspectiveDialog) {
			part.getTransientData().put(IPerspectiveProvider.TRANSIENT_DIALOG_MODEL, ((PerspectiveDialog) viewModel).getRef());
			return dslMetadataService.getClassURI(DialogProvider.class.getCanonicalName(), IPerspectiveProvider.PerspectiveViewType.DIALOG);
		} else if (viewModel instanceof PerspectiveDataInterchange) {
			String className = getFQN(viewModel)+"TriggerView";
			return dslMetadataService.getClassURI(className, IPerspectiveProvider.PerspectiveViewType.DATAINTERCHANGE);
		} else if (viewModel instanceof PerspectiveBPMN) {
			String className = BpmnView.class.getCanonicalName();
			return dslMetadataService.getClassURI(className, IPerspectiveProvider.PerspectiveViewType.BPMN);
		} else if (viewModel instanceof PerspectiveWelcome) {
			String className = WelcomeView.class.getCanonicalName();
			Bundle bundle = FrameworkUtil.getBundle(WelcomeView.class);
			return E4Constants.BUNDLE_PROTOCOL_SCHEME + "://" + bundle.getSymbolicName() + "/" + className;
		} else if (viewModel instanceof PerspectiveSaiku) {
			String className = SaikuView.class.getCanonicalName();
			Bundle bundle = FrameworkUtil.getBundle(SaikuView.class);
			return E4Constants.BUNDLE_PROTOCOL_SCHEME + "://" + bundle.getSymbolicName() + "/" + className;
		} else if (viewModel instanceof PerspectiveSearch) {
			part.getTransientData().put(IPerspectiveProvider.FilterConstants.FILTER_DTO_CLASS,
					((PerspectiveSearch) viewModel).getDtoRef());
			part.getTransientData().put(IPerspectiveProvider.FilterConstants.FILTER_DEPTH,
					((PerspectiveSearch) viewModel).getDepth());
			part.getTransientData().put(IPerspectiveProvider.FilterConstants.FILTER_COLUMNS,
					Math.max(1, ((PerspectiveSearch) viewModel).getFilterCols()));
			String className = SearchView.class.getCanonicalName();
			Bundle bundle = FrameworkUtil.getBundle(SearchView.class);
			return E4Constants.BUNDLE_PROTOCOL_SCHEME + "://" + bundle.getSymbolicName() + "/" + className;
		} else if (viewModel instanceof PerspectiveKanban) {
			part.getTransientData().put(IPerspectiveProvider.KanbanConstants.DTO,
					((PerspectiveKanban) viewModel).getDtoRef());
			part.getTransientData().put(IPerspectiveProvider.KanbanConstants.DIALOG,
					((PerspectiveKanban) viewModel).getDialogRef());
			part.getTransientData().put(IPerspectiveProvider.KanbanConstants.CARD,
					((PerspectiveKanban) viewModel).getCardRef());
			String className = KanbanView.class.getCanonicalName();
			Bundle bundle = FrameworkUtil.getBundle(KanbanView.class);
			return E4Constants.BUNDLE_PROTOCOL_SCHEME + "://" + bundle.getSymbolicName() + "/" + className;
		} else if (viewModel instanceof PerspectiveBrowser) {
			String url = "";
			if (((PerspectiveBrowser) viewModel).isCubeView()){
				int port = ProductConfiguration.prefs().getCubeViewPort();
				URI location = Page.getCurrent().getLocation();
				try {
					url = new URL(location.getScheme(), location.getHost(), port, "").toString();
				} catch (MalformedURLException e) {
					log.error("cube view URL is malformed!", e);
				}
			} else {
				url = ((PerspectiveBrowser) viewModel).getUrl();
			}
			part.getTransientData().put(IPerspectiveProvider.BrowserConstants.URL, url);
			String className = BrowserView.class.getCanonicalName();
			Bundle bundle = FrameworkUtil.getBundle(BrowserView.class);
			return E4Constants.BUNDLE_PROTOCOL_SCHEME + "://" + bundle.getSymbolicName() + "/" + className;
		}
		return null;
	}

	/**
	 * Returns the FQN for the content of the view.
	 * 
	 * @param viewModel
	 *            - the model of the view
	 * @return null or the FQN
	 */
	private String getFQN(PerspectiveView viewModel) { // NOSONAR
		log.trace("{}","get FQN");
		if (viewModel instanceof PerspectiveTable) {
			Table object = ((PerspectiveTable) viewModel).getRef();
			TablePackage pkg = (TablePackage) object.eContainer();
			return pkg == null ? "" : toFQN(pkg.getName(), object.getName());
		} else if (viewModel instanceof PerspectiveSelection) {
			Table object = ((PerspectiveSelection) viewModel).getRef();
			TablePackage pkg = (TablePackage) object.eContainer();
			return pkg == null ? "" : toFQN(pkg.getName(), object.getName());
		} else if (viewModel instanceof PerspectiveGrid) {
			Table object = ((PerspectiveGrid) viewModel).getRef();
			TablePackage pkg = (TablePackage) object.eContainer();
			return pkg == null ? "" : toFQN(pkg.getName(), object.getName());
		} else if (viewModel instanceof PerspectiveChart) {
			Chart object = ((PerspectiveChart) viewModel).getRef();
			ChartPackage pkg = (ChartPackage) object.eContainer();
			return pkg == null ? "" : toFQN(pkg.getName(), object.getName());
		} else if (viewModel instanceof PerspectiveReport) {
			Report object = ((PerspectiveReport) viewModel).getRef();
			ReportPackage pkg = (ReportPackage) object.eContainer();
			return pkg == null ? "" : toFQN(pkg.getName(), object.getName());
		} else if (viewModel instanceof PerspectiveOrganization) {
			Organization object = ((PerspectiveOrganization) viewModel).getRef();
			OrganizationPackage pkg = (OrganizationPackage) object.eContainer();
			return pkg == null ? "" : toFQN(pkg.getName(), object.getName());
		} else if (viewModel instanceof PerspectiveTopology) {
			Topology object = ((PerspectiveTopology) viewModel).getRef();
			TopologyPackage pkg = (TopologyPackage) object.eContainer();
			return pkg == null ? "" : toFQN(pkg.getName(), object.getName());
		} else if (viewModel instanceof PerspectiveDialog) {
			Dialog object = ((PerspectiveDialog) viewModel).getRef();
			DialogPackage pkg = (DialogPackage) object.eContainer();
			return pkg == null ? "" : toFQN(pkg.getName(), object.getName());
		} else if (viewModel instanceof PerspectiveDataInterchange) {
			DataInterchangeGroup group = ((PerspectiveDataInterchange) viewModel).getRef();
			DataInterchangePackage pkg = (DataInterchangePackage) group.eContainer();
			return toFQN(pkg.getName(), group.getName());
		}
		return null;
	}

	/**
	 * Return the NS-URI for the content of the view. Used as a content type
	 * marker.
	 *
	 * @param viewModel
	 *            the view model
	 * @return the ns uri
	 */
	private String getNsURI(PerspectiveView viewModel) { // NOSONAR
		log.trace("{}","get NsURI");
		if (viewModel instanceof PerspectiveTable) {
			return TableDSLPackage.eNS_URI;
		} else if (viewModel instanceof PerspectiveSelection) {
			return TableDSLPackage.eNS_URI;
		} else if (viewModel instanceof PerspectiveGrid) {
			return TableDSLPackage.eNS_URI;
		} else if (viewModel instanceof PerspectiveChart) {
			return ChartDSLPackage.eNS_URI;
		} else if (viewModel instanceof PerspectiveReport) {
			return ReportDSLPackage.eNS_URI;
		} else if (viewModel instanceof PerspectiveOrganization) {
			return OrganizationDSLPackage.eNS_URI;
		} else if (viewModel instanceof PerspectiveTopology) {
			return TopologyDSLPackage.eNS_URI;
		} else if (viewModel instanceof PerspectiveDialog) {
			return DialogDSLPackage.eNS_URI;
		} else if (viewModel instanceof PerspectiveBPMN) {
			return Bpmn2Package.eNS_URI;
		} else if (viewModel instanceof PerspectiveKanban) {
			return ExtensionModelPackage.eNS_URI;
		} else if (viewModel instanceof PerspectiveBrowser) {
			return ExtensionModelPackage.eNS_URI;
		} else if (viewModel instanceof PerspectiveDataInterchange) {
			return DataDSLPackage.eNS_URI;
		}
		return null;
	}

	private String getFlavor(PerspectiveView viewModel) { // NOSONAR
		if (viewModel instanceof PerspectiveTable) {
			return "table";
		} else if (viewModel instanceof PerspectiveGrid) {
			return "grid";
		}
		return null;
	}

	/**
	 * To fqn.
	 *
	 * @param pkg
	 *            the pkg
	 * @param name
	 *            the name
	 * @return the string
	 */
	private String toFQN(String pkg, String name) {
		return pkg + "." + name;
	}

	/**
	 * Subscribe.
	 */
	protected void subscribe() {
		if (taskClient != null) {
			taskClient.registerPerspectiveListener(this);
		}
		createEventHandlers();
		eventBroker.subscribe(AuthenticationConstants.Events.Authentication.PRE_LOGOUT, doLogout);
	}

	/**
	 * Unsubscribe.
	 */
	@PreDestroy
	protected void unsubscribe() {
		taskClient.unsubscribeTaskEventNotification(this);
		if (taskClient != null) {
			taskClient.unregisterPerspectiveListener(this);
		}
	}

	/**
	 * Creates the event handlers.
	 */
	private void createEventHandlers() {
		doLogout = (Event event) -> {
			log.trace("{}","logout pending");
			suspendAllTasks();
		};
	}

	/**
	 * Suspend all pending tasks while user pressed logout or closed browser.
	 * 
	 */
	private void suspendAllTasks() {
		for (BPMTaskSummary summary : perspectiveTasks.keySet()) {
			log.debug("suspend task {}", summary.getId());
			taskClient.operations(summary.getId(), user, null, BPMOperation.Suspend);
		}
	}

	/**
	 * Tries to find the perspective model using the perspective builder
	 * service.
	 *
	 * @param perspectiveId
	 *            - the id of the perspective used in the model
	 * @return the perspective
	 */
	protected PerspectiveFound findPerspective(String perspectiveId) {
		log.trace("{}","find perspective model by id");
		return new PerspectiveFound(null,
				(Perspective) dslMetadataService.getMetadata(perspectiveId, PerspectiveDslPackage.Literals.PERSPECTIVE),
				null, null, perspectiveId);
	}

	private final class PerspectiveFound {
		public final BPMTaskSummary taskSummary;
		public final Perspective perspective;
		public final BlipItem blipTask;
		public final Task bpmTask;
		public final String fqn;

		protected PerspectiveFound(BPMTaskSummary taskSummary, Perspective perspective, BlipItem blipTask,
				Task bpmTask, String fqn) {
			this.taskSummary = taskSummary;
			this.perspective = perspective;
			this.blipTask = blipTask;
			this.bpmTask = bpmTask;
			this.fqn = fqn;
		}
	}

	/**
	 * Tries to find the perspective model using the perspective builder
	 * service.
	 *
	 * @param task
	 *            the task
	 * @return the perspective
	 */
	protected PerspectiveFound findPerspective(BPMTaskSummary taskSummary) {
		log.trace("{}","find perspective model by task");
		for (EObject eObj : dslMetadataService.getAll(PerspectiveDslPackage.Literals.PERSPECTIVE)) {
			if ((((Perspective) eObj).getProcess() != null) && (((Perspective) eObj).getUserTask() != null)) {
				Process process = ((Perspective) eObj).getProcess().getProcess();
				BlipUserTask blipTask = ((Perspective) eObj).getUserTask();
				if ((process != null) && (process.getId().equals(taskSummary.getProcessId()))) {
					Task bpmTask = blipTask.getTask();
					if ((bpmTask != null) && bpmTask.getName().equals(taskSummary.getName())) {
						return new PerspectiveFound(taskSummary, (Perspective) eObj, blipTask, bpmTask, ((PerspectivePackage) eObj.eContainer()).getName()+"."+((Perspective) eObj).getName());
					}
				}
			}
		}
		return null;
	}

	/**
	 * Tries to find the action toolbar model using the action builder service.
	 *
	 * @param toolbarId
	 *            the toolbar id
	 * @return the action toolbar
	 */
	protected ActionToolbar findToolbar(String toolbarId) {
		log.trace("{}","find toolbar model");
		return (ActionToolbar) dslMetadataService.getMetadata(toolbarId, ActionDSLPackage.Literals.ACTION_TOOLBAR);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.osbp.bpm.api.IBPMTaskEventNotification#notifyTaskEvent(org
	 * .jbpm.task.event.entity.TaskEventType,
	 * org.jbpm.task.event.entity.TaskUserEvent)
	 */
	@Override
	public void notifyTaskEvent(BPMTaskEventType type, BPMTaskUserEvent event) {
		closePerspective(event.getTaskId());
	}

	@Override
	public void notifyProcessCompletedEvent() {
		// NOP
	}

	@Override
	public void receiveEvent(EventDispatcherEvent event) {
		if (event.getCommand() == EventDispatcherCommand.ACTION
				&& event.getData().containsKey(EventDispatcherDataTag.BUTTON_ID)
				&& event.getData().get(EventDispatcherDataTag.BUTTON_ID) instanceof TaskActionEnum
				&& event.getData().containsKey(EventDispatcherDataTag.TASK_ID)
				&& event.getData().get(EventDispatcherDataTag.TASK_ID) instanceof Long) {
			Object buttonId = event.getData().get(EventDispatcherDataTag.BUTTON_ID);
			TaskActionEnum enumId = (TaskActionEnum) buttonId;
			Long taskId = (Long) event.getData().get(EventDispatcherDataTag.TASK_ID);
			if (enumId == TaskActionEnum.TASK_ACTION_DELEGATE) {
				log.debug("dispatch action received in PerspectiveSupport for {}", TaskActionEnum.TASK_ACTION_DELEGATE.getLiteral());
			} else {
				taskClient.operations(taskId, user, null, BPMOperation.valueOf(enumId.getLiteral()));
			}
		}
		if (event.getCommand() == EventDispatcherCommand.REFRESH &&
			event.getTopic().equals("reloadModel.perspective")) {
			Map<BPMTaskSummary,String> taskToReload = new HashMap<>(perspectiveTasks);
			for(BPMTaskSummary summary:taskToReload.keySet()) {
				closePerspective(summary);
			}
			Map<String,MPerspective> toReload = new HashMap<>(perspectives);
			for(String p:toReload.keySet()) {
				closePerspective(p);
			}
			for(BPMTaskSummary summary:taskToReload.keySet()) {
				openPerspective(summary);
			}
			for(String perspectiveId:toReload.keySet()) {
				openPerspective(perspectiveId);
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.osbp.ui.api.perspective.IPerspectiveProvider#openPerspective(
	 * java.lang.String, java.lang.String, java.lang.Class)
	 */
	@Override
	public void openPerspective(String elementId, String labelName, Class<?> clazz) {
		MPerspectiveStack stack = initPerspectiveStack();
		if (stack != null) {
			// bring to top if already contained in model
			for (MPerspective perspective : stack.getChildren()) {
				if ((toPerspectiveElementId(elementId)).equals(perspective.getElementId())) {
					modelService.bringToTop(perspective);
					return;
				}
			}
			MPerspective perspective = AdvancedFactoryImpl.eINSTANCE.createPerspective();

			perspective.getTags().add(IPerspectiveProvider.E4Constants.TAG_REMOVE_ON_CLOSE);
			perspective.getTags().add(IPerspectiveProvider.E4Constants.TAG_NOT_IN_OPEN_PERSPECTIVE_DIALOG);

			perspective.setElementId(toPerspectiveElementId(elementId));
			perspective.setLabel(labelName);
			perspective.setVisible(true);
			perspective.setToBeRendered(true);
			perspective.setIconURI(themeResourceService.getThemeURI("osbee", ThemeResourceType.ICON));
			MPart part = BasicFactoryImpl.eINSTANCE.createPart();
			part.setVisible(true);
			part.setCloseable(false);
			perspective.getChildren().add(part);
			String className = clazz.getCanonicalName();
			Bundle bundle = FrameworkUtil.getBundle(clazz);
			String contributionURI = E4Constants.BUNDLE_PROTOCOL_SCHEME + "://" + bundle.getSymbolicName() + "/"+ className;
			part.setContributionURI(contributionURI);
			stack.getChildren().add(perspective);
			stack.setSelectedElement(perspective);
			modelService.bringToTop(perspective);
		}
	}

	@Override
	public void openPerspective(BPMTaskSummary taskSummary) {
		// register tasksummary in context for action's TaskHelper
		eclipseContext.set(BPMTaskSummary.class, taskSummary);
		PerspectiveFound perspectiveFound = null;
		log.debug("open perspective with taskId {}", taskSummary.getId());
		perspectiveFound = findPerspective(taskSummary);
		if (perspectiveFound != null) {
			// notify orgachart with current user's position
			eventBroker.post(EventBrokerMsg.ORGCHART_SELECT, user.getPosition());
			openPerspective(perspectiveFound, taskSummary);
		} else {
			log.error("perspective for taskid {} not found", taskSummary.getId());
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.osbp.ui.api.perspective.IPerspectiveProvider#
	 * openPerspectiveEvent(java.lang.String)
	 */
	@Override
	public void openPerspective(String perspectiveId) {
		PerspectiveFound perspectiveFound = findPerspective(perspectiveId);
		if (perspectiveFound != null) {
			log.debug("{}", "openPerspective starts");
			openPerspective(perspectiveFound, null);
			log.debug("{}", "openPerspective finished");
		} else {
			log.error("perspective id {} not found", perspectiveId);
		}
	}

	/**
	 * Creates a new perspective suitable for the given task it was called from.
	 *
	 * @param perspectiveModel
	 *            the perspective model
	 * @param humanTask
	 * @param taskSummary
	 */
	private void openPerspective(PerspectiveFound perspectiveFound, BPMTaskSummary summary) {
		MPerspectiveStack stack = initPerspectiveStack();
		if (stack != null && perspectiveFound.perspective != null) {
			// bring to top if already contained in model
			// lo wants multiple manually opened perspectives of same type by
			// 02/28/2018
			if (summary != null) {
				for (MPerspective perspective : stack.getChildren()) {
					if ((toPerspectiveElementId(perspectiveFound.fqn))
							.equals(perspective.getElementId())) {
						modelService.bringToTop(perspective);
						return;
					}
				}
			}

			log.debug("open perspective {}", perspectiveFound.fqn);
			log.trace("{}","add perspective");
			MPerspective perspective = createPerspective(stack, perspectiveFound.perspective,
					perspectiveFound.fqn);
			if (summary != null) {
				registerContext(perspective.getTransientData(), perspectiveFound);
				// create the toolbar
				if (perspectiveFound.perspective.getToolbar() != null) {
					String toolBarId = dslMetadataService.getFullyQualifiedName(perspectiveFound.perspective.getToolbar());
					toolbarProvider.addToolbar(perspectiveFound.fqn, findToolbar(toolBarId));
				}
			}
			stack.getChildren().add(perspective);
			stack.setSelectedElement(perspective);
			modelService.bringToTop(perspective);

			perspectives.put(perspectiveFound.fqn, perspective);
			if(summary != null) {
				perspectiveTasks.put(summary, perspectiveFound.fqn);
			}
			// get notified from bpm
			if (taskClient != null) {
				taskClient.subscribeProcessCompletedEventNotification(this);
				taskClient.subscribeTaskEventNotification(BPMTaskEventType.Release, this);
				taskClient.subscribeTaskEventNotification(BPMTaskEventType.Complete, this);
				taskClient.subscribeTaskEventNotification(BPMTaskEventType.Delegated, this);
				taskClient.subscribeTaskEventNotification(BPMTaskEventType.Fail, this);
				taskClient.subscribeTaskEventNotification(BPMTaskEventType.Skipped, this);
				taskClient.subscribeTaskEventNotification(BPMTaskEventType.Release, this);
				taskClient.subscribeTaskEventNotification(BPMTaskEventType.Stop, this);
				taskClient.subscribeTaskEventNotification(BPMTaskEventType.Suspended, this);
			}
		}
	}

	/**
	 * Close perspective.
	 *
	 * @param perspectiveId
	 *            of the perspective to close
	 * @param suspendTask
	 *            is true if task should be set to susupended
	 */
	private void closePerspective(String perspectiveId) {
		if (perspectiveTasks.containsValue(perspectiveId)) {
			for (Map.Entry<BPMTaskSummary, String> perspective : perspectiveTasks.entrySet()) {
				if (perspective.getValue().equals(perspectiveId)) {
					closePerspective(perspective.getKey());
					break;
				}
			}
		} else {
			if(perspectives.containsKey(perspectiveId)) {
				modelService.resetPerspectiveModel(perspectives.get(perspectiveId), trimmedWindow);
				modelService.removePerspectiveModel(perspectives.get(perspectiveId), trimmedWindow);
				perspectives.remove(perspectiveId);
			}
		}
	}

	/**
	 * Close perspective an remove from PerspectiveStack.
	 *
	 * @param taskId
	 *            of the perspective to close
	 */
	private void closePerspective(long taskId) {
		for(BPMTaskSummary summary:perspectiveTasks.keySet()) {
			if(summary.getId() == taskId) {
				closePerspective(summary);
				break;
			}
		}
	}

	@Override
	public void closePerspective(BPMTaskSummary summary) {
		if (perspectiveTasks.containsKey(summary)) {
			modelService.resetPerspectiveModel(perspectives.get(perspectiveTasks.get(summary)), trimmedWindow);
			modelService.removePerspectiveModel(perspectives.get(perspectiveTasks.get(summary)), trimmedWindow);
			toolbarProvider.removeToolbar(perspectiveTasks.get(summary));
			perspectives.remove(perspectiveTasks.get(summary));
			perspectiveTasks.remove(summary);
		}
	}

	private void addAdapter(MUIElement element) {
		((EObject) element).eAdapters().add(new AdapterImpl() {
			@Override
			public void notifyChanged(Notification notification) {
				if (notification.getEventType() == Notification.SET) {
					switch(notification.getFeatureID(UIElementImpl.class)) {
						case UiPackageImpl.UI_ELEMENT__CONTAINER_DATA:
							if(element.getElementId() != null) {
								user.addToProperties(getFQNKey(element), element.getContainerData());
							}
							break;
						case UiPackageImpl.ELEMENT_CONTAINER__SELECTED_ELEMENT:
							if(element.getTransientData().containsKey(IPerspectiveProvider.EventDispatcherConstants.SYNCHRONIZE_WITH)) {
								String elementId = (String) element.getTransientData().get(IPerspectiveProvider.EventDispatcherConstants.SYNCHRONIZE_WITH);
								MPartStack partStack = (MPartStack) modelService.find(elementId, element.getParent());
								int index = ((MPartStack)element).getChildren().indexOf(((MPartStack)element).getSelectedElement());
								if(index <= partStack.getChildren().size() && (partStack.getSelectedElement() == null || !partStack.getSelectedElement().equals(partStack.getChildren().get(index)))) {
									partStack.setSelectedElement(partStack.getChildren().get(index));
								}
							}
							break;
					}
				}
			}
		});
	}

	private String getFQNKey(MUIElement element) {
		MUIElement muiElement = element;
		List<String> elementIds = new LinkedList<>();
		StringBuilder key = new StringBuilder();
		while (muiElement != null) {
			if (muiElement.getElementId() != null) {
				elementIds.add(muiElement.getElementId());
				if (muiElement.getElementId().startsWith(E4Constants.PERSPECTIVE_PREFIX)) {
					break;
				}
				muiElement = muiElement.getParent();
			}
		}
		for (int i = elementIds.size(); i > 0; i--) {
			if (key.length() != 0) {
				key.append(".");
			}
			key.append(elementIds.get(i - 1));
		}
		return key.toString();
	}
}
