/**
 *                                                                            
 * Copyright (c) 2011, 2016 - 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:   
 * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation 
 */
package org.eclipse.osbp.osgi.hybrid.api;

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.net.URI;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
import java.util.UUID;

import javax.imageio.ImageIO;

import org.apache.commons.codec.binary.Hex;
import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URLEncodedUtils;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.e4.ui.model.application.ui.MUIElement;
import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective;
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
import org.eclipse.e4.ui.workbench.modeling.EModelService;
import org.eclipse.e4.ui.workbench.modeling.EPartService;
import org.eclipse.osbp.dsl.common.datatypes.IDto;
import org.eclipse.osbp.osgi.hybrid.api.IEventForNextRefresh.FocusPerspective;
import org.eclipse.osbp.osgi.hybrid.api.IEventForNextRefresh.TryToAuthenticate;
import org.eclipse.osbp.preferences.ProductConfiguration;
import org.eclipse.osbp.ui.api.themes.IThemeResourceService;
import org.eclipse.osbp.ui.api.useraccess.AbstractAuthorization.Permission;
import org.eclipse.osbp.ui.api.useraccess.AbstractAuthorization.PermissionResult;
import org.eclipse.osbp.ui.api.useraccess.AbstractPosition;
import org.eclipse.osbp.ui.api.useraccess.IPermissionList;
import org.eclipse.osbp.ui.api.useraccess.IUserAccessService;
import org.eclipse.osbp.utils.session.VaadinSessionAttributes;
import org.eclipse.osbp.webserver.messagequeue.CXMqConsumer;
import org.eclipse.osbp.webserver.messagequeue.CXMqMessagePerspectiveData;
import org.eclipse.osbp.webserver.messagequeue.ECXMqMessageAttribute;
import org.eclipse.osbp.webserver.messagequeue.ECXMqMessageEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.github.wolfie.refresher.Refresher;
import com.github.wolfie.refresher.Refresher.RefreshListener;
import com.vaadin.server.AbstractClientConnector;
import com.vaadin.server.Extension;
import com.vaadin.server.Page;
import com.vaadin.server.VaadinRequest;
import com.vaadin.ui.UI;

public class HybridVaadinVaaclipseConnector implements RefreshListener, IHybridVaadinVaaclipseListener {

	private static final long serialVersionUID = 7239729235615118954L;
	private static final Logger LOGGER = LoggerFactory.getLogger(HybridVaadinVaaclipseConnector.class);
	
	/**
	 * @param element to search the containing perspective
	 * @return the perspective
	 */
	public static MPerspective findCurrentPerspectiveFor(MUIElement element) {
		MPerspective perspective = null;
		if	(element != null) {
			if	(element instanceof MPerspective) {
				perspective = (MPerspective) element;
			}
			else {
				if  (element.getCurSharedRef() != null) {
					perspective = findCurrentPerspectiveFor(element.getCurSharedRef());
				}
				if  ((perspective == null) && (element.getParent() != null)) {
					perspective = findCurrentPerspectiveFor(element.getParent());
				}
			}
		}
		return perspective;
	}
	
	private final IEclipseContext fEclipseContext;
	private MApplication fE4Application;
	private String fLastFocusPerspectiveId = "";
	private Queue<Map<String,Object>> fLastListOfPerspectives = new LinkedList<Map<String,Object>>();
	private Queue<IEventForNextRefresh> fEventsForNextRefresh = null;
	private HybridPartStateRefresher fPartStateRefresher = null;
	private MPart fLastActivePart;
	private AbstractClientConnector fLastExtensionHolder;
	private boolean fPostInitForSessionHandled;
	private boolean fPostInitForAuthenticationHandled;
	private String fMqBrokerHost;
	private int fMqBrokerPort;
	private CXMqConsumer fMqConsumer;
	protected String fSessionId;
	private Set<IHybridVaadinVaaclipseListener> fListeners = new HashSet<IHybridVaadinVaaclipseListener>();

	private IThemeResourceService getThemeResourceService() {
		if (fEclipseContext.containsKey(IThemeResourceService.class)) {
			return fEclipseContext.get(IThemeResourceService.class);
		}
		return null;
	}
	
	private EPartService getPartService() {
		if (fEclipseContext.containsKey(EPartService.class)) {
			return fEclipseContext.get(EPartService.class);
		}
		return null;
	}

	private EModelService getModelService() {
		if (fEclipseContext.containsKey(EModelService.class)) {
			return fEclipseContext.get(EModelService.class);
		}
		return null;
	}

	/**
	 *  Send message via ActiveMQ
	 *  @param event
	 *  @param args
	 *  @see CXMqConsumer#sendMessage(ECXMqMessageEvent, Object...)
	 */
	public void sendMessage(ECXMqMessageEvent event, Object... args) {
		if	(fMqConsumer == null) {
			LOGGER.error("Messagequeue consumer is null");
		}
		else {
			fMqConsumer.sendMessage(event, args);
		}
	}

	/**
	 *  @return true if a refresher is already added to the one-and-only TrimmedWindowContent
	 */
	public boolean isTrimmedWindowContent() {
		return isTrimmedWindowContent(fLastExtensionHolder);
	}
	
	/**
	 *  @param component to be checked
	 *  @return true if the component is of instance TrimmedWindowContent
	 */
	public static boolean isTrimmedWindowContent(AbstractClientConnector component) {
		return ((component != null) && "org.eclipse.osbp.vaaclipse.presentation.widgets.TrimmedWindowContent".equals(component.getClass().getCanonicalName()));
	}
	
	@Override
	public void refresh(Refresher source) {
		// --- if not yet on TrimmedWindowContent ---
		if	(!isTrimmedWindowContent()) {
			// --- re-active a part state refresher ---
			activatePartStateRefresher();
		}
		// --- handle all events received via ActiveMq ---
		while	(!fEventsForNextRefresh.isEmpty()) {
			IEventForNextRefresh event = fEventsForNextRefresh.poll();
			if	(event instanceof TryToAuthenticate) {
				TryToAuthenticate tryToAuthenticate = (TryToAuthenticate) event;
				tryToAuthenticate(tryToAuthenticate.getPortalId(), tryToAuthenticate.getUserName(), tryToAuthenticate.getPassword());
			}
			if	(event instanceof FocusPerspective) {
				FocusPerspective focusPerspective = (FocusPerspective) event;
				String perspectiveId = focusPerspective.getSwitchingPerspective();
				switchPerspective(perspectiveId);
			}
		}
	}

	/**
	 *  Try to load the icon for the perspective and send it via ActiveMq back to the requester
	 *  @param perspectiveId the perspective whose icon is requested
	 *  @return always true, because the corresponding request has always been answered
	 */
	public boolean requestIcon(String perspectiveId) {
		MPerspective perspective = findPerspective(perspectiveId);
		if	(perspective != null) {
			String iconURI = perspective.getIconURI();
			String iconSerialized = null; // get the icon from resource;
			if	(getThemeResourceService() != null) {
				try {
					InputStream stream = getThemeResourceService().getThemeResourceInputStream(iconURI);
					String[] tokens = iconURI.split("\\.");
					String extension = tokens[tokens.length-1];
					BufferedImage originalImage = ImageIO.read(stream);
					ByteArrayOutputStream baos = new ByteArrayOutputStream();
					ImageIO.write(originalImage, extension, baos);
					baos.flush();
					byte[] imageInByte = baos.toByteArray();
					baos.close();
					iconSerialized = new String(Hex.encodeHex(imageInByte));
	//				byte[] h = Hex.decodeHex(iconSerialized.toCharArray());
				}
				catch (Exception e) {
					LOGGER.error(e.getLocalizedMessage());
				}
			}
			else {
				LOGGER.error("themeResourceService not set!");
			}
			if	(iconSerialized != null) {
				sendMessage(ECXMqMessageEvent.GET_ICON,
						ECXMqMessageAttribute.PERSPECTIVE_ID, perspectiveId,
						ECXMqMessageAttribute.ICON_URI, iconURI,
						ECXMqMessageAttribute.ICON_SERIALIZED, iconSerialized
				);
			}
		}
		return true;
	}

	/**
	 *  Try to bring the perspective to focus 
	 *  @param perspectiveId
	 *  @return true if it was possible, false otherwise
	 */
	public boolean onFocusPerspective(String perspectiveId) {
		boolean retcode = false;
		// --- if this perspective has already the focus ---
		if	(fLastFocusPerspectiveId.equals(perspectiveId)) {
			retcode = true;
		}
		// --- if no event queue is existing ---
		else if (fEventsForNextRefresh == null) {
			retcode = switchPerspective(perspectiveId);
		}
		// --- otherwise put it into the event queue to be handled inside the refresh method ---
		else {
			fEventsForNextRefresh.add(new FocusPerspective(perspectiveId));
			retcode = true;
		}
		return retcode;
	}

	/**
	 *  Try to bring the perspective to focus
	 * @param perspectiveId
	 * @return
	 */
	private boolean switchPerspective(String perspectiveId) {
		boolean retcode = false;
		// --- if this perspective hasn't already the focus ---
		if	(!fLastFocusPerspectiveId.equals(perspectiveId)) {
			MPerspective perspective = findPerspective(perspectiveId);
			// --- if the perspective exists ---
			if	(perspective != null) {
				try {
					/* ???
					// @see PerspectiveStackRenderer.processContents()
					MElementContainer<MUIElement> perspectiveStackElement = perspective.getParent();
					MPerspectiveStack perspectiveStack = (MPerspectiveStack)((MElementContainer<?>) perspectiveStackElement);
					perspectiveStack.setSelectedElement(perspective);
					HybridServiceBinder.processContents(perspectiveStack, perspectiveStackElement);
	//				for	(MWindow window : perspective.getWindows()) {
	//					partService.bringToTop(window);
	//					partService.activate(window);
	//				}
					partService.switchPerspective(perspective);
					??? */
					getModelService().bringToTop(perspective);
					fLastFocusPerspectiveId = perspectiveId;
					retcode = true;
				}
				catch (Exception e) {} // NOP
			}
		}
		return retcode;
	}

	/**
	 * @param modelService
	 * @param elementId
	 * @return the perspective found for elementId
	 */
	private MPerspective findPerspective(String elementId) {
		List<MPerspective> found = getModelService().findElements(fE4Application, elementId, MPerspective.class, null);
		if	((found != null) && (found.size() == 1)) {
			return found.get(0);
		}
		else {
			return null;
		}
	}

	/**
	 * @return the perspective found for elementId
	 */
	public List<MPerspective> findPerspectives() {
		return (getModelService().findElements(fE4Application, null, MPerspective.class, null));
	}

	/**
	 *  @return the connector instance for the current session
	 */
	public static HybridVaadinVaaclipseConnector instance(IEclipseContext eclipseContext) {
		HybridVaadinVaaclipseConnector instance = VaadinSessionAttributes.get(HybridVaadinVaaclipseConnector.class);
		if	(instance == null) {
			instance = new HybridVaadinVaaclipseConnector(eclipseContext);
			VaadinSessionAttributes.set(HybridVaadinVaaclipseConnector.class, instance);
		}
		return instance;
	}

	/**
	 *  Dispose the connector instance from the current session
	 */
	public static void dispose() {
		VaadinSessionAttributes.remove(HybridVaadinVaaclipseConnector.class);
	}
	
	public HybridVaadinVaaclipseConnector(IEclipseContext eclipseContext) {
		fEclipseContext = eclipseContext;
		fPostInitForSessionHandled = false;
		fPostInitForAuthenticationHandled = false;
		// --- get the adress of the Active Message Queue Broker ---
		fMqBrokerHost = ProductConfiguration.getActiveMqBrokerServerName();
		fMqBrokerPort = ProductConfiguration.getActiveMqBrokerServerPort();
	}

	/**
	 *  @return true if a refresher exists
	 */
	protected boolean refresherExisting() {
		return (fPartStateRefresher != null);
	}

	/**
	 *  re-create a refresher if it is needed and not yet added to a TrimmedWindowContent
	 */
	protected void activatePartStateRefresher() {
		if	((fMqConsumer != null) && !isTrimmedWindowContent() && (fLastActivePart != null)) {
			activatePartStateRefresher(fLastActivePart);
		}
	}

	/**
	 *  (re-)create a refresher for the MPart and not yet added to a TrimmedWindowContent
	 *  @param part
	 */
	protected void activatePartStateRefresher(MPart part) {
		fLastActivePart = part;
		// --- create the event queue if it doesn't exists yet ---
		if	(fEventsForNextRefresh == null) {
			fEventsForNextRefresh = new LinkedList<IEventForNextRefresh>();			
		}
		// --- no refresher if not connected to any hybrid ---
		if	(fMqConsumer == null) {
			return;
		}
		// --- no re-create refresher if it is already set on a TrimmedWindowContent ---
		if	(isTrimmedWindowContent()) {
			return;
		}
		if	(part != null) {
			Object object = part.getObject();
			// --- get the view connected to the MPart ---
			if	(object instanceof AbstractHybridVaaclipseView) {
				AbstractHybridVaaclipseView view = (AbstractHybridVaaclipseView) object;
				// --- get the parent component ---
				AbstractClientConnector parent = view.getParent();
				Method addExtension = null;
				AbstractClientConnector extensionHolder = null;
				try {
					// --- traverse the parents to get the topmost extension holder ---
					while  ((parent != null) && (parent.getParent() != null)) {
						try {
							// --- check each parent for ... ---
							for	(Class cls = parent.getClass(); cls != null; cls = cls.getSuperclass()) {
								try {
									// --- ... each extended class ... ---
									if  (cls.getDeclaredMethod("addExtension", Extension.class) != null) {
										// --- if it has a method addExtension(Extension) ---
										extensionHolder = parent;
										addExtension = cls.getDeclaredMethod("addExtension", Extension.class);
										break;
									}
								}
								catch (Exception e) {} // NOP
							}
						}
						catch (Exception e) {} // NOP
						// --- the parent ---
						parent = (AbstractClientConnector) parent.getParent();
						// --- if this instance is a TrimmedWindowContent itself ---
						if	(HybridVaadinVaaclipseConnector.isTrimmedWindowContent(extensionHolder)) {
							break;
						}
					}
					// --- if a possible extension holder was found ---
					if	(extensionHolder != null) {
						Collection<Extension> extensions = extensionHolder.getExtensions();
						for	(Extension extension : extensions) {
							// --- if it already has a refresher ---
							if	(extension instanceof HybridPartStateRefresher) {
								return;
							}
						}
						if	(addExtension != null) {
							// --- enable the accessability of the method ---
							addExtension.setAccessible(true);
							// --- generate a new refresher; they can't be moved to another parent ---
							fPartStateRefresher = new HybridPartStateRefresher(this);
							addExtension.invoke(extensionHolder, new Object[] { fPartStateRefresher });
							// --- remember the last active extension holder ---
							fLastExtensionHolder = extensionHolder;
						}
					}
				}
				catch (Exception e) {} // NOP
			}
		}
	}
	
	public void setE4Application(MApplication e4Application) {
		fE4Application = e4Application;
	}
	
	public IUserAccessService getUserAccessService() {
		return HybridServiceBinder.getUserAccessService();
	}
	
	public void addListener(IHybridVaadinVaaclipseListener listener) {
		if	(!fListeners.contains(listener)) {
			fListeners.add(listener);
			// --- inform the listener if the session is already authenticated ---
			listener.setAuthenticated(isAuthenticated());
		}
	}

	public void removeListener(IHybridVaadinVaaclipseListener listener) {
		fListeners.remove(listener);
	}

	public HybridCredentials getCredentials(boolean forceCheckForCredentials) {
		HybridCredentials credentials = null;
		// --- do it only once per session ---
		if	(forceCheckForCredentials || !fPostInitForAuthenticationHandled) {
			fPostInitForAuthenticationHandled = true;
			
			UI ui = UI.getCurrent();
			if	(ui != null) {
				Page page = ui.getPage();
				if	(page != null) {
					String developmentCredentialsParam = null;
					
					// --- get the starting URI --- 
					URI uri = page.getLocation();
					// --- extract all parameters ---
					List<NameValuePair> params = URLEncodedUtils.parse(uri, "UTF-8");
		
					for (NameValuePair param : params) {
						// --- if - in development mode - credentials are given ---
						if	("OSBEE_HYBRID_DEVELOPMENT_PASSWORD_NONE_CRYPTED".equals(param.getName())) {
							developmentCredentialsParam = param.getValue();
						}
					}
					if (developmentCredentialsParam != null) {
						try {
							String[] token = developmentCredentialsParam.split("@", 3);
							credentials = new HybridCredentials(token[0], token[1], token[2]);
						}
						catch (Exception e) {
						}
					}
				}
			}
		}			
		return credentials;
	}
	
	/**
	 * You <b>must call this  at the end of the overriden init()</b>
	 */
	public final void postInit(VaadinRequest request) {
		// --- do it only once per session ---
		if	(!fPostInitForSessionHandled) {
			fPostInitForSessionHandled = true;
			
			Page page = UI.getCurrent().getPage();
			if	(page != null) {
				String requestParam = null;
				
				// --- get the starting URI --- 
				URI uri = page.getLocation();
				// --- extract all parameters ---
				List<NameValuePair> params = URLEncodedUtils.parse(uri, "UTF-8");
	
				for (NameValuePair param : params) {
					// --- if the parameter request was used ---
					if	("request".equals(param.getName())) {
						requestParam = param.getValue();
					}
					else {
						LOGGER.debug(param.getName() + " : " + param.getValue());
					}
				}
				
				// --- if request, then only request ---
				if	(requestParam != null) {
					if	(requestParam.startsWith("tcp://")) {
						try {
							String[] mqBrokerInfo = requestParam.replace("tcp://", "").split("\\|")[0].split(":");
							if	(mqBrokerInfo.length == 2) {
								fMqBrokerHost = mqBrokerInfo[0];
								fMqBrokerPort = Integer.parseInt(mqBrokerInfo[1]);
							}
						}
						catch (Exception e) {}
					}
					// --- connect to the ActiveMQ and try to connect to the corresponding queuename ---
					fMqConsumer = new CXMqConsumer(
						fMqBrokerHost, fMqBrokerPort,
						requestParam,
						UUID.randomUUID().toString(),
						this,
						null
					);
					// TODO this should help out to wait long enough until the authentication is done
					// TODO there should be definitely a better wait for that!!!!
					// TODO see {@link #onMessage(ECXMqMessageEvent, Map<ECXMqMessageAttribute, Object>)}
					// ???? try {
					// ???? 	Thread.sleep(5000);
					// ???? } catch (InterruptedException e) {
					// ???? 	e.printStackTrace();
					// ???? }
				}
				else {
					try {
						HybridCredentials credentials = getCredentials(false);
						if	(credentials != null) {
							tryToAuthenticate(credentials.getPortalId(), credentials.getUserName(), credentials.getPassword());
						}
					}
					catch (Exception e) {
						LOGGER.error(e.getLocalizedMessage());
					}
				}
			}
		}
	}
	
	
	
	/**
	 * React in the application according to <code>authenticated</code>
	 * @param authenticated true if the user is authenticated now!
	 */
	@Deprecated
	public void setAuthenticated(boolean authenticated) {
		// @TODO to be overwritten
	}

	/**
	 * @return true if the actual session is authenticated
	 */
	public boolean isAuthenticated() {
		if 	(HybridServiceBinder.getUserAccessService() == null) {
			return false;
		}
		else {
			return HybridServiceBinder.getUserAccessService().isAuthenticated();
		}
	}

	/**
	 * @return the user instance for the authenticated session, otherwise null
	 */
	public IDto getUser() {
		if 	(HybridServiceBinder.getUserAccessService() == null) {
			return null;
		}
		else {
			return HybridServiceBinder.getUserAccessService().getUser();
		}
	}
	
	/**
	 * @return the position instance for the authenticated session, otherwise null
	 */
	public AbstractPosition getPosition() {
		if 	(HybridServiceBinder.getUserAccessService() == null) {
			return null;
		}
		else {
			return HybridServiceBinder.getUserAccessService().getPosition();
		}
	}
	
	/**
	 * @return the collection of roles for the authenticated session, otherwise null
	 */
	public Collection<String> getRoles() {
		if 	(HybridServiceBinder.getUserAccessService() == null) {
			return null;
		}
		else {
			return HybridServiceBinder.getUserAccessService().getRoles();
		}
	}
	
	/**
	 * @return the permission list for the authenticated session, otherwise null
	 */
	public IPermissionList getPermissions() {
		if 	(HybridServiceBinder.getUserAccessService() == null) {
			return null;
		}
		else {
			return HybridServiceBinder.getUserAccessService().getPermissions();
		}
	}

	/**
	 * @param permission the permission to be checked
	 * @return true if the permission is permitted for the actual session
	 */
	public PermissionResult isPermitted(Permission permission) {
		if 	(HybridServiceBinder.getUserAccessService() == null) {
			return null;
		}
		else {
			return HybridServiceBinder.getUserAccessService().isPermitted(permission);
		}
	}

	/**
	 * @return the list of all usernames; null will be returned if the session is not authenticated
	 */
	public Set<String> getAllUsers() {
		if	(!isAuthenticated()) {
			return null;
		}
		else {
			return HybridServiceBinder.getUserAccessService().getAllUsers();
		}
	}
	
	/**
	 * @param username name of the user
	 * @return the user instance for the username; null will be returned if the session is not authenticated
	 */
	public IDto findUserAccount(String username) {
		if	(!isAuthenticated()) {
			return null;
		}
		else {
			return HybridServiceBinder.getUserAccessService().findUserAccount(username);
		}
	}
	
	/**
	 * @param position to be checked
	 * @return the list of usernames connected to the position; null will be returned if the session is not authenticated
	 */
	public Set<String> findUsersForPosition(AbstractPosition position) {
		if	(!isAuthenticated()) {
			return null;
		}
		else {
			return findUsersForPosition(position.getName());
		}
	}
	
	/**
	 * @param orgNode name of the position to be checked
	 * @return the list of usernames connected to the position; null will be returned if the session is not authenticated
	 */
	public Set<String> findUsersForPosition(String orgNode) {
		if	(!isAuthenticated()) {
			return null;
		}
		else {
			return HybridServiceBinder.getUserAccessService().findUsersForPosition(orgNode);
		}
	}
	
	/**
	 * @return the list of all position instances; null will be returned if the session is not authenticated
	 */
	public Set<AbstractPosition> getAllPositions() {
		if	(!isAuthenticated()) {
			return null;
		}
		else {
			return HybridServiceBinder.getUserAccessService().getAllPositions();
		}
	}
	
	/**
	 * @param username name of the user
	 * @return the position instances for the user; null will be returned if the session is not authenticated
	 */
	public AbstractPosition findPositionForUser(String username) {
		if	(!isAuthenticated()) {
			return null;
		}
		else {
			return HybridServiceBinder.getUserAccessService().findPositionForUser(username);
		}
	}

	/**
	 * @param username name of the user
	 * @return the list of roles for the user; null will be returned if the session is not authenticated
	 */
	public Collection<String> findRolesForUser(String username) {
		if	(!isAuthenticated()) {
			return null;
		}
		else {
			return HybridServiceBinder.getUserAccessService().findRolesForUser(username);
		}
	}
	
	/**
	 * @param username name of the user
	 * @return the permission list for the user; null will be returned if the session is not authenticated
	 */
	public IPermissionList findPermissionsForUser(String username) {
		if	(!isAuthenticated()) {
			return null;
		}
		else {
			return HybridServiceBinder.getUserAccessService().findPermissionsForUser(username);
		}
	}
	
	/**
	 * Try to authenticate with the credentials given!<br>
	 * {@link #setAuthenticated(boolean)} will explicit be called!
	 * @param portalId
	 * @param userName
	 * @param password
	 * @return true if the user was authenticated successful
	 */
	boolean tryToAuthenticate(String portalId, String userName, String password) {
		boolean authenticated = isAuthenticated();
		if	(!authenticated) {
			try {
				authenticated = HybridServiceBinder.getUserAccessService().authenticate(portalId, userName, password);
			}
			catch (Exception e) {
				LOGGER.error(e.getLocalizedMessage());
			}
			for	(IHybridVaadinVaaclipseListener listener : fListeners) {
				listener.setAuthenticated(authenticated);
			}
		}
		return authenticated;
	}
	
	/**
	 * Logout from the Shiro API and send a LOGOUT event via ActiveMQ
	 */
	protected void logout() {
		if	(HybridServiceBinder.getUserAccessService() == null) {
		}
		else {
			HybridServiceBinder.getUserAccessService().logout();
		}
		if	(fMqConsumer != null) {
			fMqConsumer.sendMessage(ECXMqMessageEvent.LOGOUT);
		}
		for	(IHybridVaadinVaaclipseListener listener : fListeners) {
			listener.setAuthenticated(false);
		}
		dispose();
	}
	
	/**
	 *  Inform the hybrid client about the now focussed perspective
	 *  @param perspectiveId
	 */
	public final void updateFocusPerspective(String perspectiveId) {
		if	(fMqConsumer != null) {
			// --- only if the focussed perspective has changed ---
			if	(!fLastFocusPerspectiveId.equals(perspectiveId)) {
				fMqConsumer.sendMessage(ECXMqMessageEvent.FOCUS_PERSPECTIVE, ECXMqMessageAttribute.PERSPECTIVE_ID, perspectiveId);
			}
			fLastFocusPerspectiveId = perspectiveId;
		}
	}

	/**
	 *  @param q1
	 *  @param q2
	 *  @return true if both queues have identical content
	 */
	private final boolean compare(Queue<Map<String,Object>> q1, Queue<Map<String,Object>> q2) {
		try {
			if	(q1 == q2) {
				return true;
			}
			if	(q1.size() != q2.size()) {
				return false;
			}
			else {
				Object[] a1 = q1.toArray();
				Object[] a2 = q2.toArray();
				for	(int i=0; i<q1.size(); i++) {
					if	(!a1[i].equals(a2[i])) {
						return false;
					}
				}
			}
			return true;
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}
	
	/**
	 *  Inform the hybrid client about all available perspectives
	 *  @param perspectiveId
	 */
	public final void updatePerspectiveList() {
		if	((fMqConsumer != null) && (fE4Application != null)) {
			// --- get the perspectives ---
			List<MPerspective> perspectives = findPerspectives();
			Queue<Map<String,Object>> queue = new LinkedList<Map<String,Object>>();
			// --- if no perspectives available ---
			if	((perspectives == null) || perspectives.isEmpty()) {
				fMqConsumer.sendMessage(ECXMqMessageEvent.LIST_OF_PERSPECTIVES);
			}
			// --- otherwise ---
			else {
				for	(MPerspective perspective : perspectives) {
					// --- only rememer visible perspectives ---
					if	(perspective.isVisible() && perspective.isToBeRendered()) {
						CXMqMessagePerspectiveData data = new CXMqMessagePerspectiveData(
								perspective.getElementId(),
								perspective.getLabel(),
								perspective.getIconURI());
						queue.offer(data.getMap());
					}
				}
			}
			// --- only if the queue of perspectives has changed ---
			if	(!compare(queue, fLastListOfPerspectives)) {
				fLastListOfPerspectives = new LinkedList<Map<String,Object>>(queue);
				fMqConsumer.sendMessage(ECXMqMessageEvent.LIST_OF_PERSPECTIVES, ECXMqMessageAttribute.PERSPECTIVE_ID, queue);
			}
			// --- now inform about the actual focussed perspective ---
			MPerspective active = findCurrentPerspectiveFor(getPartService().getActivePart());
			if	(active instanceof MPerspective) {
				updateFocusPerspective (active.getElementId());
			}
		}
	}

	/**
	 *  call a legacy program via hybrid client
	 *  @param legacyProgramCall
	 */
	public final void callLegacyProgram(String legacyProgramCall) {
		if	(fMqConsumer != null) {
			fMqConsumer.callLegacyProgram(legacyProgramCall);
		}
	}
	
	/**
	 * handle any message received via ActiveMQ
	 * @param event
	 * @param body
	 */
	@Override
	public final boolean onMessage(ECXMqMessageEvent event, Map<ECXMqMessageAttribute, Object> body) {
		boolean retcode = false;
		switch (event) {
			case TRY_AUTHENTICATE:
				// --- try to authenticate with the credentials received ---
				if	(fEventsForNextRefresh == null) {
					tryToAuthenticate(
							body.get(ECXMqMessageAttribute.PORTAL_ID).toString(),
							body.get(ECXMqMessageAttribute.USERNAME).toString(),
							body.get(ECXMqMessageAttribute.PASSWORD).toString()
						);
				}
				else {
					fEventsForNextRefresh.add(new TryToAuthenticate(
							body.get(ECXMqMessageAttribute.PORTAL_ID).toString(),
							body.get(ECXMqMessageAttribute.USERNAME).toString(),
							body.get(ECXMqMessageAttribute.PASSWORD).toString()
						));
				}
				// TODO maybe after that the sleep could be stopped?
				// TODO see {@link #postInit(VaadinRequest)}
				retcode = true;
				break;
			case DISPOSE:
			case LOGOUT:
				// --- logout triggered through the event ---
				logout();
				retcode = true;
				break;
			default:
				for	(IHybridVaadinVaaclipseListener listener : fListeners) {
					if	(listener.onMessage(event, body)) {
						retcode = true;
						break;
					}
				}
				break;
		}
		return retcode;
	}
}
