/**
 * Copyright (c) 2011, 2014 - Lunifera GmbH (Gross Enzersdorf, Austria), 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 v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors: 
 * 		Florian Pirchner - Initial implementation
 */
package org.eclipse.osbp.vaaclipse.addons.ecview.views;

import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;

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

import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.ui.di.Persist;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.e4.ui.model.application.commands.MCommand;
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
import org.eclipse.e4.ui.model.application.ui.menu.MHandledToolItem;
import org.eclipse.e4.ui.model.application.ui.menu.MMenuFactory;
import org.eclipse.e4.ui.model.application.ui.menu.MToolBar;
import org.eclipse.e4.ui.model.application.ui.menu.MToolBarElement;
import org.eclipse.e4.ui.model.application.ui.menu.MToolItem;
import org.eclipse.e4.ui.workbench.modeling.EModelService;
import org.eclipse.e4.ui.workbench.modeling.EPartService;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.osbp.dsl.dto.lib.services.DtoServiceException;
import org.eclipse.osbp.dsl.dto.lib.services.IDTOService;
import org.eclipse.osbp.ecview.core.common.beans.ISlot;
import org.eclipse.osbp.ecview.core.common.context.ContextException;
import org.eclipse.osbp.ecview.core.common.context.IViewContext;
import org.eclipse.osbp.ecview.core.common.editpart.IFieldEditpart;
import org.eclipse.osbp.ecview.core.common.model.core.CoreModelPackage;
import org.eclipse.osbp.ecview.core.common.model.core.YBeanSlot;
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddable;
import org.eclipse.osbp.ecview.core.common.model.core.YExposedAction;
import org.eclipse.osbp.ecview.core.common.model.core.YField;
import org.eclipse.osbp.ecview.core.common.model.core.YFocusable;
import org.eclipse.osbp.ecview.core.common.model.core.YView;
import org.eclipse.osbp.ecview.core.common.model.core.util.BindingIdUtil;
import org.eclipse.osbp.ecview.core.common.validation.IFieldValidationManager;
import org.eclipse.osbp.ecview.core.util.emf.ModelUtil;
import org.eclipse.osbp.runtime.common.annotations.DtoUtils;
import org.eclipse.osbp.runtime.common.event.IEventBroker;
import org.eclipse.osbp.runtime.common.i18n.II18nService;
import org.eclipse.osbp.runtime.common.state.ISharedStateContext;
import org.eclipse.osbp.runtime.common.state.SharedStateUnitOfWork;
import org.eclipse.osbp.runtime.common.validation.IStatus;
import org.eclipse.osbp.runtime.common.validation.ValidationKind;
import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.VaadinRenderer;
import org.eclipse.osbp.runtime.web.vaadin.common.resource.IResourceProvider;
import org.eclipse.osbp.runtime.web.vaadin.components.dialogs.AcceptDeleteDialog;
import org.eclipse.osbp.runtime.web.vaadin.components.dialogs.AcceptLoosingDataDialog;
import org.eclipse.osbp.runtime.web.vaadin.components.dialogs.AcceptReloadDialog;
import org.eclipse.osbp.vaaclipse.addons.common.api.IE4Constants;
import org.eclipse.osbp.vaaclipse.addons.common.api.IE4Topics;
import org.eclipse.osbp.vaaclipse.addons.common.api.di.Callback;
import org.eclipse.osbp.vaaclipse.addons.common.api.di.Delete;
import org.eclipse.osbp.vaaclipse.addons.common.api.di.EnabledState;
import org.eclipse.osbp.vaaclipse.addons.common.api.di.Load;
import org.eclipse.osbp.vaaclipse.addons.common.api.di.Validate;
import org.eclipse.osbp.vaaclipse.addons.common.api.status.IStatusManager;
import org.eclipse.osbp.vaaclipse.addons.common.api.status.IStatusScope;
import org.eclipse.osbp.vaaclipse.addons.common.event.EventTopicNormalizer;
import org.eclipse.osbp.vaaclipse.addons.ecview.event.E4EventBrokerAdapter;
import org.eclipse.osbp.vaaclipse.addons.keybinding.IKeyBindingService;
import org.eclipse.osbp.vaaclipse.publicapi.commands.IPartItemExecutionService;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.vaadin.event.LayoutEvents;
import com.vaadin.event.LayoutEvents.LayoutClickEvent;
import com.vaadin.ui.Notification;
import com.vaadin.ui.Notification.Type;
import com.vaadin.ui.VerticalLayout;

/**
 * A generic ECView view part implementation. It will be used by the
 * DynamicViewSupport to create views on the fly.
 * <p>
 * Client should not subclass this implementation.
 */
public class GenericECViewPart implements IFieldValidationManager.Listener {

	/** The Constant BEAN_SLOT__VALIDATION_ERROR. */
	private static final String BEAN_SLOT__VALIDATION_ERROR = "validationError";

	/** The Constant LOGGER. */
	private static final Logger LOGGER = LoggerFactory
			.getLogger(GenericECViewPart.class);

	/** The eclipse context. */
	@Inject
	private IEclipseContext eclipseContext;
	
	/** The m part. */
	@Inject
	private MPart mPart;
	
	/** The parent layout. */
	@Inject
	private VerticalLayout parentLayout;
	
	/** The e4 event broker. */
	@Inject
	private org.eclipse.e4.core.services.events.IEventBroker e4EventBroker;
	
	/** The topic normalizer. */
	@Inject
	private EventTopicNormalizer topicNormalizer;
	
	/** The i18n service. */
	@Inject
	private II18nService i18nService;
	
	/** The resource provider. */
	@Inject
	private IResourceProvider resourceProvider;
	
	/** The y view. */
	@Inject
	private YView yView;
	
	/** The shared state. */
	@Inject
	private ISharedStateContext sharedState;
	
	/** The dto service. */
	@Inject
	private IDTOService<Object> dtoService;
	
	/** The part service. */
	@Inject
	private EPartService partService;
	
	/** The status manager. */
	@Inject
	private IStatusManager statusManager;
	
	/** The key binding service. */
	@Inject
	private IKeyBindingService keyBindingService;

	/** The command info. */
	private Map<String, CommandInfo> commandInfo = new HashMap<String, CommandInfo>();

	/** The exposed actions callback. */
	private ExposedActionsCallback exposedActionsCallback;
	
	/** The view context. */
	private IViewContext viewContext;
	
	/** The redirected eventtopics. */
	private HashMap<String, Set<YBeanSlot>> redirectedEventtopics;
	
	/** The event handlers. */
	private Set<EventHandler> eventHandlers = new HashSet<EventHandler>();

	/** The ecview field validation manager. */
	private IFieldValidationManager ecviewFieldValidationManager;

	/** The validation result. */
	private Set<IStatus> validationResult;

	/**
	 * Instantiates a new generic ec view part.
	 */
	public GenericECViewPart() {
	}

	/**
	 * Setup.
	 */
	@SuppressWarnings("serial")
	@PostConstruct
	public void setup() {

		if (yView == null) {
			Notification.show("View model is not available!",
					Notification.Type.ERROR_MESSAGE);
			return;
		}

		exposedActionsCallback = new ExposedActionsCallback();

		VerticalLayout layout = new VerticalLayout();
		parentLayout.addComponent(layout);
		layout.setSizeFull();

		redirectEventTopics(yView);

		// render the Vaadin UI
		Map<String, Object> properties = new HashMap<String, Object>();

		// register services to be used
		Map<String, Object> services = new HashMap<String, Object>();
		services.put(org.eclipse.osbp.runtime.common.event.IEventBroker.class
				.getName(), new E4EventBrokerAdapter(e4EventBroker));
		if (sharedState != null) {
			services.put(ISharedStateContext.class.getName(), sharedState);
		}
		properties.put(IViewContext.PARAM_SERVICES, services);

		VaadinRenderer renderer = new VaadinRenderer();
		try {
			viewContext = renderer.render(layout, yView, properties);
			viewContext.createBeanSlot(BEAN_SLOT__VALIDATION_ERROR,
					Boolean.class);
			viewContext.setBean(BEAN_SLOT__VALIDATION_ERROR, Boolean.FALSE);
		} catch (ContextException e) {
			LOGGER.error("{}", e);
		}

		// bridges the validation from ECView core to Vaaclipse
		setupValidationBridge();

		// register a layout click listener to activate the part.
		layout.addLayoutClickListener(new LayoutEvents.LayoutClickListener() {
			@Override
			public void layoutClick(LayoutClickEvent event) {
				partService.activate(mPart);
			}
		});

		setupFocusFieldFeature();

		preparePartToolbar(yView);
	}

	/**
	 * Setup the focus-field feature. Handles events from event broker and tries
	 * to focus the element.
	 */
	protected void setupFocusFieldFeature() {
		// install an event handler that is responsible to focus elements
		EventHandler focusEventHandler = new EventHandler() {
			@Override
			public void handleEvent(Event event) {
				String partId = (String) event
						.getProperty(IE4Topics.PartEvents.PROP_MPART_ID);
				if (partId != null && partId.equals(mPart.getElementId())) {
					String fieldId = (String) event
							.getProperty(IE4Topics.PartEvents.PROP_FIELD_ID);
					if (fieldId != null && !fieldId.equals("")) {
						YEmbeddable yElement = (YEmbeddable) viewContext
								.findModelElement(fieldId);
						if (yElement instanceof YFocusable) {
							YView yView = (YView) viewContext.getViewEditpart()
									.getModel();
							yView.setCurrentFocus((YFocusable) yElement);
						}
					}
				}
			}
		};
		eventHandlers.add(focusEventHandler);

		e4EventBroker.subscribe(IE4Topics.PartEvents.FOCUS_FIELD_TOPIC,
				focusEventHandler);
	}

	/**
	 * Setup validation bridge.
	 */
	protected void setupValidationBridge() {
		// create a validation enhancer. If an error message is added to the
		// field validation manager. The enhancer will set the id of the mpart
		// to the status.
		ecviewFieldValidationManager = viewContext
				.getService(IFieldValidationManager.class.getName());
		ecviewFieldValidationManager
				.setEnhancer(new IFieldValidationManager.Enhancer() {
					@Override
					public void enhance(IStatus status) {
						status.putProperty(IStatus.PROP_UI_APPLICATION_ID,
								mPart.getElementId());
					}
				});

		ecviewFieldValidationManager.addListener(this);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.core.common.validation.IFieldValidationManager.Listener#validationChanged(org.eclipse.osbp.ecview.core.common.validation.IFieldValidationManager.Event)
	 */
	@Override
	public void validationChanged(IFieldValidationManager.Event event) {
		// add them to the Vaaclipse status manager
		IStatusScope scope = statusManager.getScopeFor(mPart);
		scope.modifyStatus(event.getOldStatus(), event.getNewStatus());

		applyValidationResult();
	}

	/**
	 * Remove defined event topics at bean slots. We pass them to custom
	 * handlers which will forward to the view. So we can avoid loosing changed
	 * data.
	 *
	 * @param yView
	 *            the y view
	 */
	private void redirectEventTopics(YView yView) {

		// redirect event topics
		redirectedEventtopics = new HashMap<String, Set<YBeanSlot>>();
		for (YBeanSlot yBeanSlot : yView.getBeanSlots()) {
			String eventTopic = yBeanSlot.getEventTopic();
			if (eventTopic != null && !eventTopic.trim().equals("")) {
				eventTopic = eventTopic.trim();

				// events will be forwarded by this view
				yBeanSlot.setRedirectEvents(true);

				Set<YBeanSlot> yRedirSlots = redirectedEventtopics
						.get(eventTopic);
				if (yRedirSlots == null) {
					yRedirSlots = new HashSet<YBeanSlot>();
					redirectedEventtopics.put(eventTopic, yRedirSlots);
				}
				yRedirSlots.add(yBeanSlot);
			}
		}

		if (redirectedEventtopics.size() > 0) {
			// install event handler for each redirected topic
			for (String eventTopic : redirectedEventtopics.keySet()) {
				// install the event handler
				EventHandler handler = new EventHandler() {
					@Override
					public void handleEvent(Event event) {
						dispatchEventBrokerEvent(event);
					}
				};

				e4EventBroker.subscribe(eventTopic, handler);
				eventHandlers.add(handler);
			}
		}
	}

	/**
	 * Save.
	 *
	 * @param commandId
	 *            the command id
	 */
	@Persist
	public void save(@Named("commandId") String commandId) {
		final Object mainDto = viewContext.getBean(IViewContext.MAIN_BEAN_SLOT);
		boolean processedProperly = false;
		try {
			if (mainDto != null) {
				new SharedStateUnitOfWork<Object>() {
					@Override
					protected Object doExecute() {
						dtoService.update(mainDto);
						return null;
					}
				}.execute(sharedState);
				// in case of exception, it is still false
				processedProperly = true;
			} else {
			}
		} finally {
			if (processedProperly) {
				notifyExecuted(toExposedAction(commandId));
			} else {
				notifyCanceled(toExposedAction(commandId));
			}
		}
	}

	/**
	 * To exposed action.
	 *
	 * @param commandId
	 *            the command id
	 * @return the y exposed action
	 */
	private YExposedAction toExposedAction(String commandId) {
		return commandInfo.get(commandId).action;
	}

	/**
	 * Validate.
	 *
	 * @param commandId
	 *            the command id
	 */
	@Validate
	public void validate(@Named("commandId") String commandId) {
		if (commandId != null) {

			Set<IStatus> oldValidationResult = validationResult != null ? new HashSet<IStatus>(
					validationResult) : new HashSet<IStatus>();

			final Object mainDto = viewContext
					.getBean(IViewContext.MAIN_BEAN_SLOT);
			validationResult = dtoService.validate(mainDto,
					ValidationKind.OTHER, null);

			for (IStatus status : validationResult) {
				// set the application id to the status
				status.putProperty(IStatus.PROP_UI_APPLICATION_ID,
						mPart.getElementId());

				if (status.containsProperty(IStatus.PROP_FIELD_ID)
						&& status.containsProperty(IStatus.PROP_FIELD_I18N_KEY)) {
					continue;
				}

				// fix the field id. Therefore we try to find the yField that is
				// bound to the property path of javax.validation result.
				if (!status.containsProperty(IStatus.PROP_FIELD_ID)) {
					if (status
							.containsProperty(IStatus.PROP_JAVAX_PROPERTY_PATH)) {
						String path = (String) status
								.getProperty(IStatus.PROP_JAVAX_PROPERTY_PATH);

						// if path points to a collection, then remove all the
						// collection stuff, since Vaadin can not focus rows
						if (path.matches(".*\\[\\d*\\].*")) {
							path = path.substring(0, path.indexOf("["));
						}

						// using a regex to find the yElement:
						// "beanslot/.*/{propertyPath}"
						YEmbeddable yElement = (YEmbeddable) viewContext
								.findBoundField(String.format("%s.*/%s",
										BindingIdUtil.BEANSLOT, path));
						if (yElement != null) {
							status.putProperty(IStatus.PROP_FIELD_ID,
									yElement.getId());
							status.putProperty(IStatus.PROP_FIELD_I18N_KEY,
									yElement.getLabelI18nKey());
						}
					}
				}
			}

			// now update the field with the new Status instances
			//
			for (IStatus status : oldValidationResult) {
				String fieldId = (String) status
						.getProperty(IStatus.PROP_FIELD_ID);
				if (fieldId != null && !fieldId.trim().equals("")) {
					YField yField = (YField) viewContext
							.findModelElement(fieldId);
					IFieldEditpart editpart = ModelUtil.findEditpart(yField);
					if (editpart != null) {
						editpart.removeExternalStatus(status);
					}
				}
			}

			for (IStatus status : validationResult) {
				String fieldId = (String) status
						.getProperty(IStatus.PROP_FIELD_ID);
				if (fieldId != null && !fieldId.trim().equals("")) {
					YField yField = (YField) viewContext
							.findModelElement(fieldId);
					IFieldEditpart editpart = ModelUtil.findEditpart(yField);
					if (editpart != null) {
						editpart.addExternalStatus(status);
					}
				}
			}

			statusManager.getScopeFor(mPart).modifyStatus(oldValidationResult,
					validationResult);

			notifyExternalClicked(toExposedAction(commandId));

			applyValidationResult();
		}
	}

	/**
	 * Apply the validation result to the view.
	 */
	protected void applyValidationResult() {
		// set the validation result
		viewContext.setBean(BEAN_SLOT__VALIDATION_ERROR, Boolean.FALSE);
		for (IStatus status : statusManager.getScopeFor(mPart).getAllStatus()) {
			if (status.isError()) {
				viewContext.setBean(BEAN_SLOT__VALIDATION_ERROR, Boolean.TRUE);
				break;
			}
		}
	}

	/**
	 * Gets the enabled state.
	 *
	 * @param commandId
	 *            the command id
	 * @return the enabled state
	 */
	@EnabledState
	public boolean getEnabledState(@Named("commandId") String commandId) {
		CommandInfo info = findCommandInfo(commandId);
		if (info == null) {
			return true;
		}
		return info.enabled;
	}

	/**
	 * Delete.
	 *
	 * @param commandId
	 *            the command id
	 */
	@Delete
	public void delete(@Named("commandId") final String commandId) {
		final Object mainDto = viewContext.getBean(IViewContext.MAIN_BEAN_SLOT);
		if (mainDto != null) {
			AcceptDeleteDialog.showDialog(i18nService, resourceProvider,
					new Runnable() {
						@Override
						public void run() {
							new SharedStateUnitOfWork<Object>() {
								@Override
								protected Object doExecute() {
									boolean processed = false;
									try {
										try {
											dtoService.delete(mainDto);
											// in case of exception, it is not
											// changed
											processed = true;
										} catch (DtoServiceException e) {
											// catch exception, show message and
											// return
											Notification.show("",
													e.getMessage(),
													Type.ERROR_MESSAGE);
										}
									} finally {
										if (processed) {
											notifyExecuted(toExposedAction(commandId));
										} else {
											notifyCanceled(toExposedAction(commandId));
										}
									}
									return null;
								}
							}.execute(sharedState);
						}
					}, new ActionCanceledAdapter(toExposedAction(commandId)));
		} else {
			notifyCanceled(toExposedAction(commandId));
		}
	}

	/**
	 * Notifies the action about cancel.
	 *
	 * @param yAction
	 *            the y action
	 */
	protected void notifyCanceled(final YExposedAction yAction) {
		ActionCanceledAdapter.notify(yAction);
	}

	/**
	 * Notifies the action about executed.
	 *
	 * @param yAction
	 *            the y action
	 */
	protected void notifyExecuted(final YExposedAction yAction) {
		ActionExecutedAdapter.notify(yAction);
	}

	/**
	 * Notifies the action about external clicked.
	 *
	 * @param yAction
	 *            the y action
	 */
	protected void notifyExternalClicked(final YExposedAction yAction) {
		ActionExternalClickedAdapter.notify(yAction);
	}

	/**
	 * Reload.
	 *
	 * @param commandId
	 *            the command id
	 */
	@Load
	public void reload(@Named("commandId") final String commandId) {
		final Object mainDto = viewContext.getBean(IViewContext.MAIN_BEAN_SLOT);
		if (mainDto != null) {
			boolean isDirty = false;
			try {
				isDirty = DtoUtils.isDirty(mainDto);
			} catch (IllegalAccessException e) {
				// nothing to do
			}

			// if there is no dirty indicator, or the record is not dirty,
			// reload the data
			if (!isDirty) {
				new SharedStateUnitOfWork<Object>() {
					@Override
					protected Object doExecute() {
						boolean processed = false;
						try {
							dtoService.reload(mainDto);
							// in case of exception, it is not changed
							processed = true;
						} finally {
							if (processed) {
								statusManager.getScopeFor(mPart).clearStatus();

								notifyExecuted(toExposedAction(commandId));
							} else {
								notifyCanceled(toExposedAction(commandId));
							}
						}
						return null;
					}
				}.execute(sharedState);
			} else {
				AcceptReloadDialog.showDialog(
						i18nService,
						resourceProvider,
						new Runnable() {
							@Override
							public void run() {
								new SharedStateUnitOfWork<Object>() {
									@Override
									protected Object doExecute() {
										boolean processed = false;
										try {
											dtoService.reload(mainDto);
											// in case of exception, it is not
											// changed
											processed = true;
										} finally {
											if (processed) {
												statusManager
														.getScopeFor(mPart)
														.clearStatus();

												notifyExecuted(toExposedAction(commandId));
											} else {
												notifyCanceled(toExposedAction(commandId));
											}
										}
										return null;
									}
								}.execute(sharedState);
							}
						},
						new ActionCanceledAdapter(toExposedAction(commandId)));
			}
		} else {
			notifyCanceled(toExposedAction(commandId));
		}
	}

	/**
	 * If a command was executed, the original actionId from the ECView view
	 * (YView) will be passed here.
	 *
	 * @param yAction
	 *            the y action
	 */
	@Callback
	public void commandExecuted(YExposedAction yAction) {
		if (yAction != null) {
			// we are going to forward the execution of the action to the ecView
			// exposed action
			// final YExposedAction yAction = (YExposedAction) action;
			yAction.setExternalClickTime(new Date().getTime());

			// check if dto is dirty
			//
			boolean isDirty = false;
			final Object mainDto = viewContext
					.getBean(IViewContext.MAIN_BEAN_SLOT);
			if (mainDto != null) {
				try {
					isDirty = DtoUtils.isDirty(mainDto);
				} catch (IllegalAccessException e) {
					// nothing to do -> if there is not dirty flag, we ignore
					// this
				}
			}

			// to notify about executed or canceled state, first check if the
			// state is dirty
			if (isDirty && yAction.isCheckDirty()) {
				// show accept dialog
				AcceptLoosingDataDialog.showDialog(i18nService,
						resourceProvider, new ActionExecutedAdapter(yAction),
						new ActionCanceledAdapter(yAction));
			} else {
				notifyExecuted(yAction);
			}
		}
	}

	/**
	 * Prepares the toolbar for the view.
	 *
	 * @param yView
	 *            the y view
	 */
	private void preparePartToolbar(YView yView) {
		MToolBar mToolbar = mPart.getToolbar();
		clearToolbar(mToolbar);

		for (YExposedAction yAction : yView.getExposedActions()) {

			// register the exposed actions callback to handle enabled state
			yAction.eAdapters().add(exposedActionsCallback);

			MHandledToolItem toolItem = null;
			if (yAction.getExternalCommandId() == null) {
				toolItem = createToolItem(yAction,
						IE4Constants.COMMAND_DEFAULT_PART_CALLBACK,
						yAction.isInitialEnabled());
			} else if (yAction.getExternalCommandId() != null) {
				toolItem = createToolItem(yAction,
						yAction.getExternalCommandId(),
						yAction.isInitialEnabled());
			}

			if (toolItem != null) {
				mToolbar.getChildren().add(toolItem);
				// set default after rendering
				toolItem.setEnabled(yAction.isInitialEnabled());
			}
		}
	}

	/**
	 * Clear toolbar.
	 *
	 * @param mToolbar
	 *            the m toolbar
	 */
	protected void clearToolbar(MToolBar mToolbar) {
		// bug in Vaaclipse -> Iterate to remove all
		for (Iterator<MToolBarElement> iterator = mToolbar.getChildren()
				.iterator(); iterator.hasNext();) {
			iterator.next();
			iterator.remove();
		}
	}

	/**
	 * Creates handled tool items for the given exposed action and the
	 * commandId.
	 *
	 * @param yAction
	 *            the y action
	 * @param commandId
	 *            the command id
	 * @param initialEnabled
	 *            the initial enabled
	 * @return the m handled tool item
	 */
	private MHandledToolItem createToolItem(YExposedAction yAction,
			String commandId, boolean initialEnabled) {
		MCommand command = findCommand(mPart, commandId);
		if (command == null) {
			LOGGER.error("No action created for " + yAction.getId()
					+ " since command missing: " + commandId);
			return null;
		}

		MHandledToolItem toolItem = MMenuFactory.INSTANCE
				.createHandledToolItem();
		toolItem.setCommand(command);

		String keyBinding = keyBindingService.getKeyBindingString(mPart,
				commandId);
		String tooltip = i18nService.getValue(yAction.getLabelI18nKey(),
				Locale.getDefault());
		toolItem.setTooltip(tooltip + " " + keyBinding);
		toolItem.setIconURI(i18nService.getValue(yAction.getIcon(),
				Locale.getDefault()));
		toolItem.setVisible(true);
		toolItem.setToBeRendered(true);

		commandInfo.put(commandId, new CommandInfo(yAction, toolItem,
				initialEnabled, commandId));

		return toolItem;
	}

	/**
	 * Tries to find the command with the specified id.
	 *
	 * @param mPart
	 *            the m part
	 * @param id
	 *            the id
	 * @return the m command
	 */
	private MCommand findCommand(MPart mPart, String id) {
		EModelService modelService = eclipseContext.get(EModelService.class);
		List<MCommand> commands = modelService.findElements(
				eclipseContext.get(MApplication.class), id, MCommand.class,
				Collections.<String> emptyList());
		MCommand command = null;
		if (commands.size() > 0) {
			command = commands.get(0);
		}
		return command;
	}

	/**
	 * Dispose.
	 */
	@PreDestroy
	public void dispose() {
		try {
			if (redirectedEventtopics != null) {
				redirectedEventtopics.clear();
				redirectedEventtopics = null;
			}

			exposedActionsCallback = null;

			if (eventHandlers != null) {
				for (EventHandler handler : eventHandlers) {
					e4EventBroker.unsubscribe(handler);

				}
				eventHandlers.clear();
				eventHandlers = null;
			}

			if (viewContext != null) {
				viewContext.dispose();
			}

			if (ecviewFieldValidationManager != null) {
				ecviewFieldValidationManager.dispose();
				ecviewFieldValidationManager.removeListener(this);
				ecviewFieldValidationManager = null;
			}

		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	/**
	 * Dispatches events from the event broker to the proper bean slots.
	 *
	 * @param event
	 *            the event
	 */
	protected void dispatchEventBrokerEvent(final Event event) {
		if (redirectedEventtopics == null) {
			return;
		}
		final String eventTopic = topicNormalizer.unwrapTopic(event.getTopic());
		if (!redirectedEventtopics.containsKey(eventTopic)) {
			return;
		}

		final Object newBean = event.getProperty(IEventBroker.DATA);

		// create a runnable processing the set operations
		Runnable doRunnable = new Runnable() {
			@Override
			public void run() {

				resetStatus();

				for (YBeanSlot yBeanSlot : redirectedEventtopics
						.get(eventTopic)) {
					final ISlot slot = viewContext.getBeanSlot(yBeanSlot
							.getName());

					// TODO workaround for databinding -> New instance may be
					// polymorphic brother of the current instance. And if
					// binding
					// the new instance, numeric field will not become unbound.
					// So
					// lets set a new instance of current set instance before
					// setting the new entry.
					Object oldValue = slot.getValue();
					if (oldValue != null) {
						Class<?> valueClass = oldValue.getClass();
						try {
							// now all fields will become unbound from the
							// current
							// instance
							slot.setValue(valueClass.newInstance());
						} catch (Exception e) {
							LOGGER.warn("Could not reset the value by {}",
									valueClass.getName());
						}
					}

					slot.setValue(newBean);
				}
			}
		};

		if (isBeanslotDirty(eventTopic, newBean)) {
			// show an accept loosing data dialog
			AcceptLoosingDataDialog.showDialog(i18nService, resourceProvider,
					doRunnable, null);
		} else {
			doRunnable.run();
		}

	}

	/**
	 * Returns true, if one of the bean slots addressed by the eventTopic is
	 * dirty.
	 *
	 * @param eventTopic
	 *            the event topic
	 * @param newBean
	 *            the new bean
	 * @return true, if is beanslot dirty
	 */
	protected boolean isBeanslotDirty(String eventTopic, Object newBean) {
		boolean dirty = false;
		for (YBeanSlot yBeanSlot : redirectedEventtopics.get(eventTopic)) {
			final ISlot slot = viewContext.getBeanSlot(yBeanSlot.getName());
			Object currentBean = slot.getValue();
			if (currentBean != null && currentBean != newBean) {
				try {
					dirty = DtoUtils.isDirty(currentBean);
					if (dirty) {
						// dirty found and leave
						break;
					}
				} catch (IllegalAccessException e) {
					// if there is no dirty flag, we just ignore it
				}
			}
		}
		return dirty;
	}

	/**
	 * Resets the status in the status manager.
	 */
	protected void resetStatus() {
		statusManager.getScopeFor(mPart).clearStatus();
	}

	/**
	 * Forwards the enabled state to the e4 tool item.
	 */
	private class ExposedActionsCallback extends AdapterImpl {

		/* (non-Javadoc)
		 * @see org.eclipse.emf.common.notify.impl.AdapterImpl#notifyChanged(org.eclipse.emf.common.notify.Notification)
		 */
		@Override
		public void notifyChanged(org.eclipse.emf.common.notify.Notification msg) {
			if (msg.getEventType() == org.eclipse.emf.common.notify.Notification.SET) {
				if (msg.getFeature() == CoreModelPackage.Literals.YENABLE__ENABLED) {
					YExposedAction yAction = (YExposedAction) msg.getNotifier();
					CommandInfo info = findCommandInfo(yAction);
					if (info != null) {
						boolean newEnabled = msg.getNewBooleanValue();
						info.toolItem.setEnabled(newEnabled);
						info.enabled = newEnabled;
					}
				} else if (msg.getFeature() == CoreModelPackage.Literals.YEXPOSED_ACTION__INTERNAL_CLICK_TIME) {
					YExposedAction yAction = (YExposedAction) msg.getNotifier();
					CommandInfo info = findCommandInfo(yAction);
					if (info != null) {
						MHandledToolItem handledItem = (MHandledToolItem) info.toolItem;
						IPartItemExecutionService service = mPart.getContext()
								.get(IPartItemExecutionService.class);
						if (service != null
								&& service.canExecuteItem(handledItem)) {
							// notify the exposed action about the external
							// click
							yAction.setExternalClickTime(new Date().getTime());
							service.executeItem(handledItem);
						} else {
							// notify the action about the cancel
							ActionCanceledAdapter.notify(yAction);
						}
					}
				}
			}
		}
	}

	/**
	 * Notifies the action about a cancel.
	 */
	private static class ActionCanceledAdapter implements Runnable {
		
		/** The action. */
		private final YExposedAction action;

		/**
		 * Notify.
		 *
		 * @param action
		 *            the action
		 */
		public static void notify(YExposedAction action) {
			action.setCanceledNotificationTime(new Date().getTime());
		}

		/**
		 * Instantiates a new action canceled adapter.
		 *
		 * @param action
		 *            the action
		 */
		public ActionCanceledAdapter(YExposedAction action) {
			super();
			this.action = action;
		}

		/* (non-Javadoc)
		 * @see java.lang.Runnable#run()
		 */
		@Override
		public void run() {
			notify(action);
		}
	}

	/**
	 * Notifies the action about their proper execution.
	 */
	private static class ActionExecutedAdapter implements Runnable {
		
		/** The action. */
		private final YExposedAction action;

		/**
		 * Notify.
		 *
		 * @param action
		 *            the action
		 */
		public static void notify(YExposedAction action) {
			action.setExecutedNotificationTime(new Date().getTime());
		}

		/**
		 * Instantiates a new action executed adapter.
		 *
		 * @param action
		 *            the action
		 */
		public ActionExecutedAdapter(YExposedAction action) {
			super();
			this.action = action;
		}

		/* (non-Javadoc)
		 * @see java.lang.Runnable#run()
		 */
		@Override
		public void run() {
			notify(action);
		}
	}

	/**
	 * Notifies the action about the external click.
	 */
	private static class ActionExternalClickedAdapter implements Runnable {
		
		/** The action. */
		private final YExposedAction action;

		/**
		 * Notify.
		 *
		 * @param action
		 *            the action
		 */
		public static void notify(YExposedAction action) {
			action.setExternalClickTime(new Date().getTime());
		}

		/**
		 * Instantiates a new action external clicked adapter.
		 *
		 * @param action
		 *            the action
		 */
		@SuppressWarnings("unused")
		public ActionExternalClickedAdapter(YExposedAction action) {
			super();
			this.action = action;
		}

		/* (non-Javadoc)
		 * @see java.lang.Runnable#run()
		 */
		@Override
		public void run() {
			notify(action);
		}
	}

	/**
	 * A pojo to keep related objects together. Will be used by the
	 * GenericECViewPart and also by handlers to determine enabled state.
	 */
	private static class CommandInfo {

		/** The action. */
		private YExposedAction action;
		
		/** The tool item. */
		private MToolItem toolItem;
		
		/** The enabled. */
		// is used to return the enabled state for a request from handler
		private boolean enabled;
		
		/** The command id. */
		private String commandId;

		/**
		 * Instantiates a new command info.
		 *
		 * @param action
		 *            the action
		 * @param toolItem
		 *            the tool item
		 * @param enabled
		 *            the enabled
		 * @param commandId
		 *            the command id
		 */
		public CommandInfo(YExposedAction action, MToolItem toolItem,
				boolean enabled, String commandId) {
			super();
			this.action = action;
			this.toolItem = toolItem;
			this.enabled = enabled;
			this.commandId = commandId;
		}

	}

	/**
	 * Returns the command info for the given action.
	 *
	 * @param yAction
	 *            the y action
	 * @return the command info
	 */
	protected CommandInfo findCommandInfo(final YExposedAction yAction) {
		try {
			return commandInfo.values().stream()
					.filter(e -> e.action == yAction).findFirst().get();
		} catch (NoSuchElementException e) {
			return null;
		}
	}

	/**
	 * Returns the command info for the given toolItem.
	 *
	 * @param toolItem
	 *            the tool item
	 * @return the command info
	 */
	protected CommandInfo findCommandInfo(MToolBarElement toolItem) {
		try {
			return commandInfo.values().stream()
					.filter(e -> e.toolItem == toolItem).findFirst().get();
		} catch (NoSuchElementException e) {
			return null;
		}
	}

	/**
	 * Returns the command info for the given commandId.
	 *
	 * @param commandId
	 *            the command id
	 * @return the command info
	 */
	protected CommandInfo findCommandInfo(final String commandId) {
		return commandInfo.get(commandId);
	}

}
