/*******************************************************************************
 * Copyright (c) 2012 Rushan R. Gilmullin and others.
 * 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:
 *     Rushan R. Gilmullin - initial API and implementation
 *     Florian Pirchner - adjustings for osbp implementation
 *******************************************************************************/

package org.eclipse.osbp.vaaclipse.addons.app.webapp;

import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.HttpSession;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.RegistryFactory;
import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.core.di.extensions.EventUtils;
import org.eclipse.e4.core.services.contributions.IContributionFactory;
import org.eclipse.e4.core.services.events.IEventBroker;
import org.eclipse.e4.core.services.log.Logger;
import org.eclipse.e4.core.services.translation.TranslationProviderFactory;
import org.eclipse.e4.core.services.translation.TranslationService;
import org.eclipse.e4.ui.di.UISynchronize;
import org.eclipse.e4.ui.internal.workbench.ActiveChildLookupFunction;
import org.eclipse.e4.ui.internal.workbench.ActivePartLookupFunction;
import org.eclipse.e4.ui.internal.workbench.E4Workbench;
import org.eclipse.e4.ui.internal.workbench.E4XMIResourceFactory;
import org.eclipse.e4.ui.internal.workbench.ExceptionHandler;
import org.eclipse.e4.ui.internal.workbench.ModelServiceImpl;
import org.eclipse.e4.ui.internal.workbench.PlaceholderResolver;
import org.eclipse.e4.ui.internal.workbench.ReflectionContributionFactory;
import org.eclipse.e4.ui.internal.workbench.WorkbenchLogger;
import org.eclipse.e4.ui.model.application.MAddon;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.e4.ui.model.application.MApplicationFactory;
import org.eclipse.e4.ui.model.application.MContribution;
import org.eclipse.e4.ui.model.application.commands.impl.CommandsPackageImpl;
import org.eclipse.e4.ui.model.application.impl.ApplicationPackageImpl;
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.MPlaceholder;
import org.eclipse.e4.ui.model.application.ui.advanced.impl.AdvancedPackageImpl;
import org.eclipse.e4.ui.model.application.ui.basic.impl.BasicPackageImpl;
import org.eclipse.e4.ui.model.application.ui.impl.UiPackageImpl;
import org.eclipse.e4.ui.model.application.ui.menu.impl.MenuPackageImpl;
import org.eclipse.e4.ui.services.IServiceConstants;
import org.eclipse.e4.ui.services.internal.events.EventBroker;
import org.eclipse.e4.ui.workbench.IExceptionHandler;
import org.eclipse.e4.ui.workbench.IModelResourceHandler;
import org.eclipse.e4.ui.workbench.lifecycle.PostContextCreate;
import org.eclipse.e4.ui.workbench.lifecycle.ProcessAdditions;
import org.eclipse.e4.ui.workbench.lifecycle.ProcessRemovals;
import org.eclipse.e4.ui.workbench.modeling.EModelService;
import org.eclipse.e4.ui.workbench.modeling.EPlaceholderResolver;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.equinox.app.IApplicationContext;
import org.eclipse.osbp.runtime.common.session.ISession;
import org.eclipse.osbp.runtime.web.vaadin.databinding.VaadinObservables;
import org.eclipse.osbp.ui.api.perspective.IPerspectiveProvider;
import org.eclipse.osbp.ui.api.user.IUser;
import org.eclipse.osbp.vaaclipse.addons.app.VaadinE4Application;
import org.eclipse.osbp.vaaclipse.addons.app.converter.VaaclipseConverterFactory;
import org.eclipse.osbp.vaaclipse.addons.app.servlet.VaadinExecutorServiceImpl;
import org.eclipse.osbp.vaaclipse.addons.app.session.VaaclipseSession;
import org.eclipse.osbp.vaaclipse.addons.common.api.resource.ICustomizedModelResourceHandler;
import org.eclipse.osbp.vaaclipse.addons.common.api.resource.ISystemuserModelHandler;
import org.eclipse.osbp.vaaclipse.addons.common.resource.LayoutChangedObserver;
import org.eclipse.osbp.vaaclipse.api.VaadinExecutorService;
import org.eclipse.osbp.vaaclipse.publicapi.authentication.AuthenticationConstants;
import org.eclipse.osbp.vaaclipse.publicapi.debug.IOwningWorkspaceAccess;
import org.eclipse.osbp.vaaclipse.publicapi.events.IWidgetModelAssociations;
import org.eclipse.osbp.vaaclipse.publicapi.theme.Theme;
import org.eclipse.osbp.vaaclipse.publicapi.theme.ThemeConstants;
import org.eclipse.osgi.service.datalocation.Location;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.event.EventHandler;

import com.vaadin.annotations.Push;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinSession;
import com.vaadin.server.WrappedHttpSession;
import com.vaadin.ui.ComponentContainer;
import com.vaadin.ui.UI;
import com.vaadin.ui.UIDetachedException;
import com.vaadin.ui.VerticalLayout;

/**
 * The Class VaadinUI.
 */
@SuppressWarnings("restriction")
@Push
public class VaadinUI extends UI {

	/** The Constant serialVersionUID. */
	private static final long serialVersionUID = 1L;

	/** The Constant THEME_ID. */
	public static final String THEME_ID = "cssTheme";

	/**
	 * This UI uses a different default resource handler.
	 */
	private static final String DEFAULT_RESOURCE_HANDLER = "bundleclass://org.eclipse.osbp.vaaclipse.addons.common/org.eclipse.osbp.vaaclipse.addons.common.resource.ResourceHandler";

	/** The Constant CUSTOMIZED_MODEL_SERVICE. */
	private static final String CUSTOMIZED_MODEL_SERVICE = "bundleclass://org.eclipse.osbp.vaaclipse.addons.common/org.eclipse.osbp.vaaclipse.addons.common.resource.SystemuserModelHandler";

	/** The presentation engine uri. */
	protected static String presentationEngineURI = "bundleclass://org.eclipse.osbp.vaaclipse.presentation/"
			+ "org.eclipse.osbp.vaaclipse.presentation.engine.VaadinPresentationEngine";

	/** The logger. */
	protected Logger logger;

	/** The args. */
	private String[] args;

	/** The model resource handler. */
	private ICustomizedModelResourceHandler modelResourceHandler;

	/** The e4 workbench. */
	private E4Workbench e4Workbench;

	/** The instance location. */
	private Location instanceLocation;

	/** The context. */
	private IApplicationContext context;

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

	/** The lc manager. */
	private Object lcManager;

	/** The app context. */
	private IEclipseContext appContext;

	/** The factory. */
	private IContributionFactory factory;

	/** The user. */
	private IUser user;

	/** The user class. */
	private Class<Object> userClass;

	/** The executor service. */
	private VaadinExecutorServiceImpl executorService;

	/** The layout changed observer. */
	private LayoutChangedObserver layoutChangedObserver;

	private ServiceRegistration<ISession> sessionReg;

	/** The temp user store. */
	private static Map<String, Object[]> tempUserStore = new HashMap<String, Object[]>();
	
	private static List<String> addOns = new ArrayList<String>() {
		private static final long serialVersionUID = 1L;
	{
		add("bundleclass://org.eclipse.osbp.vaaclipse.addons.softwarefactory/org.eclipse.osbp.vaaclipse.addons.softwarefactory.service.OSBPServiceAddon");
		add("bundleclass://org.eclipse.e4.core.commands/org.eclipse.e4.core.commands.CommandServiceAddon");
		add("bundleclass://org.eclipse.e4.ui.services/org.eclipse.e4.ui.services.ContextServiceAddon");
		add("bundleclass://org.eclipse.e4.ui.bindings/org.eclipse.e4.ui.bindings.BindingServiceAddon");
		add("bundleclass://org.eclipse.e4.ui.workbench/org.eclipse.e4.ui.internal.workbench.addons.CommandProcessingAddon");
		add("bundleclass://org.eclipse.e4.ui.workbench/org.eclipse.e4.ui.internal.workbench.addons.HandlerProcessingAddon");
		add("bundleclass://org.eclipse.e4.ui.workbench/org.eclipse.e4.ui.internal.workbench.addons.ContextProcessingAddon");
		add("bundleclass://org.eclipse.osbp.vaaclipse.emf.addon/org.eclipse.osbp.vaaclipse.addon.EMFAddon");
		add("bundleclass://org.eclipse.osbp.vaaclipse.addons.keybinding/org.eclipse.osbp.vaaclipse.addons.keybinding.KeyBindingServiceAddon");
	}};

	/**
	 * Instantiates a new vaadin ui.
	 */
	public VaadinUI() {
	}

	/**
	 * Gets the root context.
	 *
	 * @return the root context
	 */
	public IEclipseContext getRootContext() {
		return appContext;
	}

	/**
	 * Sets the theme internal.
	 *
	 * @param themeId
	 *            the new theme internal
	 */
	private void setThemeInternal(String themeId) {
		super.setTheme(themeId);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.vaadin.ui.UI#init(com.vaadin.server.VaadinRequest)
	 */
	@Override
	public void init(VaadinRequest request) {
		initializeWorkbenchState(request);
	}

	/**
	 * Initializes the vaaclipse workbench.
	 * 
	 * @param request
	 */
	@SuppressWarnings({ "unchecked", "unused" })
	protected void initializeWorkbenchState(VaadinRequest request) {
		executorService = new VaadinExecutorServiceImpl();
		context = VaadinE4Application.getInstance().getAppContext();
		logger = VaadinE4Application.getInstance().getLogger();

		String sessionId = getSession().getSession().getId();
		Object[] prevUser = tempUserStore.remove(sessionId);
		if (prevUser != null) {
			this.user = (IUser) prevUser[0];
			this.userClass = (Class<Object>) prevUser[1];
		}

		// -------------------------------------
		prepareEnvironment(context);

		IEventBroker eventBroker = appContext.get(EventBroker.class);
		eventBroker.subscribe(ThemeConstants.Events.setThemeEvent, new EventHandler() {
			@Override
			public void handleEvent(org.osgi.service.event.Event event) {
				Theme theme = (Theme) event.getProperty(IEventBroker.DATA);
				if (theme != null) {
					HttpSession httpSession = ((WrappedHttpSession) getSession().getSession()).getHttpSession();
					httpSession.setAttribute(ThemeConstants.Attrubutes.themeid, theme.getId());
					setThemeInternal(theme.getWebId());
				}
			}
		});

		String authProvider = VaadinE4Application.getInstance().getApplicationAuthenticationProvider();

		if (authProvider == null || authProvider.trim().isEmpty()) {
			appContext.set(AuthenticationConstants.USER_ID, "Administrator");
			createAndRunWorkbench(request);
		} else {
			IContributionFactory contributionFactory = (IContributionFactory) appContext
					.get(IContributionFactory.class.getName());
			IEclipseContext authConext = appContext.createChild();

			VerticalLayout content = new VerticalLayout();
			content.setSizeFull();
			setContent(content);

			authConext.set(ComponentContainer.class, content);
			authConext.set(VerticalLayout.class, content);
			Object authProviderObj = contributionFactory.create(authProvider, authConext);
		}

		eventBroker.subscribe(AuthenticationConstants.Events.Authentication.name, new EventHandler() {
			@Override
			public void handleEvent(org.osgi.service.event.Event event) {

				user = (IUser) event.getProperty(EventUtils.DATA);
				userClass = (Class<Object>) event.getProperty(AuthenticationConstants.Events.Authentication.userClass);

				if (userClass == null && user != null) {
					userClass = (Class<Object>) user.getClass();
				}
				appContext.set(userClass, user);
				appContext.set(AuthenticationConstants.USER, user);

				if (user instanceof IUser) {
					appContext.set(AuthenticationConstants.USER_ID, ((IUser) user).getUserName());
				}

				if (e4Workbench != null) {
					String sessionId = getSession().getSession().getId();
					tempUserStore.put(sessionId, new Object[] { user, userClass });
					e4Workbench.close();
				} else {
					if (user instanceof IUser) {
						// set the theme set in user_account
						String themeId = ((IUser) user).getTheme();
						if (themeId != null) {
							HttpSession httpSession = ((WrappedHttpSession) getSession().getSession()).getHttpSession();
							httpSession.setAttribute(ThemeConstants.Attrubutes.themeid, themeId);
							setThemeInternal(themeId.replaceAll("\\.", "-"));
						}
					}
					createAndRunWorkbench(request);
					if (user instanceof IUser) {
						// we need the application in case the user changes
						// locale and we must updateLocalizations
						user.setApplication((MApplication) appContext.get(MApplication.class.getName()));
						// if there is a default perspective set in user_account
						// - load it
						IPerspectiveProvider perspectiveProvider = appContext.get(IPerspectiveProvider.class);
						String perspectiveId = user.getPerspective();
						if (perspectiveId != null && !perspectiveId.isEmpty()) {
							perspectiveProvider.openPerspective(perspectiveId); 
						}
					}
				}

			}
		});

		// handle logout events
		//
		eventBroker.subscribe(AuthenticationConstants.Events.Authentication.LOGOUT, new EventHandler() {
			@Override
			public void handleEvent(org.osgi.service.event.Event event) {
				logout();
			}
		});

		executeLater();
	}

	/**
	 * Handles the logout process.
	 */
	protected void logout() {
		if (e4Workbench != null) {
			e4Workbench.close();
			e4Workbench = null;
		} else {
			close();
		}
	}

	/**
	 * Disposes the workbench state.
	 */
	protected void disposeWorkbenchState() {

		if (sessionReg != null) {
			sessionReg.unregister();
			sessionReg = null;
		}

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

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

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

		String sessionId = getSession().getSession().getId();
		tempUserStore.remove(sessionId);

		lcManager = null;
		modelResourceHandler = null;

		user = null;
		userClass = null;
		factory = null;
		args = null;
		id2element = null;
		instanceLocation = null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.vaadin.ui.UI#push()
	 */
	@Override
	public void push() {
		VaadinSession session = getSession();

		if (session == null) {
			throw new UIDetachedException("Cannot push a detached UI");
		}
		assert session.hasLock();

		if (!getPushConfiguration().getPushMode().isEnabled()) {
			throw new IllegalStateException("Push not enabled");
		}
		assert getPushConnection() != null;

		/*
		 * Purge the pending access queue as it might mark a connector as dirty
		 * when the push would otherwise be ignored because there are no changes
		 * to push.
		 */
		session.getService().runPendingAccessTasks(session);

		// execute the runnables for e4 kernel
		if (executorService != null) {
			executorService.exec();
		}

		if (!getConnectorTracker().hasDirtyConnectors()) {
			// Do not push if there is nothing to push
			return;
		}

		getPushConnection().push();
	}

	/**
	 * Is used to execute the runnables from executor service.
	 */
	public void executeLater() {
		VaadinExecutorServiceImpl man = (VaadinExecutorServiceImpl) appContext.get(VaadinExecutorService.class);
		man.exec();
	}

	/**
	 * Prepare environment.
	 *
	 * @param applicationContext
	 *            the application context
	 */
	public void prepareEnvironment(IApplicationContext applicationContext) {
		args = (String[]) applicationContext.getArguments().get(IApplicationContext.APPLICATION_ARGS);

		appContext = createDefaultContext(applicationContext);
		appContext.set("e4ApplicationInstanceId", UUID.randomUUID().toString());
		appContext.set("vaadinUI", this);
		appContext.set(UI.class, this);
		appContext.set(VaadinExecutorService.class, getExecutorService());
		appContext.set(ISession.Type.class, ISession.Type.MASTER);
		appContext.set(UISynchronize.class, new UISynchronize() {

			public void syncExec(Runnable runnable) {
				VaadinObservables.activateRealm(VaadinUI.this);
				VaadinUI.this.accessSynchronously(runnable);
			}

			public void asyncExec(Runnable runnable) {
				VaadinObservables.activateRealm(VaadinUI.this);
				VaadinUI.this.access(runnable);
			}
		});

		factory = (IContributionFactory) appContext.get(IContributionFactory.class.getName());

		// Install the life-cycle manager for this session if there's one
		// defined
		String lifeCycleURI = getArgValue(E4Workbench.LIFE_CYCLE_URI_ARG, applicationContext, false);
		if (lifeCycleURI != null) {
			lcManager = factory.create(lifeCycleURI, appContext);
			if (lcManager != null) {
				// Let the manager manipulate the appContext if desired
				ContextInjectionFactory.invoke(lcManager, PostContextCreate.class, appContext, null);
			}
		}

		// setup the widgetToModel-associations
		appContext.set(IWidgetModelAssociations.class,
				ContextInjectionFactory.make(WidgetModelAssociations.class, appContext));

		// setup a new converterFactory to handle the "default" date formatting
		// without time part
		getSession().setConverterFactory(new VaaclipseConverterFactory());
	}

	/**
	 * Gets the executor service.
	 *
	 * @return the executor service
	 */
	private VaadinExecutorService getExecutorService() {
		return executorService;
	}

	/**
	 * Creates the e4 workbench.
	 *
	 * @param applicationContext
	 *            the application context
	 * @return the e4 workbench
	 */
	public E4Workbench createE4Workbench(IApplicationContext applicationContext) {
		// Create the app model and its context
		MApplication appModel = loadApplicationModel(applicationContext, appContext);
		fixNullElementIds(appModel);
		appModel.setContext(appContext);
		appContext.set(MApplication.class.getName(), appModel);

		// ContextInjectionFactory.setDefault(appContext);
		if (lcManager != null) {
			ContextInjectionFactory.invoke(lcManager, ProcessAdditions.class, appContext, null);
			ContextInjectionFactory.invoke(lcManager, ProcessRemovals.class, appContext, null);
		}
		// Create the addons
//		for (MContribution addon : appModel.getAddons()) {
//			Object obj = factory.create(addon.getContributionURI(), appContext);
//			addon.setObject(obj);
//		}
		
		// Create pre-defined addOns and discard the model
		for (String contributionUri : addOns) {
			MAddon addon = MApplicationFactory.INSTANCE.createAddon();
			addon.setContributionURI(contributionUri);
			addon.setElementId(UUID.randomUUID().toString());
			Object obj = factory.create(addon.getContributionURI(), appContext);
			addon.setObject(obj);
		}

		return new E4Workbench(appModel, appContext);
	}

	/**
	 * Fix null element ids.
	 *
	 * @param element
	 *            the element
	 */
	private void fixNullElementIds(MUIElement element) {
		if (!(element instanceof MApplication)) {
			if (element.getElementId() == null || element.getElementId().trim().isEmpty()) {
				element.setElementId(UUID.randomUUID().toString());
			} else {
				if (element instanceof MPlaceholder) {
					// NOTHING TO DO - We must not touch the ID. Otherwise parts
					// can not be wired for the #reference after cloning.
					logger.debug("Skip fixing ID for " + element);
				} else if (isInSharedArea(element)) {
					// NOTHING TO DO - We must not touch the ID
					logger.debug("Skip fixing ID for " + element);
				} else {
					// check that there are not element in model with this id
					// MUIElement someElement =
					// modelService.find(element.getElementId(), app); //this
					// search
					// recursive - very long, so use map
					MUIElement someElement = id2element.get(element.getElementId());
					if (someElement != null && someElement != element) {
						final String randomUUID = UUID.randomUUID().toString();
						element.setElementId(element.getElementId() + "_" + randomUUID);
					}
				}
			}

			id2element.put(element.getElementId(), element);
		}

		if (element instanceof MElementContainer<?>) {
			for (MUIElement child : ((MElementContainer<?>) element).getChildren()) {
				fixNullElementIds(child);
			}
		}
	}

	/**
	 * Checks if is in shared area.
	 *
	 * @param element
	 *            the element
	 * @return true, if is in shared area
	 */
	private boolean isInSharedArea(MUIElement element) {
		EModelService modelService = appContext.get(EModelService.class);
		int location = modelService.getElementLocation(element);
		if ((location & EModelService.IN_SHARED_AREA) != 0) {
			return true;
		}
		return false;
	}

	/**
	 * Load application model.
	 *
	 * @param appContext
	 *            the app context
	 * @param eclipseContext
	 *            the eclipse context
	 * @return the m application
	 */
	@SuppressWarnings({ "unused", "deprecation" })
	private MApplication loadApplicationModel(IApplicationContext appContext, IEclipseContext eclipseContext) {
		logger.debug("VaadinE4Application.loadApplicationModel()");
		MApplication theApp = null;

		RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean();
		List<String> arguments = runtimeMxBean.getInputArguments();
		if(arguments.contains("-XstartOnFirstThread")) {
			throw new RuntimeException("Please remove the -XstartOnFirstThread for Mac-OS from launch configuration. Else OSBP will crash.");
		}
		
		instanceLocation = VaadinE4Application.getInstance().getInstanceLocation();

		String appModelPath = getArgValue(E4Workbench.XMI_URI_ARG, appContext, false);
		Assert.isNotNull(appModelPath, E4Workbench.XMI_URI_ARG + " argument missing"); //$NON-NLS-1$
		final URI initialWorkbenchDefinitionInstance = URI.createPlatformPluginURI(appModelPath, true);

		eclipseContext.set(E4Workbench.INITIAL_WORKBENCH_MODEL_URI, initialWorkbenchDefinitionInstance);
		eclipseContext.set(E4Workbench.INSTANCE_LOCATION, instanceLocation);

		// in debug mode, this value may be used to access the launching
		// workspace location
		String debugOwnerPath = getArgValue(IOwningWorkspaceAccess.DEBUG_OWNER_WORKSPACE_LOCATION, appContext, false);
		if (debugOwnerPath != null && !debugOwnerPath.trim().equals("")) {
			final URI debugOwnerPathURI = URI.createFileURI(debugOwnerPath);
			eclipseContext.set(IOwningWorkspaceAccess.DEBUG_OWNER_WORKSPACE_LOCATION, debugOwnerPathURI);
		}

		// Save and restore
		boolean saveAndRestore;
		String value = getArgValue(E4Workbench.PERSIST_STATE, appContext, false);

		saveAndRestore = value == null || Boolean.parseBoolean(value);

		eclipseContext.set(E4Workbench.PERSIST_STATE, true);

		// Persisted state
		boolean clearPersistedState;
		value = getArgValue(E4Workbench.CLEAR_PERSISTED_STATE, appContext, true);
		clearPersistedState = value != null && Boolean.parseBoolean(value);
		eclipseContext.set(E4Workbench.CLEAR_PERSISTED_STATE, false);

		// Delta save and restore
		// boolean deltaRestore;
		// value = getArgValue(E4Workbench.DELTA_RESTORE, appContext, false);
		// deltaRestore = value == null || Boolean.parseBoolean(value);
		// eclipseContext.set(E4Workbench.DELTA_RESTORE,
		// Boolean.valueOf(deltaRestore));

		registerResourceSet(eclipseContext);

		IContributionFactory factory = eclipseContext.get(IContributionFactory.class);

		// create the customized model service
		ISystemuserModelHandler service = (ISystemuserModelHandler) factory.create(CUSTOMIZED_MODEL_SERVICE,
				eclipseContext);
		eclipseContext.set(ISystemuserModelHandler.class, service);

		String resourceHandler = getArgValue(E4Workbench.MODEL_RESOURCE_HANDLER, appContext, false);

		if (resourceHandler == null) {
			resourceHandler = DEFAULT_RESOURCE_HANDLER;
		}

		modelResourceHandler = (ICustomizedModelResourceHandler) factory.create(resourceHandler, eclipseContext);
		eclipseContext.set(IModelResourceHandler.class, modelResourceHandler);
		eclipseContext.set(ICustomizedModelResourceHandler.class, modelResourceHandler);

		Resource resource = modelResourceHandler.loadMostRecentModel();
		theApp = (MApplication) resource.getContents().get(0);

		return theApp;
	}

	/**
	 * Registers the model resource set at the eclipse context.
	 *
	 * @param eclipseContext
	 *            the eclipse context
	 */
	private void registerResourceSet(IEclipseContext eclipseContext) {
		ResourceSet resourceSetImpl = new ResourceSetImpl();
		resourceSetImpl.getResourceFactoryRegistry().getExtensionToFactoryMap()
				.put(Resource.Factory.Registry.DEFAULT_EXTENSION, new E4XMIResourceFactory());
		resourceSetImpl.getPackageRegistry().put(ApplicationPackageImpl.eNS_URI, ApplicationPackageImpl.eINSTANCE);
		resourceSetImpl.getPackageRegistry().put(CommandsPackageImpl.eNS_URI, CommandsPackageImpl.eINSTANCE);
		resourceSetImpl.getPackageRegistry().put(UiPackageImpl.eNS_URI, UiPackageImpl.eINSTANCE);
		resourceSetImpl.getPackageRegistry().put(MenuPackageImpl.eNS_URI, MenuPackageImpl.eINSTANCE);
		resourceSetImpl.getPackageRegistry().put(BasicPackageImpl.eNS_URI, BasicPackageImpl.eINSTANCE);
		resourceSetImpl.getPackageRegistry().put(AdvancedPackageImpl.eNS_URI, AdvancedPackageImpl.eINSTANCE);
		resourceSetImpl.getPackageRegistry().put(
				org.eclipse.e4.ui.model.application.descriptor.basic.impl.BasicPackageImpl.eNS_URI,
				org.eclipse.e4.ui.model.application.descriptor.basic.impl.BasicPackageImpl.eINSTANCE);

		eclipseContext.set(ResourceSet.class, resourceSetImpl);
		eclipseContext.set("e4ModelResourceset", resourceSetImpl);
	}

	/**
	 * Gets the arg value.
	 *
	 * @param argName
	 *            the arg name
	 * @param appContext
	 *            the app context
	 * @param singledCmdArgValue
	 *            the singled cmd arg value
	 * @return the arg value
	 */
	private String getArgValue(String argName, IApplicationContext appContext, boolean singledCmdArgValue) {
		// Is it in the arg list ?
		if (argName == null || argName.length() == 0) {
			return null;
		}

		if (singledCmdArgValue) {
			for (int i = 0; i < args.length; i++) {
				if (("-" + argName).equals(args[i])) {
					return "true";
				}
			}
		} else {
			for (int i = 0; i < args.length; i++) {
				if (("-" + argName).equals(args[i]) && i + 1 < args.length) {
					return args[i + 1];
				}
			}
		}

		final String brandingProperty = appContext.getBrandingProperty(argName);
		return brandingProperty == null ? System.getProperty(argName) : brandingProperty;
	}

	/**
	 * Creates the default context.
	 *
	 * @param applicationContext
	 *            the application context
	 * @return the i eclipse context
	 */
	@SuppressWarnings("unchecked")
	public IEclipseContext createDefaultContext(IApplicationContext applicationContext) {
		IEclipseContext serviceContext = E4Workbench.getServiceContext();
		final IEclipseContext appContext = serviceContext.createChild("WorkbenchContext"); //$NON-NLS-1$

		IExtensionRegistry registry = RegistryFactory.getRegistry();
		ReflectionContributionFactory contributionFactory = new ReflectionContributionFactory(registry);
		appContext.set(IContributionFactory.class.getName(), contributionFactory);

		appContext.set(Logger.class.getName(), ContextInjectionFactory.make(WorkbenchLogger.class, appContext));

		String presentationURI = getArgValue(E4Workbench.PRESENTATION_URI_ARG, applicationContext, false);
		if (presentationURI == null) {
			presentationURI = presentationEngineURI;
		}
		appContext.set(E4Workbench.PRESENTATION_URI_ARG, presentationURI);
		appContext.set(UI.class, this);

		appContext.set(EPlaceholderResolver.class, new PlaceholderResolver());

		if (user != null) {
			if (userClass == null) {
				userClass = (Class<Object>) user.getClass();
			}
			appContext.set(userClass, user);
			appContext.set("user", user);
		}

		String themeId = getArgValue(THEME_ID, applicationContext, false);
		appContext.set(THEME_ID, themeId);

		// if (themeId != null && !themeId.equals("")) {
		// setTheme(themeId);
		// } else {
		// setTheme(ValoTheme.THEME_NAME);
		// }

		String cssURI = getArgValue(E4Workbench.CSS_URI_ARG, applicationContext, false);
		if (cssURI != null) {
			appContext.set(E4Workbench.CSS_URI_ARG, cssURI);
		}

		// Temporary to support old property as well
		if (cssURI != null && !cssURI.startsWith("platform:")) {
			logger.warn("Warning " + cssURI + " changed its meaning it is used now to run without theme support");
			appContext.set(THEME_ID, cssURI);
		}

		String cssResourcesURI = getArgValue(E4Workbench.CSS_RESOURCE_URI_ARG, applicationContext, false);
		appContext.set(E4Workbench.CSS_RESOURCE_URI_ARG, cssResourcesURI);

		appContext.set(EModelService.class, new ModelServiceImpl(appContext));

		// translation
		serviceContext.set(TranslationService.LOCALE, getLocale());
		logger.debug("Setting locale to " + getLocale().toLanguageTag());
		TranslationService bundleTranslationProvider = TranslationProviderFactory
				.bundleTranslationService(serviceContext);
		serviceContext.set(TranslationService.class, bundleTranslationProvider);

		ExceptionHandler exceptionHandler = new ExceptionHandler();
		appContext.set(IExceptionHandler.class.getName(), exceptionHandler);
		appContext.set(IExtensionRegistry.class.getName(), registry);

		// setup for commands and handlers
		appContext.set(IServiceConstants.ACTIVE_PART, new ActivePartLookupFunction());

		appContext.set(IServiceConstants.ACTIVE_SHELL,
				new ActiveChildLookupFunction(IServiceConstants.ACTIVE_SHELL, E4Workbench.LOCAL_ACTIVE_SHELL));

		return appContext;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.vaadin.ui.UI#detach()
	 */
	@Override
	public void detach() {
		if (e4Workbench != null) {
			e4Workbench.close();
			e4Workbench = null;
		}

		disposeWorkbenchState();

		super.detach();
	}

	/**
	 * Creates the and run workbench.
	 * 
	 * @param request
	 */
	protected void createAndRunWorkbench(VaadinRequest request) {
		e4Workbench = createE4Workbench(context);
		e4Workbench.createAndRunUI(e4Workbench.getApplication());

		// register the layout changed observer when application was started
		layoutChangedObserver = ContextInjectionFactory.make(LayoutChangedObserver.class,
				e4Workbench.getApplication().getContext());
		e4Workbench.getApplication().getContext().set(LayoutChangedObserver.class, layoutChangedObserver);

		registerSessionService(request);
	}

	/**
	 * Registers the session service.
	 * 
	 * @param request
	 */
	private void registerSessionService(VaadinRequest request) {
		BundleContext bc = FrameworkUtil.getBundle(getClass()).getBundleContext();

		Dictionary<String, Object> dictionary = new Hashtable<>();
		dictionary.put("vaadinUIId", Integer.toString(getUIId()));
		String instanceId = (String) appContext.get("e4ApplicationInstanceId");
		if (instanceId != null) {
			dictionary.put("e4SessionId", instanceId);
		}
		IUser user = (IUser) appContext.get("user");
		if (user != null) {
			dictionary.put("userName", user.getUserName());
		}
		Locale locale = (Locale) appContext.get(TranslationService.LOCALE);
		if (locale != null) {
			dictionary.put("locale", locale.toLanguageTag());
		}

		try {
			InetAddress netAddress = InetAddress.getByName(getPage().getWebBrowser().getAddress());
			String hostName = netAddress.getHostName();
			appContext.set("ip", hostName);
		} catch (UnknownHostException e) {
			logger.error("{}", e);
		}

		appContext.set(ISession.Type.class, ISession.Type.MASTER);

		sessionReg = bc.registerService(ISession.class, new VaaclipseSession(this, appContext, null), dictionary);
	}
}
