/**
 *                                                                            
 *  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 2.0        
 *  which accompanies this distribution, and is available at                  
 *  https://www.eclipse.org/legal/epl-2.0/                                 
 *                                 
 *  SPDX-License-Identifier: EPL-2.0                                 
 *                                                                            
 *  Contributors:                                                      
 * 	   Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
 * 
 */
 package org.eclipse.osbp.ecview.extension.presentation.tests.strategy;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Locale;
import java.util.Map;

import org.eclipse.emf.ecore.util.EcoreUtil;
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.DelegatingEditPartManager;
import org.eclipse.osbp.ecview.core.common.editpart.IEmbeddableEditpart;
import org.eclipse.osbp.ecview.core.common.editpart.binding.IBindingEditpart;
import org.eclipse.osbp.ecview.core.common.model.binding.BindingFactory;
import org.eclipse.osbp.ecview.core.common.model.binding.YBindingEndpoint;
import org.eclipse.osbp.ecview.core.common.model.binding.YListBinding;
import org.eclipse.osbp.ecview.core.common.model.binding.YListBindingEndpoint;
import org.eclipse.osbp.ecview.core.common.model.binding.YValueBinding;
import org.eclipse.osbp.ecview.core.common.model.binding.YValueBindingEndpoint;
import org.eclipse.osbp.ecview.core.common.model.core.CoreModelFactory;
import org.eclipse.osbp.ecview.core.common.model.core.YBeanSlot;
import org.eclipse.osbp.ecview.core.common.model.core.YCollectionBindable;
import org.eclipse.osbp.ecview.core.common.model.core.YElement;
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddable;
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddableCollectionEndpoint;
import org.eclipse.osbp.ecview.core.common.model.core.YFocusable;
import org.eclipse.osbp.ecview.core.common.model.core.YKeyCode;
import org.eclipse.osbp.ecview.core.common.model.core.YKeyStrokeDefinition;
import org.eclipse.osbp.ecview.core.common.model.core.YLayout;
import org.eclipse.osbp.ecview.core.common.model.core.YModifierKey;
import org.eclipse.osbp.ecview.core.common.model.core.YValueBindable;
import org.eclipse.osbp.ecview.core.common.model.core.YView;
import org.eclipse.osbp.ecview.core.common.services.IWidgetAssocationsService;
import org.eclipse.osbp.ecview.core.extension.model.extension.ExtensionModelFactory;
import org.eclipse.osbp.ecview.core.extension.model.extension.YDecimalField;
import org.eclipse.osbp.ecview.core.extension.model.extension.YTextField;
import org.eclipse.osbp.ecview.core.extension.model.extension.YVerticalLayout;
import org.eclipse.osbp.ecview.core.extension.model.extension.util.SimpleExtensionModelFactory;
import org.eclipse.osbp.ecview.core.ui.core.editparts.extension.IDecimalFieldEditpart;
import org.eclipse.osbp.ecview.core.ui.core.editparts.extension.ITextFieldEditpart;
import org.eclipse.osbp.ecview.core.ui.core.editparts.extension.IVerticalLayoutEditpart;
import org.eclipse.osbp.ecview.core.util.emf.ModelUtil;
import org.eclipse.osbp.ecview.extension.api.IFocusingStrategy;
import org.eclipse.osbp.ecview.extension.api.IFocusingStrategyProvider;
import org.eclipse.osbp.ecview.extension.api.ILayoutingStrategy;
import org.eclipse.osbp.ecview.extension.api.ILayoutingStrategyProvider;
import org.eclipse.osbp.ecview.extension.editparts.ILayoutingInfoEditpart;
import org.eclipse.osbp.ecview.extension.editparts.IStrategyLayoutEditpart;
import org.eclipse.osbp.ecview.extension.editparts.ISuspectLayoutingInfoEditpart;
import org.eclipse.osbp.ecview.extension.editparts.emf.StrategyLayoutEditpart;
import org.eclipse.osbp.ecview.extension.editparts.emf.strategies.DelegatingFocusingStrategyEditpart;
import org.eclipse.osbp.ecview.extension.editparts.emf.strategies.LayoutingStrategyEditpart;
import org.eclipse.osbp.ecview.extension.model.YDelegatingFocusingStrategy;
import org.eclipse.osbp.ecview.extension.model.YECviewFactory;
import org.eclipse.osbp.ecview.extension.model.YLayoutingInfo;
import org.eclipse.osbp.ecview.extension.model.YStrategyLayout;
import org.eclipse.osbp.ecview.extension.model.YSuspect;
import org.eclipse.osbp.ecview.extension.model.YSuspectInfo;
import org.eclipse.osbp.ecview.extension.presentation.vaadin.strategy.StrategyLayoutPresentation;
import org.eclipse.osbp.runtime.common.event.IEventBroker;
import org.eclipse.osbp.runtime.common.keystroke.KeyCode;
import org.eclipse.osbp.runtime.common.keystroke.KeyStrokeCallback;
import org.eclipse.osbp.runtime.common.keystroke.KeyStrokeDefinition;
import org.eclipse.osbp.runtime.common.keystroke.ModifierKey;
import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.VaadinRenderer;
import org.eclipse.osbp.runtime.web.vaadin.components.fields.DecimalField;
import org.eclipse.osbp.runtime.web.vaadin.databinding.VaadinObservables;
import org.junit.Before;
import org.junit.Test;
import org.knowhowlab.osgi.testing.utils.BundleUtils;
import org.knowhowlab.osgi.testing.utils.ServiceUtils;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.FrameworkUtil;
import org.osgi.service.cm.ConfigurationException;

import com.vaadin.event.ActionManager;
import com.vaadin.event.ShortcutAction;
import com.vaadin.ui.AbstractComponent;
import com.vaadin.ui.Component;
import com.vaadin.ui.CssLayout;
import com.vaadin.ui.Panel;
import com.vaadin.ui.TextField;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;

import de.compex.ecview.extension.tests.dtos.Person;

/**
 * Tests the {@link StrategyLayoutPresentation}.
 */
public class StrategyLayoutTests {

	private SimpleExtensionModelFactory factory = new SimpleExtensionModelFactory();
	private YECviewFactory cxFactory = YECviewFactory.eINSTANCE;
	private CssLayout rootLayout = new CssLayout();
	private IViewContext viewContext;

	@SuppressWarnings("unchecked")
	private static <A> A findEditpart(YElement yElement) {
		return (A) DelegatingEditPartManager.getInstance().findEditpart(
				yElement);
	}

	@SuppressWarnings("unchecked")
	private <A> A getEditpart(YElement yElement) {
		return (A) DelegatingEditPartManager.getInstance().getEditpart(
				viewContext, yElement);
	}

	/**
	 * Setup tests.
	 * 
	 * @throws ConfigurationException
	 * @throws BundleException
	 */
	@Before
	public void setup() throws ConfigurationException, BundleException {
		BundleUtils.startBundleAsync(getBundleContext(),
				"org.lunifera.runtime.event");

		UI.setCurrent(new DefaultUI());
		UI.getCurrent().setContent(rootLayout);
		VaadinObservables.activateRealm(UI.getCurrent());
		
		Dictionary<String, Object> properties1 = new Hashtable<>();
		properties1.put("ecview.focusing.id", "default");
		getBundleContext().registerService(IFocusingStrategyProvider.class, new DefaultFocusingStrategyProvider(), properties1);
		
		Dictionary<String, Object> properties2 = new Hashtable<>();
		properties2.put("ecview.layouting.id", "Default");
		getBundleContext().registerService(ILayoutingStrategyProvider.class, new DefaultLayoutingStrategyProvider(), properties2);
		
	}

	private BundleContext getBundleContext() {
		return FrameworkUtil.getBundle(getClass()).getBundleContext();
	}

	/**
	 * A very simple render without Suspects.
	 * 
	 * @throws ContextException
	 */
	@Test
	public void test_SimpleRender() throws ContextException {

		// switch the global locale to german
		Locale.setDefault(Locale.GERMAN);

		// ----------------------------------------------------------
		// ------------- Create the layout --------------------------
		// ----------------------------------------------------------
		YView yView = factory.createView();
		YStrategyLayout yLayout = cxFactory.createYStrategyLayout();
		yView.setContent(yLayout);

		// ----------------------------------------------------------
		// ----------------- Render the UI --------------------------
		// ----------------------------------------------------------
		VaadinRenderer renderer = new VaadinRenderer();
		viewContext = renderer.render(rootLayout, yView, null);
		IStrategyLayoutEditpart layoutEP = DelegatingEditPartManager
				.getInstance().getEditpart(viewContext, yLayout);
		StrategyLayoutPresentation layoutPres = layoutEP.getPresentation();

		assertTrue(layoutPres.isRendered());
		assertFalse(layoutPres.isDisposed());
		assertTrue(layoutEP.isRendered());
		assertFalse(layoutEP.isDisposed());

		layoutEP.requestDispose();
		assertFalse(layoutPres.isRendered());
		assertTrue(layoutPres.isDisposed());
		assertFalse(layoutEP.isRendered());
		assertTrue(layoutEP.isDisposed());
	}

	/**
	 * Tests for the default layouter.
	 * 
	 * @throws ContextException
	 */
	@Test
	public void test_Layouter_Default() throws ContextException {

		// switch the global locale to german
		Locale.setDefault(Locale.GERMAN);

		// ----------------------------------------------------------
		// ------------- Create the layout --------------------------
		// ----------------------------------------------------------
		YView yView = factory.createView();
		YBeanSlot yBeanSlot = yView.addBeanSlot("main", Person.class);

		YStrategyLayout yLayout = cxFactory.createYStrategyLayout();
		yView.setContent(yLayout);

		// create suspects
		YSuspect nameSuspect = cxFactory.createYSuspect();
		nameSuspect.setName("name");
		nameSuspect.getValueBindingEndpoints().add(
				yBeanSlot.createBindingEndpoint("name"));
		yLayout.getSuspects().add(nameSuspect);
		YSuspect ageSuspect = cxFactory.createYSuspect();
		ageSuspect.setName("age");
		// ensure a decimal field
		ageSuspect.getTags().add("decimal");
		ageSuspect.getValueBindingEndpoints().add(
				yBeanSlot.createBindingEndpoint("age"));
		yLayout.getSuspects().add(ageSuspect);

		// ----------------------------------------------------------
		// ----------------- Render the UI --------------------------
		// ----------------------------------------------------------
		VaadinRenderer renderer = new VaadinRenderer();
		Map<String, Object> params = new HashMap<String, Object>();
		Map<String, Object> services = new HashMap<String, Object>();

		params.put(IViewContext.PARAM_SERVICES, services);
		services.put(ILayoutingStrategyProvider.class.getName(),
				new DefaultLayoutingStrategyProvider());
		services.put(IFocusingStrategyProvider.class.getName(),
				new DefaultFocusingStrategyProvider());

		viewContext = renderer.render(rootLayout, yView, params);
		viewContext.setBean("main", new Person());

		// ----------------------------------------------------------
		// --------------------- Check bindings ---------------------
		// ----------------------------------------------------------
		assertEquals(0, yView.getBindingSet().getBindings().size());
		assertEquals(2, yView.getBindingSet().getTransientBindings().size());

		IStrategyLayoutEditpart layoutEP = DelegatingEditPartManager
				.getInstance().getEditpart(viewContext, yLayout);
		StrategyLayoutPresentation layoutPres = layoutEP.getPresentation();

		// ----------------------------------------------------------
		// ------------- Read in the created editparts --------------
		// ----------------------------------------------------------
		YLayoutingInfo cxLayoutingInfo = yLayout.getLayoutingInfo();
		ILayoutingInfoEditpart cxLayoutingInfoEP = DelegatingEditPartManager
				.getInstance().getEditpart(viewContext, cxLayoutingInfo);
		// ensure that strategy did some layouting
		YEmbeddable yContent = cxLayoutingInfo.getContent();
		assertNotNull(yContent);

		// read the suspect layouting infos
		//
		YSuspectInfo nameSuspectInfo = cxLayoutingInfo.getActiveSuspectInfos()
				.get(0);
		YSuspectInfo ageSuspectInfo = cxLayoutingInfo.getActiveSuspectInfos()
				.get(1);
		ISuspectLayoutingInfoEditpart nameSuspectInfoEP = DelegatingEditPartManager
				.getInstance().getEditpart(viewContext, nameSuspectInfo);
		ISuspectLayoutingInfoEditpart ageSuspectInfoEP = DelegatingEditPartManager
				.getInstance().getEditpart(viewContext, ageSuspectInfo);

		IVerticalLayoutEditpart contentEP = DelegatingEditPartManager
				.getInstance().getEditpart(viewContext, yContent);

		// do asserts
		//
		assertTrue(layoutPres.isRendered());
		assertFalse(layoutPres.isDisposed());

		assertTrue(layoutEP.isRendered());
		assertFalse(layoutEP.isDisposed());
		assertTrue(contentEP.isRendered());
		assertFalse(contentEP.isDisposed());
		assertFalse(cxLayoutingInfoEP.isDisposed());
		assertFalse(nameSuspectInfoEP.isDisposed());
		assertFalse(ageSuspectInfoEP.isDisposed());

		IEmbeddableEditpart child1 = contentEP.getElements().get(0);
		IEmbeddableEditpart child2 = contentEP.getElements().get(1);

		// ensure, that layout elements have been created and rendered properly
		assertTrue(child1 instanceof ITextFieldEditpart);
		assertTrue(child2 instanceof IDecimalFieldEditpart);
		assertTrue(child1.isRendered());
		assertFalse(child1.isDisposed());
		assertTrue(child2.isRendered());
		assertFalse(child2.isDisposed());

		// ----------------------------------------------------------
		// ----------------- Dispose the strategy -------------------
		// ----------------------------------------------------------
		layoutEP.requestDispose();

		// do further tests
		//
		assertFalse(layoutPres.isRendered());
		assertTrue(layoutPres.isDisposed());

		assertFalse(contentEP.isRendered());
		assertTrue(contentEP.isDisposed());
		assertFalse(layoutEP.isRendered());
		assertTrue(layoutEP.isDisposed());
		assertTrue(cxLayoutingInfoEP.isDisposed());
		assertTrue(nameSuspectInfoEP.isDisposed());
		assertTrue(ageSuspectInfoEP.isDisposed());

		// ensure, that layout elements have been disposed properly
		assertFalse(child1.isRendered());
		assertTrue(child1.isDisposed());
		assertFalse(child2.isRendered());
		assertTrue(child2.isDisposed());

		// ensure, that editparts have been removed from models
		assertNull(findEditpart(yLayout));
		assertNull(findEditpart(nameSuspect));
		assertNull(findEditpart(ageSuspect));
		assertNull(findEditpart(cxLayoutingInfo));
		assertNull(findEditpart(yContent));
		assertNull(findEditpart(nameSuspectInfo));
		assertNull(findEditpart(ageSuspectInfo));

		// ensure bindings are removed
		//
		assertEquals(0, yView.getBindingSet().getBindings().size());
		assertEquals(0, yView.getBindingSet().getTransientBindings().size());

	}

	/**
	 * If a new default layout strategy provider is set and published by event
	 * admin, then the layout will update immediately.
	 * 
	 * @throws ContextException
	 */
	@Test
	public void test_Layouter_DefaultByEventBroker() throws ContextException {

		IEventBroker eventBroker = ServiceUtils.getService(getBundleContext(),
				IEventBroker.class);
		assertNotNull(eventBroker);

		// ----------------------------------------------------------
		// ------------- Create the layout --------------------------
		// ----------------------------------------------------------
		// switch the global locale to german
		Locale.setDefault(Locale.GERMAN);

		YView yView = factory.createView();
		YBeanSlot yBeanSlot = yView.addBeanSlot("main", Person.class);

		YStrategyLayout yLayout = cxFactory.createYStrategyLayout();
		yView.setContent(yLayout);

		// create suspects
		YSuspect nameSuspect = cxFactory.createYSuspect();
		nameSuspect.setName("name");
		nameSuspect.getValueBindingEndpoints().add(
				yBeanSlot.createBindingEndpoint("name"));
		yLayout.getSuspects().add(nameSuspect);
		YSuspect ageSuspect = cxFactory.createYSuspect();
		ageSuspect.setName("age");
		// ensure a decimal field
		ageSuspect.getTags().add("decimal");
		ageSuspect.getValueBindingEndpoints().add(
				yBeanSlot.createBindingEndpoint("age"));
		yLayout.getSuspects().add(ageSuspect);

		// ----------------------------------------------------------
		// ----------------- Render the UI --------------------------
		// ----------------------------------------------------------
		VaadinRenderer renderer = new VaadinRenderer();
		Map<String, Object> params = new HashMap<String, Object>();
		Map<String, Object> services = new HashMap<String, Object>();

		params.put(IViewContext.PARAM_SERVICES, services);
		services.put(ILayoutingStrategyProvider.class.getName(),
				new DefaultLayoutingStrategyProvider());
		services.put(IFocusingStrategyProvider.class.getName(),
				new DefaultFocusingStrategyProvider());

		viewContext = renderer.render(rootLayout, yView, params);
		viewContext.setBean("main", new Person());

		// ensure bindings are activated
		//
		assertEquals(2, yView.getBindingSet().getTransientBindings().size());

		// ----------------------------------------------------------
		// ------------- Read in the created editparts --------------
		// ----------------------------------------------------------
		IStrategyLayoutEditpart layoutEP = DelegatingEditPartManager
				.getInstance().getEditpart(viewContext, yLayout);
		StrategyLayoutPresentation layoutPres = layoutEP.getPresentation();

		// read the created layouting info
		//
		YLayoutingInfo cxLayoutingInfo = yLayout.getLayoutingInfo();
		ILayoutingInfoEditpart cxLayoutingInfoEP = DelegatingEditPartManager
				.getInstance().getEditpart(viewContext, cxLayoutingInfo);
		// ensure that strategy did some layouting
		YEmbeddable yContent = cxLayoutingInfo.getContent();
		assertNotNull(yContent);

		// read the suspect layouting infos
		//
		YSuspectInfo nameSuspectInfo = cxLayoutingInfo.getActiveSuspectInfos()
				.get(0);
		YSuspectInfo ageSuspectInfo = cxLayoutingInfo.getActiveSuspectInfos()
				.get(1);
		ISuspectLayoutingInfoEditpart nameSuspectInfoEP = DelegatingEditPartManager
				.getInstance().getEditpart(viewContext, nameSuspectInfo);
		ISuspectLayoutingInfoEditpart ageSuspectInfoEP = DelegatingEditPartManager
				.getInstance().getEditpart(viewContext, ageSuspectInfo);

		IVerticalLayoutEditpart contentEP = DelegatingEditPartManager
				.getInstance().getEditpart(viewContext, yContent);

		// do asserts
		//
		assertTrue(layoutPres.isRendered());
		assertFalse(layoutPres.isDisposed());

		assertTrue(layoutEP.isRendered());
		assertFalse(layoutEP.isDisposed());
		assertTrue(contentEP.isRendered());
		assertFalse(contentEP.isDisposed());
		assertFalse(cxLayoutingInfoEP.isDisposed());
		assertFalse(nameSuspectInfoEP.isDisposed());
		assertFalse(ageSuspectInfoEP.isDisposed());

		IEmbeddableEditpart child1 = contentEP.getElements().get(0);
		IEmbeddableEditpart child2 = contentEP.getElements().get(1);

		// ensure, that layout elements have been created and rendered properly
		assertTrue(child1 instanceof ITextFieldEditpart);
		assertTrue(child2 instanceof IDecimalFieldEditpart);
		assertTrue(child1.isRendered());
		assertFalse(child1.isDisposed());
		assertTrue(child2.isRendered());
		assertFalse(child2.isDisposed());

		// ----------------------------------------------------------
		// ------------- Apply a new default strategy ---------------
		// ----------------------------------------------------------
		OnlyLayoutTaggedStrategyProvider strategyProvider = new OnlyLayoutTaggedStrategyProvider();
		viewContext.registerService(ILayoutingStrategyProvider.class.getName(),
				strategyProvider);

		eventBroker.send(ILayoutingStrategyProvider.ACTIVE_PROVIDER_TOPIC,
				strategyProvider);

		StrategyLayoutEditpart implLayoutEP = (StrategyLayoutEditpart) layoutEP;
		LayoutingStrategyEditpart<?> implStrategyEP = (LayoutingStrategyEditpart<?>) implLayoutEP
				.getLayoutingStrategy();
		assertTrue(implStrategyEP.getStrategy() instanceof OnlyLayoutTaggedStrategy);

		// do asserts OLD values
		//
		assertFalse(layoutPres.isDisposed());
		assertFalse(layoutEP.isDisposed());
		assertTrue(contentEP.isDisposed());
		assertTrue(cxLayoutingInfoEP.isDisposed());
		assertTrue(nameSuspectInfoEP.isDisposed());
		assertTrue(ageSuspectInfoEP.isDisposed());
		assertFalse(child1.isRendered());
		assertTrue(child1.isDisposed());
		assertFalse(child2.isRendered());
		assertTrue(child2.isDisposed());

		// ----------------------------------------------------------
		// ------------- Read in the created editparts --------------
		// ----------------------------------------------------------
		cxLayoutingInfo = yLayout.getLayoutingInfo();
		cxLayoutingInfoEP = DelegatingEditPartManager.getInstance()
				.getEditpart(viewContext, cxLayoutingInfo);
		// ensure that strategy did some layouting
		yContent = cxLayoutingInfo.getContent();
		assertNotNull(yContent);

		// read the suspect layouting infos
		//
		ageSuspectInfo = cxLayoutingInfo.getActiveSuspectInfos().get(0);
		ageSuspectInfoEP = DelegatingEditPartManager.getInstance().getEditpart(
				viewContext, ageSuspectInfo);

		contentEP = DelegatingEditPartManager.getInstance().getEditpart(
				viewContext, yContent);

		// do asserts
		//
		assertTrue(layoutPres.isRendered());
		assertFalse(layoutPres.isDisposed());

		assertTrue(layoutEP.isRendered());
		assertFalse(layoutEP.isDisposed());
		assertTrue(contentEP.isRendered());
		assertFalse(contentEP.isDisposed());
		assertFalse(cxLayoutingInfoEP.isDisposed());
		assertFalse(ageSuspectInfoEP.isDisposed());

		child1 = contentEP.getElements().get(0);

		// ensure, that layout elements have been created and rendered properly
		assertTrue(child1 instanceof IDecimalFieldEditpart);
		assertTrue(child1.isRendered());
		assertFalse(child1.isDisposed());

	}

	/**
	 * Tests that YLayoutingInfo can become activated and deactivated.
	 * 
	 * @throws ContextException
	 */
	@Test
	public void test_LayoutInfo_ActivateAndDeactivate() throws ContextException {

		// switch the global locale to german
		Locale.setDefault(Locale.GERMAN);

		// ----------------------------------------------------------
		// ------------- Create the layout --------------------------
		// ----------------------------------------------------------
		YView yView = factory.createView();
		YBeanSlot yBeanSlot = yView.addBeanSlot("main", Person.class);

		YStrategyLayout yLayout = cxFactory.createYStrategyLayout();
		yView.setContent(yLayout);

		// create suspects
		YSuspect nameSuspect = cxFactory.createYSuspect();
		nameSuspect.setName("name");
		nameSuspect.getValueBindingEndpoints().add(
				yBeanSlot.createBindingEndpoint("name"));
		yLayout.getSuspects().add(nameSuspect);
		YSuspect ageSuspect = cxFactory.createYSuspect();
		ageSuspect.setName("age");
		// ensure a decimal field
		ageSuspect.getTags().add("decimal");
		ageSuspect.getValueBindingEndpoints().add(
				yBeanSlot.createBindingEndpoint("age"));
		yLayout.getSuspects().add(ageSuspect);

		// ----------------------------------------------------------
		// ----------------- Render the UI --------------------------
		// ----------------------------------------------------------
		VaadinRenderer renderer = new VaadinRenderer();
		Map<String, Object> params = new HashMap<String, Object>();
		Map<String, Object> services = new HashMap<String, Object>();

		params.put(IViewContext.PARAM_SERVICES, services);
		services.put(ILayoutingStrategyProvider.class.getName(),
				new DefaultLayoutingStrategyProvider());
		services.put(IFocusingStrategyProvider.class.getName(),
				new DefaultFocusingStrategyProvider());

		viewContext = renderer.render(rootLayout, yView, params);
		viewContext.setBean("main", new Person());

		// ensure bindings are activated
		//
		assertEquals(0, yView.getBindingSet().getBindings().size());
		assertEquals(2, yView.getBindingSet().getTransientBindings().size());

		// ----------------------------------------------------------
		// ------------- Read in the created editparts --------------
		// ----------------------------------------------------------
		YLayoutingInfo cxLayoutingInfo = yLayout.getLayoutingInfo();
		ILayoutingInfoEditpart cxLayoutingInfoEP = DelegatingEditPartManager
				.getInstance().getEditpart(viewContext, cxLayoutingInfo);
		YEmbeddable yContent = cxLayoutingInfo.getContent();
		assertNotNull(yContent);

		// read the suspect layouting infos
		//
		YSuspectInfo nameSuspectInfo = cxLayoutingInfo.getActiveSuspectInfos()
				.get(0);
		YSuspectInfo ageSuspectInfo = cxLayoutingInfo.getActiveSuspectInfos()
				.get(1);
		ISuspectLayoutingInfoEditpart nameSuspectInfoEP = DelegatingEditPartManager
				.getInstance().getEditpart(viewContext, nameSuspectInfo);
		ISuspectLayoutingInfoEditpart ageSuspectInfoEP = DelegatingEditPartManager
				.getInstance().getEditpart(viewContext, ageSuspectInfo);

		// do asserts
		//
		assertFalse(cxLayoutingInfoEP.isDisposed());
		assertFalse(nameSuspectInfoEP.isDisposed());
		assertFalse(ageSuspectInfoEP.isDisposed());

		// ----------------------------------------------------------
		// ------------- Dispose the layouting info -----------------
		// ----------------------------------------------------------
		cxLayoutingInfoEP.requestDispose();

		// do further tests
		//
		assertTrue(cxLayoutingInfoEP.isDisposed());
		assertTrue(nameSuspectInfoEP.isDisposed());
		assertTrue(ageSuspectInfoEP.isDisposed());

		// ensure bindings are removed
		//
		assertEquals(0, yView.getBindingSet().getBindings().size());
		assertEquals(0, yView.getBindingSet().getTransientBindings().size());

		// ----------------------------------------------------------
		// ---------- Activate the layouting info again -------------
		// ----------------------------------------------------------
		yLayout.setLayoutingInfo(cxLayoutingInfo);

		// ----------------------------------------------------------
		// ------------- Read in the created editparts --------------
		// ----------------------------------------------------------
		cxLayoutingInfoEP = DelegatingEditPartManager.getInstance()
				.getEditpart(viewContext, cxLayoutingInfo);
		yContent = cxLayoutingInfo.getContent();
		assertNotNull(yContent);

		// read the suspect layouting infos
		//
		nameSuspectInfo = cxLayoutingInfo.getActiveSuspectInfos().get(0);
		ageSuspectInfo = cxLayoutingInfo.getActiveSuspectInfos().get(1);
		nameSuspectInfoEP = DelegatingEditPartManager.getInstance()
				.getEditpart(viewContext, nameSuspectInfo);
		ageSuspectInfoEP = DelegatingEditPartManager.getInstance().getEditpart(
				viewContext, ageSuspectInfo);

		assertFalse(cxLayoutingInfoEP.isDisposed());
		assertFalse(nameSuspectInfoEP.isDisposed());
		assertFalse(ageSuspectInfoEP.isDisposed());

		// ensure bindings are added again
		//
		assertEquals(0, yView.getBindingSet().getBindings().size());
		assertEquals(2, yView.getBindingSet().getTransientBindings().size());

		// ----------------------------------------------------------
		// ------------- Dispose the layouting info -----------------
		// ----------------------------------------------------------
		cxLayoutingInfoEP.requestDispose();
		assertTrue(cxLayoutingInfoEP.isDisposed());
		assertTrue(nameSuspectInfoEP.isDisposed());
		assertTrue(ageSuspectInfoEP.isDisposed());

		assertEquals(0, yView.getBindingSet().getBindings().size());
		assertEquals(0, yView.getBindingSet().getTransientBindings().size());
	}

	/**
	 * Tests that bindings are setup properly.
	 * 
	 * @throws ContextException
	 */
	@Test
	public void test_LayoutInfo_Bindings() throws ContextException {

		// switch the global locale to german
		Locale.setDefault(Locale.GERMAN);

		// ----------------------------------------------------------
		// ------------- Create the layout --------------------------
		// ----------------------------------------------------------
		YView yView = factory.createView();
		YBeanSlot yBeanSlot = yView.addBeanSlot("main", Person.class);

		YStrategyLayout yLayout = cxFactory.createYStrategyLayout();
		yView.setContent(yLayout);

		// create suspects
		YSuspect nameSuspect = cxFactory.createYSuspect();
		nameSuspect.setName("name");
		nameSuspect.getValueBindingEndpoints().add(
				yBeanSlot.createBindingEndpoint("name"));
		yLayout.getSuspects().add(nameSuspect);
		YSuspect ageSuspect = cxFactory.createYSuspect();
		ageSuspect.setName("age");
		// ensure a decimal field
		ageSuspect.getTags().add("decimal");
		ageSuspect.getValueBindingEndpoints().add(
				yBeanSlot.createBindingEndpoint("age"));
		yLayout.getSuspects().add(ageSuspect);

		// ----------------------------------------------------------
		// ----------------- Render the UI --------------------------
		// ----------------------------------------------------------
		VaadinRenderer renderer = new VaadinRenderer();
		Map<String, Object> params = new HashMap<String, Object>();
		Map<String, Object> services = new HashMap<String, Object>();

		params.put(IViewContext.PARAM_SERVICES, services);
		services.put(ILayoutingStrategyProvider.class.getName(),
				new DefaultLayoutingStrategyProvider());
		services.put(IFocusingStrategyProvider.class.getName(),
				new DefaultFocusingStrategyProvider());

		viewContext = renderer.render(rootLayout, yView, params);
		viewContext.setBean("main", new Person());

		// ensure bindings are activated
		//
		assertEquals(0, yView.getBindingSet().getBindings().size());
		assertEquals(2, yView.getBindingSet().getTransientBindings().size());

		// ----------------------------------------------------------
		// ------------- Read in the created editparts --------------
		// ----------------------------------------------------------
		YLayoutingInfo cxLayoutingInfo = yLayout.getLayoutingInfo();
		ILayoutingInfoEditpart cxLayoutingInfoEP = DelegatingEditPartManager
				.getInstance().getEditpart(viewContext, cxLayoutingInfo);
		YVerticalLayout yContent = (YVerticalLayout) cxLayoutingInfo
				.getContent();
		assertNotNull(yContent);

		// read the suspect layouting infos
		//
		YSuspectInfo nameSuspectInfo = cxLayoutingInfo.getActiveSuspectInfos()
				.get(0);
		YSuspectInfo ageSuspectInfo = cxLayoutingInfo.getActiveSuspectInfos()
				.get(1);
		ISuspectLayoutingInfoEditpart nameSuspectInfoEP = DelegatingEditPartManager
				.getInstance().getEditpart(viewContext, nameSuspectInfo);
		ISuspectLayoutingInfoEditpart ageSuspectInfoEP = DelegatingEditPartManager
				.getInstance().getEditpart(viewContext, ageSuspectInfo);

		// do asserts
		//
		assertFalse(cxLayoutingInfoEP.isDisposed());
		assertFalse(nameSuspectInfoEP.isDisposed());
		assertFalse(ageSuspectInfoEP.isDisposed());

		YTextField yNameField = (YTextField) yContent.getElement(0);
		YDecimalField yAgeField = (YDecimalField) yContent.getElement(1);
		TextField nameField = (TextField) ((IEmbeddableEditpart) findEditpart(yNameField))
				.getWidget();
		DecimalField ageField = (DecimalField) ((IEmbeddableEditpart) findEditpart(yAgeField))
				.getWidget();

		Person bean = (Person) viewContext.getBean("main");
		bean.setName("My Name");
		bean.setAge(44);
		assertEquals(bean.getName(), nameField.getValue());
		assertEquals(new Double(bean.getAge()), ageField.getConvertedValue());

		// ----------------------------------------------------------
		// ------------- Dispose the layouting info -----------------
		// ----------------------------------------------------------
		cxLayoutingInfoEP.requestDispose();

		// do further tests
		//
		assertTrue(cxLayoutingInfoEP.isDisposed());
		assertTrue(nameSuspectInfoEP.isDisposed());
		assertTrue(ageSuspectInfoEP.isDisposed());

		// ensure bindings are removed
		//
		assertEquals(0, yView.getBindingSet().getBindings().size());
		assertEquals(0, yView.getBindingSet().getTransientBindings().size());

		bean.setName("Other Name");
		bean.setAge(36);
		assertNotEquals(bean.getName(), nameField.getValue());
		assertNotEquals(new Double(bean.getAge()), ageField.getConvertedValue());

		// ----------------------------------------------------------
		// ---------- Activate the layouting info again -------------
		// ----------------------------------------------------------
		yLayout.setLayoutingInfo(cxLayoutingInfo);

		// ----------------------------------------------------------
		// ------------- Read in the created editparts --------------
		// ----------------------------------------------------------
		cxLayoutingInfoEP = DelegatingEditPartManager.getInstance()
				.getEditpart(viewContext, cxLayoutingInfo);
		yContent = (YVerticalLayout) cxLayoutingInfo.getContent();
		assertNotNull(yContent);

		// read the suspect layouting infos
		//
		nameSuspectInfo = cxLayoutingInfo.getActiveSuspectInfos().get(0);
		ageSuspectInfo = cxLayoutingInfo.getActiveSuspectInfos().get(1);
		nameSuspectInfoEP = DelegatingEditPartManager.getInstance()
				.getEditpart(viewContext, nameSuspectInfo);
		ageSuspectInfoEP = DelegatingEditPartManager.getInstance().getEditpart(
				viewContext, ageSuspectInfo);

		// get new Vaadin fields
		yNameField = (YTextField) yContent.getElement(0);
		yAgeField = (YDecimalField) yContent.getElement(1);
		nameField = (TextField) ((IEmbeddableEditpart) findEditpart(yNameField))
				.getWidget();
		ageField = (DecimalField) ((IEmbeddableEditpart) findEditpart(yAgeField))
				.getWidget();

		bean = (Person) viewContext.getBean("main");
		bean.setName("Just a test");
		bean.setAge(22);
		assertEquals(bean.getName(), nameField.getValue());
		assertEquals(new Double(bean.getAge()), ageField.getConvertedValue());

		assertFalse(cxLayoutingInfoEP.isDisposed());
		assertFalse(nameSuspectInfoEP.isDisposed());
		assertFalse(ageSuspectInfoEP.isDisposed());

		// ensure bindings are added again
		//
		assertEquals(0, yView.getBindingSet().getBindings().size());
		assertEquals(2, yView.getBindingSet().getTransientBindings().size());

		// ----------------------------------------------------------
		// ------------- Dispose the layouting info -----------------
		// ----------------------------------------------------------
		cxLayoutingInfoEP.requestDispose();
		assertTrue(cxLayoutingInfoEP.isDisposed());
		assertTrue(nameSuspectInfoEP.isDisposed());
		assertTrue(ageSuspectInfoEP.isDisposed());

		assertEquals(0, yView.getBindingSet().getBindings().size());
		assertEquals(0, yView.getBindingSet().getTransientBindings().size());

		bean.setName("Another test");
		bean.setAge(44);
		assertNotEquals(bean.getName(), nameField.getValue());
		assertNotEquals(new Double(bean.getAge()), ageField.getConvertedValue());
	}

	/**
	 * Switching the layoutInfo between two instances.
	 * 
	 * @throws ContextException
	 */
	@Test
	public void test_LayoutInfo_SwitchInfo() throws ContextException {

		// switch the global locale to german
		Locale.setDefault(Locale.GERMAN);

		// ----------------------------------------------------------
		// ------------- Create the layout --------------------------
		// ----------------------------------------------------------
		YView yView = factory.createView();
		YBeanSlot yBeanSlot = yView.addBeanSlot("main", Person.class);

		YStrategyLayout yLayout = cxFactory.createYStrategyLayout();
		yView.setContent(yLayout);

		// create suspects
		YSuspect nameSuspect = cxFactory.createYSuspect();
		nameSuspect.setName("name");
		nameSuspect.getValueBindingEndpoints().add(
				yBeanSlot.createBindingEndpoint("name"));
		yLayout.getSuspects().add(nameSuspect);
		YSuspect ageSuspect = cxFactory.createYSuspect();
		ageSuspect.setName("age");
		// ensure a decimal field
		ageSuspect.getTags().add("decimal");
		ageSuspect.getValueBindingEndpoints().add(
				yBeanSlot.createBindingEndpoint("age"));
		yLayout.getSuspects().add(ageSuspect);

		// ----------------------------------------------------------
		// ----------------- Render the UI --------------------------
		// ----------------------------------------------------------
		VaadinRenderer renderer = new VaadinRenderer();
		Map<String, Object> params = new HashMap<String, Object>();
		Map<String, Object> services = new HashMap<String, Object>();

		params.put(IViewContext.PARAM_SERVICES, services);
		services.put(ILayoutingStrategyProvider.class.getName(),
				new DefaultLayoutingStrategyProvider());
		services.put(IFocusingStrategyProvider.class.getName(),
				new DefaultFocusingStrategyProvider());

		viewContext = renderer.render(rootLayout, yView, params);
		viewContext.setBean("main", new Person());

		// ensure bindings are activated
		//
		assertEquals(0, yView.getBindingSet().getBindings().size());
		assertEquals(2, yView.getBindingSet().getTransientBindings().size());

		// read the created layouting info
		//
		YLayoutingInfo cxLayoutingInfo1 = yLayout.getLayoutingInfo();
		ILayoutingInfoEditpart cxLayoutingInfoEP1 = DelegatingEditPartManager
				.getInstance().getEditpart(viewContext, cxLayoutingInfo1);
		YVerticalLayout yContent1 = (YVerticalLayout) cxLayoutingInfo1
				.getContent();
		assertNotNull(yContent1);
		assertEquals(2, yContent1.getElements().size());

		// ----------------------------------------------------------
		// ------------- Read in the created editparts --------------
		// ----------------------------------------------------------
		YSuspectInfo nameSuspectInfo1_1 = cxLayoutingInfo1
				.getActiveSuspectInfos().get(0);
		YSuspectInfo ageSuspectInfo1_2 = cxLayoutingInfo1
				.getActiveSuspectInfos().get(1);
		ISuspectLayoutingInfoEditpart nameSuspectInfoEP1_1 = DelegatingEditPartManager
				.getInstance().getEditpart(viewContext, nameSuspectInfo1_1);
		ISuspectLayoutingInfoEditpart ageSuspectInfoEP1_2 = DelegatingEditPartManager
				.getInstance().getEditpart(viewContext, ageSuspectInfo1_2);

		// ----------------------------------------------------------
		// ---------- Set a new layouting info manually -------------
		// ----------------------------------------------------------
		YLayoutingInfo cxLayoutingInfo2 = EcoreUtil.copy(cxLayoutingInfo1);

		// remove one field from the info
		cxLayoutingInfo2.getActiveSuspectInfos().remove(0);
		YVerticalLayout yContent2 = (YVerticalLayout) cxLayoutingInfo2
				.getContent();
		yContent2.getElements().remove(0);

		ILayoutingInfoEditpart cxLayoutingInfoEP2 = DelegatingEditPartManager
				.getInstance().getEditpart(viewContext, cxLayoutingInfo2);

		// read the suspect layouting infos
		YSuspectInfo ageSuspectInfo2_1 = cxLayoutingInfo2
				.getActiveSuspectInfos().get(0);
		ISuspectLayoutingInfoEditpart ageSuspectInfoEP2_1 = DelegatingEditPartManager
				.getInstance().getEditpart(viewContext, ageSuspectInfo2_1);

		// do asserts
		//
		assertFalse(cxLayoutingInfoEP1.isDisposed());
		assertFalse(nameSuspectInfoEP1_1.isDisposed());
		assertFalse(ageSuspectInfoEP1_2.isDisposed());

		assertFalse(cxLayoutingInfoEP2.isDisposed());
		assertFalse(ageSuspectInfoEP2_1.isDisposed());

		// currently 2 views active
		YVerticalLayout yCurrentContent = (YVerticalLayout) yLayout
				.getLayoutingInfo().getContent();
		assertEquals(2, yCurrentContent.getElements().size());

		// ----------------------------------------------------------
		// ------------- Now switch the layouting info --------------
		// ----------------------------------------------------------
		yLayout.setLayoutingInfo(cxLayoutingInfo2);
		assertNotNull(yContent2);
		assertEquals(1, yContent2.getElements().size());

		assertTrue(cxLayoutingInfoEP1.isDisposed());
		assertTrue(nameSuspectInfoEP1_1.isDisposed());
		assertTrue(ageSuspectInfoEP1_2.isDisposed());

		assertFalse(cxLayoutingInfoEP2.isDisposed());
		assertFalse(ageSuspectInfoEP2_1.isDisposed());

		// ensure bindings are removed
		//
		assertEquals(0, yView.getBindingSet().getBindings().size());
		assertEquals(1, yView.getBindingSet().getTransientBindings().size());

		// currently 1 views active
		yCurrentContent = (YVerticalLayout) yLayout.getLayoutingInfo()
				.getContent();
		assertEquals(1, yCurrentContent.getElements().size());

		// ----------------------------------------------------------
		// ------------------ And switch it back --------------------
		// ----------------------------------------------------------
		yLayout.setLayoutingInfo(cxLayoutingInfo1);
		assertEquals(0, yView.getBindingSet().getBindings().size());
		assertEquals(2, yView.getBindingSet().getTransientBindings().size());

		cxLayoutingInfoEP1 = DelegatingEditPartManager.getInstance()
				.getEditpart(viewContext, cxLayoutingInfo1);
		yContent1 = (YVerticalLayout) cxLayoutingInfo1.getContent();
		assertNotNull(yContent1);
		assertEquals(2, yContent1.getElements().size());

		// read the suspect layouting infos again. NEW INSTANCES!
		//
		nameSuspectInfo1_1 = cxLayoutingInfo1.getActiveSuspectInfos().get(0);
		ageSuspectInfo1_2 = cxLayoutingInfo1.getActiveSuspectInfos().get(1);
		nameSuspectInfoEP1_1 = DelegatingEditPartManager.getInstance()
				.getEditpart(viewContext, nameSuspectInfo1_1);
		ageSuspectInfoEP1_2 = DelegatingEditPartManager.getInstance()
				.getEditpart(viewContext, ageSuspectInfo1_2);

		assertFalse(cxLayoutingInfoEP1.isDisposed());
		assertFalse(nameSuspectInfoEP1_1.isDisposed());
		assertFalse(ageSuspectInfoEP1_2.isDisposed());

		assertTrue(cxLayoutingInfoEP2.isDisposed());
		assertTrue(ageSuspectInfoEP2_1.isDisposed());

		// ensure bindings are added again
		//
		assertEquals(0, yView.getBindingSet().getBindings().size());
		assertEquals(2, yView.getBindingSet().getTransientBindings().size());

		// currently 2 views active
		yCurrentContent = (YVerticalLayout) yLayout.getLayoutingInfo()
				.getContent();
		assertEquals(2, yCurrentContent.getElements().size());

		// ----------------------------------------------------------
		// --------------- Dispose the layouting info ---------------
		// ----------------------------------------------------------
		cxLayoutingInfoEP1.dispose();
		assertTrue(cxLayoutingInfoEP1.isDisposed());
		assertTrue(nameSuspectInfoEP1_1.isDisposed());
		assertTrue(ageSuspectInfoEP1_2.isDisposed());

		assertEquals(0, yView.getBindingSet().getBindings().size());
		assertEquals(0, yView.getBindingSet().getTransientBindings().size());
	}

	/**
	 * Test to show, that active rendered YLayoutingInfo can be changed. The
	 * changes are reflected to the UI, but no complete relayouting is done.
	 * 
	 * @throws ContextException
	 */
	@Test
	public void test_LayoutingInfo_ChangeValueInActive()
			throws ContextException {

		// switch the global locale to german
		Locale.setDefault(Locale.GERMAN);

		// ----------------------------------------------------------
		// ------------- Create the layout --------------------------
		// ----------------------------------------------------------
		YView yView = factory.createView();
		YBeanSlot yBeanSlot = yView.addBeanSlot("main", Person.class);

		YStrategyLayout yLayout = cxFactory.createYStrategyLayout();
		yView.setContent(yLayout);

		// create suspects
		YSuspect nameSuspect = cxFactory.createYSuspect();
		nameSuspect.setName("name");
		nameSuspect.getValueBindingEndpoints().add(
				yBeanSlot.createBindingEndpoint("name"));
		yLayout.getSuspects().add(nameSuspect);
		YSuspect ageSuspect = cxFactory.createYSuspect();
		ageSuspect.setName("age");
		// ensure a decimal field
		ageSuspect.getTags().add("decimal");
		ageSuspect.getValueBindingEndpoints().add(
				yBeanSlot.createBindingEndpoint("age"));
		yLayout.getSuspects().add(ageSuspect);

		// ----------------------------------------------------------
		// ----------------- Render the UI --------------------------
		// ----------------------------------------------------------
		VaadinRenderer renderer = new VaadinRenderer();
		Map<String, Object> params = new HashMap<String, Object>();
		Map<String, Object> services = new HashMap<String, Object>();

		params.put(IViewContext.PARAM_SERVICES, services);
		services.put(ILayoutingStrategyProvider.class.getName(),
				new DefaultLayoutingStrategyProvider());
		services.put(IFocusingStrategyProvider.class.getName(),
				new DefaultFocusingStrategyProvider());

		viewContext = renderer.render(rootLayout, yView, params);
		viewContext.setBean("main", new Person());

		// ----------------------------------------------------------
		// ------------- Read in the created editparts --------------
		// ----------------------------------------------------------
		YLayoutingInfo cxLayoutingInfo1 = yLayout.getLayoutingInfo();
		ILayoutingInfoEditpart cxLayoutingInfoEP1 = DelegatingEditPartManager
				.getInstance().getEditpart(viewContext, cxLayoutingInfo1);
		YVerticalLayout yContent = (YVerticalLayout) cxLayoutingInfo1
				.getContent();
		assertNotNull(yContent);
		assertEquals(2, yContent.getElements().size());

		// read the suspect layouting infos
		//
		YSuspectInfo nameSuspectInfo1_1 = cxLayoutingInfo1
				.getActiveSuspectInfos().get(0);
		YSuspectInfo ageSuspectInfo1_2 = cxLayoutingInfo1
				.getActiveSuspectInfos().get(1);
		ISuspectLayoutingInfoEditpart nameSuspectInfoEP1_1 = DelegatingEditPartManager
				.getInstance().getEditpart(viewContext, nameSuspectInfo1_1);
		ISuspectLayoutingInfoEditpart ageSuspectInfoEP1_2 = DelegatingEditPartManager
				.getInstance().getEditpart(viewContext, ageSuspectInfo1_2);

		// ensure values
		//
		assertFalse(nameSuspectInfoEP1_1.isDisposed());
		assertFalse(ageSuspectInfoEP1_2.isDisposed());
		assertEquals(2, yView.getBindingSet().getTransientBindings().size());

		// test Vaadin
		VerticalLayout vl = (VerticalLayout) cxLayoutingInfoEP1.getContent()
				.getWidget();
		assertEquals(2, vl.getComponentCount());

		// ----------------------------------------------------------
		// -------------- Remove nameSuspectInfoEP1_1 ---------------
		// ----------------------------------------------------------
		// now remove nameSuspectInfoEP1_1 and its representation
		cxLayoutingInfo1.getActiveSuspectInfos().remove(0);
		yContent = (YVerticalLayout) cxLayoutingInfo1.getContent();
		yContent.getElements().remove(0);

		// ----------------------------------------------------------
		// --------------- Ensure Vaadin updated UI -----------------
		// ------ No relayouting happend yet. Ui followed model------
		// ----------------------------------------------------------
		assertTrue(nameSuspectInfoEP1_1.isDisposed());
		assertFalse(cxLayoutingInfoEP1.isDisposed());
		assertFalse(ageSuspectInfoEP1_2.isDisposed());

		// test Vaadin
		vl = (VerticalLayout) cxLayoutingInfoEP1.getContent().getWidget();
		assertEquals(1, vl.getComponentCount());

		// name was removed, so age needs to be index 0
		YSuspectInfo ageSuspectInfo2_1 = cxLayoutingInfo1
				.getActiveSuspectInfos().get(0);
		assertFalse(ageSuspectInfoEP1_2.isDisposed());
		// ageSuspectInfoEP1_2 was NOT disposed
		assertSame(ageSuspectInfoEP1_2, findEditpart(ageSuspectInfo2_1));
		assertEquals(1, yView.getBindingSet().getTransientBindings().size());

		// Ui was updated
		yContent = (YVerticalLayout) cxLayoutingInfo1.getContent();
		assertNotNull(yContent);
		assertEquals(1, yContent.getElements().size());

		vl = (VerticalLayout) cxLayoutingInfoEP1.getContent().getWidget();
		assertEquals(1, vl.getComponentCount());

		// ----------------------------------------------------------
		// ----------------- Do full relayouting --------------------
		// ----------------------------------------------------------
		IStrategyLayoutEditpart layoutEP = findEditpart(yLayout);
		layoutEP.requestLayouting();

		// all active editparts have been disposed
		assertTrue(cxLayoutingInfoEP1.isDisposed());
		assertTrue(nameSuspectInfoEP1_1.isDisposed());
		assertTrue(ageSuspectInfoEP1_2.isDisposed());

		cxLayoutingInfo1 = yLayout.getLayoutingInfo();
		cxLayoutingInfoEP1 = DelegatingEditPartManager.getInstance()
				.getEditpart(viewContext, cxLayoutingInfo1);
		yContent = (YVerticalLayout) cxLayoutingInfo1.getContent();
		assertNotNull(yContent);
		assertEquals(2, yContent.getElements().size());

		// read the suspect layouting infos
		//
		nameSuspectInfo1_1 = cxLayoutingInfo1.getActiveSuspectInfos().get(0);
		ageSuspectInfo1_2 = cxLayoutingInfo1.getActiveSuspectInfos().get(1);
		nameSuspectInfoEP1_1 = DelegatingEditPartManager.getInstance()
				.getEditpart(viewContext, nameSuspectInfo1_1);
		ageSuspectInfoEP1_2 = DelegatingEditPartManager.getInstance()
				.getEditpart(viewContext, ageSuspectInfo1_2);
		assertFalse(cxLayoutingInfoEP1.isDisposed());
		assertFalse(nameSuspectInfoEP1_1.isDisposed());
		assertFalse(ageSuspectInfoEP1_2.isDisposed());
		assertEquals(2, yView.getBindingSet().getTransientBindings().size());

		// test Vaadin
		vl = (VerticalLayout) cxLayoutingInfoEP1.getContent().getWidget();
		assertEquals(2, vl.getComponentCount());

		viewContext.dispose();

	}

	/**
	 * Test to show, that active rendered YLayoutingInfo can be changed. The
	 * changes are reflected to the UI, but no complete relayouting is done.
	 * 
	 * @throws ContextException
	 */
	@Test
	public void test_LayoutingInfo_AddAndRemoveBindingValueInActive()
			throws ContextException {

		// switch the global locale to german
		Locale.setDefault(Locale.GERMAN);

		// ----------------------------------------------------------
		// ------------- Create the layout --------------------------
		// ----------------------------------------------------------
		YView yView = factory.createView();
		YBeanSlot yBeanSlot = yView.addBeanSlot("main", Person.class);

		YStrategyLayout yLayout = cxFactory.createYStrategyLayout();
		yView.setContent(yLayout);

		// create suspects
		YSuspect nameSuspect = cxFactory.createYSuspect();
		nameSuspect.setName("name");
		nameSuspect.getValueBindingEndpoints().add(
				yBeanSlot.createBindingEndpoint("name"));
		yLayout.getSuspects().add(nameSuspect);
		YSuspect ageSuspect = cxFactory.createYSuspect();
		ageSuspect.setName("age");
		// ensure a decimal field
		ageSuspect.getTags().add("decimal");
		ageSuspect.getValueBindingEndpoints().add(
				yBeanSlot.createBindingEndpoint("age"));
		yLayout.getSuspects().add(ageSuspect);

		// ----------------------------------------------------------
		// ----------------- Render the UI --------------------------
		// ----------------------------------------------------------
		VaadinRenderer renderer = new VaadinRenderer();
		Map<String, Object> params = new HashMap<String, Object>();
		Map<String, Object> services = new HashMap<String, Object>();

		params.put(IViewContext.PARAM_SERVICES, services);
		services.put(ILayoutingStrategyProvider.class.getName(),
				new DefaultLayoutingStrategyProvider());
		services.put(IFocusingStrategyProvider.class.getName(),
				new DefaultFocusingStrategyProvider());

		viewContext = renderer.render(rootLayout, yView, params);
		viewContext.setBean("main", new Person());

		// ----------------------------------------------------------
		// ------------- Read in the created editparts --------------
		// ----------------------------------------------------------
		YLayoutingInfo cxLayoutingInfo1 = yLayout.getLayoutingInfo();
		YVerticalLayout yContent = (YVerticalLayout) cxLayoutingInfo1
				.getContent();
		assertNotNull(yContent);
		assertEquals(2, yContent.getElements().size());

		// read the suspect layouting infos
		//
		YSuspectInfo nameSuspectInfo1_1 = cxLayoutingInfo1
				.getActiveSuspectInfos().get(0);

		// ----------------------------------------------------------
		// ----- Add a new binding to the active suspect info -------
		// ----------------------------------------------------------
		// make a copy -> otherwise the suspect will be changed
		YValueBindingEndpoint yValueEPName = yBeanSlot
				.createBindingEndpoint("name");
		YValueBindingEndpoint yValueEPName2 = yBeanSlot
				.createBindingEndpoint("name2");
		YValueBinding yBinding = BindingFactory.eINSTANCE.createYValueBinding();
		yBinding.setModelEndpoint(yValueEPName);
		yBinding.setTargetEndpoint(yValueEPName2);
		nameSuspectInfo1_1.getBindings().add(yBinding);

		IBindingEditpart<?> bindingEP = findEditpart(yBinding);

		// ensure that binding is active
		assertEquals(3, yView.getBindingSet().getTransientBindings().size());
		assertTrue(bindingEP.isBound());
		assertFalse(bindingEP.isDisposed());

		// ----------------------------------------------------------
		// ---------------- Remove the binding again ----------------
		// ----------------------------------------------------------
		nameSuspectInfo1_1.getBindings().remove(yBinding);
		assertEquals(2, yView.getBindingSet().getTransientBindings().size());
		assertTrue(bindingEP.isDisposed());
		assertFalse(bindingEP.isBound());

	}

	/**
	 * Tests that adding a suspect directly by model has no bad effect.
	 * 
	 * @throws ContextException
	 */
	@Test
	public void test_AddSuspect() throws ContextException {

		// switch the global locale to german
		Locale.setDefault(Locale.GERMAN);

		// ----------------------------------------------------------
		// ------------- Create the layout --------------------------
		// ----------------------------------------------------------
		YView yView = factory.createView();
		YBeanSlot yBeanSlot = yView.addBeanSlot("main", Person.class);

		YStrategyLayout yLayout = cxFactory.createYStrategyLayout();
		yView.setContent(yLayout);

		// create suspects
		YSuspect nameSuspect = cxFactory.createYSuspect();
		nameSuspect.setName("name");
		nameSuspect.getValueBindingEndpoints().add(
				yBeanSlot.createBindingEndpoint("name"));
		yLayout.getSuspects().add(nameSuspect);
		YSuspect ageSuspect = cxFactory.createYSuspect();
		ageSuspect.setName("age");
		// ensure a decimal field
		ageSuspect.getTags().add("decimal");
		ageSuspect.getValueBindingEndpoints().add(
				yBeanSlot.createBindingEndpoint("age"));
		yLayout.getSuspects().add(ageSuspect);

		// ----------------------------------------------------------
		// ----------------- Render the UI --------------------------
		// ----------------------------------------------------------
		VaadinRenderer renderer = new VaadinRenderer();
		Map<String, Object> params = new HashMap<String, Object>();
		Map<String, Object> services = new HashMap<String, Object>();

		params.put(IViewContext.PARAM_SERVICES, services);
		services.put(ILayoutingStrategyProvider.class.getName(),
				new DefaultLayoutingStrategyProvider());
		services.put(IFocusingStrategyProvider.class.getName(),
				new DefaultFocusingStrategyProvider());

		viewContext = renderer.render(rootLayout, yView, params);
		viewContext.setBean("main", new Person());

		// ----------------------------------------------------------
		// ----------------- Change the suspect ---------------------
		// ----------------------------------------------------------
		YSuspect birthdaySuspect = cxFactory.createYSuspect();
		birthdaySuspect.setName("birthday");
		// ensure a decimal field
		birthdaySuspect.getTags().add("date");
		birthdaySuspect.getValueBindingEndpoints().add(
				yBeanSlot.createBindingEndpoint("birthday"));
		yLayout.getSuspects().add(birthdaySuspect);

		// Ensure that new suspect did not change anything
		YLayoutingInfo cxLayoutingInfo = yLayout.getLayoutingInfo();
		assertEquals(2, cxLayoutingInfo.getActiveSuspectInfos().size());

		// ----------------------------------------------------------
		// ----------------- Now do a relayout ----------------------
		// ----- And the new suspect should be added to the ui -----
		// ----------------------------------------------------------
		IStrategyLayoutEditpart layoutEP = findEditpart(yLayout);
		layoutEP.requestLayouting();

		cxLayoutingInfo = yLayout.getLayoutingInfo();
		assertEquals(3, cxLayoutingInfo.getActiveSuspectInfos().size());
	}

	/**
	 * Tests that adding a suspect directly by model has no bad effect.
	 * 
	 * @throws ContextException
	 */
	@Test
	public void test_Layouter_RemoveSuspect() throws ContextException {

		// switch the global locale to german
		Locale.setDefault(Locale.GERMAN);

		// ----------------------------------------------------------
		// ------------- Create the layout --------------------------
		// ----------------------------------------------------------
		YView yView = factory.createView();
		YBeanSlot yBeanSlot = yView.addBeanSlot("main", Person.class);

		YStrategyLayout yLayout = cxFactory.createYStrategyLayout();
		yView.setContent(yLayout);

		// create suspects
		YSuspect nameSuspect = cxFactory.createYSuspect();
		nameSuspect.setName("name");
		nameSuspect.getValueBindingEndpoints().add(
				yBeanSlot.createBindingEndpoint("name"));
		yLayout.getSuspects().add(nameSuspect);
		YSuspect ageSuspect = cxFactory.createYSuspect();
		ageSuspect.setName("age");
		// ensure a decimal field
		ageSuspect.getTags().add("decimal");
		ageSuspect.getValueBindingEndpoints().add(
				yBeanSlot.createBindingEndpoint("age"));
		yLayout.getSuspects().add(ageSuspect);

		// ----------------------------------------------------------
		// ----------------- Render the UI --------------------------
		// ----------------------------------------------------------
		VaadinRenderer renderer = new VaadinRenderer();
		Map<String, Object> params = new HashMap<String, Object>();
		Map<String, Object> services = new HashMap<String, Object>();

		params.put(IViewContext.PARAM_SERVICES, services);
		services.put(ILayoutingStrategyProvider.class.getName(),
				new DefaultLayoutingStrategyProvider());
		services.put(IFocusingStrategyProvider.class.getName(),
				new DefaultFocusingStrategyProvider());

		viewContext = renderer.render(rootLayout, yView, params);
		viewContext.setBean("main", new Person());

		// ----------------------------------------------------------
		// ------------- Remove the suspect --------------
		// ----------------------------------------------------------
		yLayout.getSuspects().remove(nameSuspect);

		// Ensure that new suspect did not change anything
		YLayoutingInfo cxLayoutingInfo = yLayout.getLayoutingInfo();
		assertEquals(2, cxLayoutingInfo.getActiveSuspectInfos().size());

		// ----------------------------------------------------------
		// ------------------ Do a relayouting ----------------------
		// ----------------------------------------------------------
		IStrategyLayoutEditpart layoutEP = findEditpart(yLayout);
		layoutEP.requestLayouting();

		cxLayoutingInfo = yLayout.getLayoutingInfo();
		assertEquals(1, cxLayoutingInfo.getActiveSuspectInfos().size());

	}

	/**
	 * Tests for the default focusing.
	 * 
	 * @throws ContextException
	 */
	@Test
	public void test_Focusing_Default() throws ContextException {

		// switch the global locale to german
		Locale.setDefault(Locale.GERMAN);

		// ----------------------------------------------------------
		// ------------- Create the layout --------------------------
		// ----------------------------------------------------------
		YView yView = factory.createView();
		YBeanSlot yBeanSlot = yView.addBeanSlot("main", Person.class);

		YStrategyLayout yLayout = cxFactory.createYStrategyLayout();
		yView.setContent(yLayout);

		// create suspects
		//
		YSuspect nameSuspect = cxFactory.createYSuspect();
		nameSuspect.setName("name");
		nameSuspect.getValueBindingEndpoints().add(
				yBeanSlot.createBindingEndpoint("name"));
		yLayout.getSuspects().add(nameSuspect);
		YSuspect ageSuspect = cxFactory.createYSuspect();
		ageSuspect.setName("age");
		// ensure a decimal field
		ageSuspect.getTags().add("decimal");
		ageSuspect.getValueBindingEndpoints().add(
				yBeanSlot.createBindingEndpoint("age"));
		yLayout.getSuspects().add(ageSuspect);

		// ----------------------------------------------------------
		// ------------- Create the focusing strategy ---------------
		// ----------------------------------------------------------
		YDelegatingFocusingStrategy cxStrategy = cxFactory
				.createYDelegatingFocusingStrategy();
		cxStrategy.setDelegateStrategyId("default");
		cxStrategy.setKeyStrokeDefinition(null);
		yLayout.getFocusingStrategies().add(cxStrategy);

		// ----------------------------------------------------------
		// ----------------- Render the UI --------------------------
		// ----------------------------------------------------------
		VaadinRenderer renderer = new VaadinRenderer();
		Map<String, Object> params = new HashMap<String, Object>();
		Map<String, Object> services = new HashMap<String, Object>();

		params.put(IViewContext.PARAM_SERVICES, services);
		services.put(ILayoutingStrategyProvider.class.getName(),
				new DefaultLayoutingStrategyProvider());
		services.put(IFocusingStrategyProvider.class.getName(),
				new DefaultFocusingStrategyProvider());

		viewContext = renderer.render(rootLayout, yView, params);
		viewContext.setBean("main", new Person());

		StrategyLayoutEditpart layoutEP = findEditpart(yLayout);

		// ----------------------------------------------------------
		// ------------- Ensure proper keystroke def ---------------
		// ----------------------------------------------------------
		DelegatingFocusingStrategyEditpart strategyEP = getEditpart(cxStrategy);
		KeyStrokeDefinition keyStrokeDef = strategyEP.getKeyStrokeDefinition()
				.getDefinition();
		assertEquals(KeyCode.TAB, keyStrokeDef.getKeyCode());
		assertEquals(0, keyStrokeDef.getModifierKeys().length);

		DefaultFocusingStrategy stgy = (DefaultFocusingStrategy) strategyEP
				.getStrategy();
		assertEquals(0, stgy.calledCount);
		assertEquals(1, layoutEP.getKeystrokeCallbacks().size());

		// ----------------------------------------------------------
		// ------------- Ensure focusing is done --------------------
		// ----------------------------------------------------------
		KeyStrokeCallback callback = layoutEP.getKeystrokeCallbacks().get(
				strategyEP);
		callback.callback(null, null);
		assertEquals(1, stgy.calledCount);

		// ----------------------------------------------------------
		// ------------- Ensure focus strategy removed --------------
		// ----------------------------------------------------------
		yLayout.getFocusingStrategies().clear();
		assertEquals(0, yLayout.getFocusingStrategies().size());
		assertTrue(strategyEP.isDisposed());
		assertEquals(0, layoutEP.getKeystrokeCallbacks().size());

		try {
			callback.callback(null, null);
			fail("Exception is required");
		} catch (Exception e) {
		}

	}

	/**
	 * Tests for the focusing with two focusing strategies.
	 * 
	 * @throws ContextException
	 */
	@Test
	public void test_Focusing_WithTwoStrategies() throws ContextException {

		// switch the global locale to german
		Locale.setDefault(Locale.GERMAN);

		// ----------------------------------------------------------
		// ------------- Create the layout --------------------------
		// ----------------------------------------------------------
		YView yView = factory.createView();
		YBeanSlot yBeanSlot = yView.addBeanSlot("main", Person.class);

		YStrategyLayout yLayout = cxFactory.createYStrategyLayout();
		yView.setContent(yLayout);

		// create suspects
		//
		YSuspect nameSuspect = cxFactory.createYSuspect();
		nameSuspect.setName("name");
		nameSuspect.getValueBindingEndpoints().add(
				yBeanSlot.createBindingEndpoint("name"));
		yLayout.getSuspects().add(nameSuspect);
		YSuspect ageSuspect = cxFactory.createYSuspect();
		ageSuspect.setName("age");
		// ensure a decimal field
		ageSuspect.getTags().add("decimal");
		ageSuspect.getValueBindingEndpoints().add(
				yBeanSlot.createBindingEndpoint("age"));
		yLayout.getSuspects().add(ageSuspect);

		// ----------------------------------------------------------
		// ------------- Create two focusing strategies ---------------
		// ----------------------------------------------------------
		YDelegatingFocusingStrategy cxStrategy1 = cxFactory
				.createYDelegatingFocusingStrategy();
		cxStrategy1.setDelegateStrategyId("default");
		cxStrategy1.setKeyStrokeDefinition(null);
		yLayout.getFocusingStrategies().add(cxStrategy1);

		YDelegatingFocusingStrategy cxStrategy2 = cxFactory
				.createYDelegatingFocusingStrategy();
		cxStrategy2.setDelegateStrategyId("default");
		cxStrategy2.setKeyStrokeDefinition(null);
		yLayout.getFocusingStrategies().add(cxStrategy2);

		// ----------------------------------------------------------
		// ----------------- Render the UI --------------------------
		// ----------------------------------------------------------
		VaadinRenderer renderer = new VaadinRenderer();
		Map<String, Object> params = new HashMap<String, Object>();
		Map<String, Object> services = new HashMap<String, Object>();

		params.put(IViewContext.PARAM_SERVICES, services);
		services.put(ILayoutingStrategyProvider.class.getName(),
				new DefaultLayoutingStrategyProvider());
		services.put(IFocusingStrategyProvider.class.getName(),
				new DefaultFocusingStrategyProvider());

		viewContext = renderer.render(rootLayout, yView, params);
		viewContext.setBean("main", new Person());

		StrategyLayoutEditpart layoutEP = findEditpart(yLayout);

		// ----------------------------------------------------------
		// ------------- Ensure proper keystroke def ---------------
		// ----------------------------------------------------------
		DelegatingFocusingStrategyEditpart strategy1EP = findEditpart(cxStrategy1);
		KeyStrokeDefinition keyStrokeDef1 = strategy1EP
				.getKeyStrokeDefinition().getDefinition();
		assertEquals(KeyCode.TAB, keyStrokeDef1.getKeyCode());
		assertEquals(0, keyStrokeDef1.getModifierKeys().length);

		DefaultFocusingStrategy stgy1 = (DefaultFocusingStrategy) strategy1EP
				.getStrategy();
		assertEquals(0, stgy1.calledCount);

		DelegatingFocusingStrategyEditpart strategy2EP = findEditpart(cxStrategy2);
		KeyStrokeDefinition keyStrokeDef2 = strategy2EP
				.getKeyStrokeDefinition().getDefinition();
		assertEquals(KeyCode.TAB, keyStrokeDef2.getKeyCode());
		assertEquals(0, keyStrokeDef2.getModifierKeys().length);

		DefaultFocusingStrategy stgy2 = (DefaultFocusingStrategy) strategy2EP
				.getStrategy();
		assertEquals(0, stgy2.calledCount);

		// ensure two callbacks available
		assertEquals(2, layoutEP.getKeystrokeCallbacks().size());

		assertNotSame(strategy1EP, strategy2EP);
		assertNotSame(stgy1, stgy2);

		// ----------------------------------------------------------
		// ------------- Ensure focusing is done --------------------
		// ----------------------------------------------------------
		KeyStrokeCallback callback1 = layoutEP.getKeystrokeCallbacks().get(
				strategy1EP);
		callback1.callback(null, null);
		assertEquals(1, stgy1.calledCount);

		KeyStrokeCallback callback2 = layoutEP.getKeystrokeCallbacks().get(
				strategy2EP);
		callback2.callback(null, null);
		assertEquals(1, stgy2.calledCount);

		// ----------------------------------------------------------
		// ------------- Now remove strategy 1 ----------------------
		// ----------------------------------------------------------
		yLayout.getFocusingStrategies().remove(0);

		assertEquals(1, yLayout.getFocusingStrategies().size());
		assertTrue(strategy1EP.isDisposed());
		assertEquals(1, layoutEP.getKeystrokeCallbacks().size());

		try {
			callback1.callback(null, null);
			fail("Exception is required");
		} catch (Exception e) {
		}

		// ----------------------------------------------------------
		// ------------- Now add another strategy -------------------
		// ------------- with keystroke definitions -----------------
		// ----------------------------------------------------------

		YDelegatingFocusingStrategy cxStrategy3 = cxFactory
				.createYDelegatingFocusingStrategy();
		cxStrategy3.setDelegateStrategyId("default");
		YKeyStrokeDefinition yKeyStrokeDef3 = CoreModelFactory.eINSTANCE
				.createYKeyStrokeDefinition();
		yKeyStrokeDef3.setKeyCode(YKeyCode.B);
		yKeyStrokeDef3.getModifierKeys().add(YModifierKey.ALT);
		yKeyStrokeDef3.getModifierKeys().add(YModifierKey.CTRL);
		cxStrategy3.setKeyStrokeDefinition(yKeyStrokeDef3);
		yLayout.getFocusingStrategies().add(cxStrategy3);

		DelegatingFocusingStrategyEditpart strategy3EP = findEditpart(cxStrategy3);
		KeyStrokeDefinition keyStrokeDef3 = strategy3EP
				.getKeyStrokeDefinition().getDefinition();
		assertEquals(KeyCode.B, keyStrokeDef3.getKeyCode());
		assertEquals(2, keyStrokeDef3.getModifierKeys().length);

		DefaultFocusingStrategy stgy3 = (DefaultFocusingStrategy) strategy3EP
				.getStrategy();
		assertEquals(0, stgy3.calledCount);

		// ensure two callbacks available
		assertEquals(2, layoutEP.getKeystrokeCallbacks().size());

		KeyStrokeCallback callback3 = layoutEP.getKeystrokeCallbacks().get(
				strategy3EP);
		callback3.callback(null, null);
		assertEquals(1, stgy3.calledCount);

		callback3.callback(null, null);
		assertEquals(2, stgy3.calledCount);

		// ----------------------------------------------------------
		// ------------- Now dispose all focusing strategies --------
		// ----------------------------------------------------------
		yLayout.getFocusingStrategies().remove(0);
		yLayout.getFocusingStrategies().remove(0);

		assertTrue(strategy2EP.isDisposed());
		assertTrue(strategy3EP.isDisposed());

		assertEquals(0, yLayout.getFocusingStrategies().size());
		assertEquals(0, layoutEP.getKeystrokeCallbacks().size());
		try {
			callback2.callback(null, null);
			fail("Exception is required");
		} catch (Exception e) {
		}
		try {
			callback3.callback(null, null);
			fail("Exception is required");
		} catch (Exception e) {
		}
	}

	/**
	 * Tests for the event management in Vaadin.
	 * 
	 * @throws ContextException
	 */
	@Test
	public void test_Focusing_VaadinEvents() throws ContextException {

		// switch the global locale to german
		Locale.setDefault(Locale.GERMAN);

		// ----------------------------------------------------------
		// ------------- Create the layout --------------------------
		// ----------------------------------------------------------
		YView yView = factory.createView();
		YBeanSlot yBeanSlot = yView.addBeanSlot("main", Person.class);

		YStrategyLayout yLayout = cxFactory.createYStrategyLayout();
		yView.setContent(yLayout);

		// create suspects
		//
		YSuspect nameSuspect = cxFactory.createYSuspect();
		nameSuspect.setName("name");
		nameSuspect.getValueBindingEndpoints().add(
				yBeanSlot.createBindingEndpoint("name"));
		yLayout.getSuspects().add(nameSuspect);
		YSuspect ageSuspect = cxFactory.createYSuspect();
		ageSuspect.setName("age");
		// ensure a decimal field
		ageSuspect.getTags().add("decimal");
		ageSuspect.getValueBindingEndpoints().add(
				yBeanSlot.createBindingEndpoint("age"));
		yLayout.getSuspects().add(ageSuspect);

		// ----------------------------------------------------------
		// ------------- Create the focusing strategy ---------------
		// ----------------------------------------------------------
		YDelegatingFocusingStrategy cxStrategy = cxFactory
				.createYDelegatingFocusingStrategy();
		cxStrategy.setDelegateStrategyId("default");
		cxStrategy.setKeyStrokeDefinition(null);
		yLayout.getFocusingStrategies().add(cxStrategy);

		YKeyStrokeDefinition yKeyStrokeDef = CoreModelFactory.eINSTANCE
				.createYKeyStrokeDefinition();
		yKeyStrokeDef.setKeyCode(YKeyCode.TAB);
		yKeyStrokeDef.getModifierKeys().add(YModifierKey.ALT);
		yKeyStrokeDef.getModifierKeys().add(YModifierKey.CTRL);
		cxStrategy.setKeyStrokeDefinition(yKeyStrokeDef);

		// ----------------------------------------------------------
		// ----------------- Render the UI --------------------------
		// ----------------------------------------------------------
		VaadinRenderer renderer = new VaadinRenderer();
		Map<String, Object> params = new HashMap<String, Object>();
		Map<String, Object> services = new HashMap<String, Object>();

		params.put(IViewContext.PARAM_SERVICES, services);
		services.put(ILayoutingStrategyProvider.class.getName(),
				new DefaultLayoutingStrategyProvider());
		services.put(IFocusingStrategyProvider.class.getName(),
				new DefaultFocusingStrategyProvider());

		viewContext = renderer.render(rootLayout, yView, params);
		viewContext.setBean("main", new Person());

		StrategyLayoutEditpart layoutEP = findEditpart(yLayout);

		// ----------------------------------------------------------
		// ------------- Ensure proper keystroke def ---------------
		// ----------------------------------------------------------
		DelegatingFocusingStrategyEditpart strategyEP = getEditpart(cxStrategy);
		DefaultFocusingStrategy stgy = (DefaultFocusingStrategy) strategyEP
				.getStrategy();
		assertEquals(0, stgy.calledCount);

		// ----------------------------------------------------------
		// ------------- Ensure focusing is done --------------------
		// ----------------------------------------------------------
		Panel panel = (Panel) layoutEP.getWidget();
		ActionManager actionManager = getActionManager(panel);

		ShortcutAction action = (ShortcutAction) actionManager.getActions(null,
				null)[0];
		VerticalLayout panelContent = (VerticalLayout) panel.getContent();
		VerticalLayout innerPanelContent = (VerticalLayout) panelContent
				.getComponent(0);
		actionManager.handleAction(action, panel,
				innerPanelContent.getComponent(0));
		assertEquals(1, stgy.calledCount);

		ShortcutAction action2 = new ShortcutAction("", KeyCode.ENTER,
				new int[] { ModifierKey.SHIFT });
		actionManager.handleAction(action2, panel, panel);
		assertEquals(1, stgy.calledCount);
	}

	/**
	 * Tests for the event management in Vaadin.
	 * 
	 * @throws ContextException
	 */
	@Test
	public void test_Focusing_FieldGetsFocus() throws ContextException {

		// switch the global locale to german
		Locale.setDefault(Locale.GERMAN);

		// ----------------------------------------------------------
		// ------------- Create the layout --------------------------
		// ----------------------------------------------------------
		YView yView = factory.createView();
		YBeanSlot yBeanSlot = yView.addBeanSlot("main", Person.class);

		YStrategyLayout yLayout = cxFactory.createYStrategyLayout();
		yView.setContent(yLayout);

		// create suspects
		//
		YSuspect nameSuspect = cxFactory.createYSuspect();
		nameSuspect.setName("name");
		nameSuspect.getValueBindingEndpoints().add(
				yBeanSlot.createBindingEndpoint("name"));
		yLayout.getSuspects().add(nameSuspect);
		YSuspect ageSuspect = cxFactory.createYSuspect();
		ageSuspect.setName("age");
		// ensure a decimal field
		ageSuspect.getTags().add("decimal");
		ageSuspect.getValueBindingEndpoints().add(
				yBeanSlot.createBindingEndpoint("age"));
		yLayout.getSuspects().add(ageSuspect);

		// ----------------------------------------------------------
		// ------------- Create the focusing strategy ---------------
		// ----------------------------------------------------------
		YDelegatingFocusingStrategy cxStrategy = cxFactory
				.createYDelegatingFocusingStrategy();
		cxStrategy.setDelegateStrategyId("default");
		cxStrategy.setKeyStrokeDefinition(null);
		yLayout.getFocusingStrategies().add(cxStrategy);

		YKeyStrokeDefinition yKeyStrokeDef = CoreModelFactory.eINSTANCE
				.createYKeyStrokeDefinition();
		yKeyStrokeDef.setKeyCode(YKeyCode.TAB);
		yKeyStrokeDef.getModifierKeys().add(YModifierKey.ALT);
		yKeyStrokeDef.getModifierKeys().add(YModifierKey.CTRL);
		cxStrategy.setKeyStrokeDefinition(yKeyStrokeDef);

		// ----------------------------------------------------------
		// ----------------- Render the UI --------------------------
		// ----------------------------------------------------------
		VaadinRenderer renderer = new VaadinRenderer();
		Map<String, Object> params = new HashMap<String, Object>();
		Map<String, Object> services = new HashMap<String, Object>();

		params.put(IViewContext.PARAM_SERVICES, services);
		services.put(ILayoutingStrategyProvider.class.getName(),
				new DefaultLayoutingStrategyProvider());
		services.put(IFocusingStrategyProvider.class.getName(),
				new DefaultFocusingStrategyProvider());

		viewContext = renderer.render(rootLayout, yView, params);
		viewContext.setBean("main", new Person());

		StrategyLayoutEditpart layoutEP = findEditpart(yLayout);
		DelegatingFocusingStrategyEditpart strategyEP = getEditpart(cxStrategy);
		DefaultFocusingStrategy stgy = (DefaultFocusingStrategy) strategyEP
				.getStrategy();
		assertEquals(0, stgy.calledCount);

		// ----------------------------------------------------------
		// ------------- Ensure focusing is done --------------------
		// ----------------------------------------------------------
		Panel panel = (Panel) layoutEP.getWidget();
		ActionManager actionManager = getActionManager(panel);

		YVerticalLayout yContent = (YVerticalLayout) yLayout.getLayoutingInfo()
				.getContent();
		YTextField yNameField = (YTextField) yContent.getElements().get(0);
		YDecimalField yAgeField = (YDecimalField) yContent.getElements().get(1);

		// set the name field to be focused now
		yView.setCurrentFocus(yNameField);

		// now send an TAB-event. Then the age fields needs to have the focus.
		ShortcutAction action = (ShortcutAction) actionManager.getActions(null,
				null)[0];
		VerticalLayout panelContent = (VerticalLayout) panel.getContent();
		VerticalLayout innerPanelContent = (VerticalLayout) panelContent
				.getComponent(0);
		actionManager.handleAction(action, panel,
				innerPanelContent.getComponent(0));
		assertSame(yView.getCurrentFocus(), yAgeField);

		// send an event that is not handled
		ShortcutAction action2 = new ShortcutAction("", KeyCode.ENTER,
				new int[] { ModifierKey.SHIFT });
		actionManager.handleAction(action2, panel, panel);
		assertSame(yView.getCurrentFocus(), yAgeField);

		// now send another proper event
		actionManager.handleAction(action, panel,
				innerPanelContent.getComponent(1));
		assertSame(yView.getCurrentFocus(), yNameField);

	}

	protected ActionManager getActionManager(Component panel) {
		ActionManager actionManager = null;
		try {
			Method m = AbstractComponent.class.getDeclaredMethod(
					"getActionManager", new Class[0]);
			if (!m.isAccessible()) {
				m.setAccessible(true);
			}
			actionManager = (ActionManager) m.invoke(panel, new Object[0]);
		} catch (NoSuchMethodException | IllegalAccessException
				| InvocationTargetException e) {
			fail(e.toString());
		}
		return actionManager;
	}

	private static class DefaultLayoutingStrategyProvider implements
			ILayoutingStrategyProvider {

		@Override
		public ILayoutingStrategy getStrategy() {
			return new DefaultLayoutingStrategy();
		}

	}

	private static class OnlyLayoutTaggedStrategyProvider implements
			ILayoutingStrategyProvider {

		@Override
		public ILayoutingStrategy getStrategy() {
			return new OnlyLayoutTaggedStrategy();
		}

	}

	public static class DefaultFocusingStrategyProvider implements
			IFocusingStrategyProvider {

		private IFocusingStrategy strategy;

		@Override
		public IFocusingStrategy getStrategy() {
			return strategy != null ? strategy : new DefaultFocusingStrategy();
		}
	}

	protected static class DefaultLayoutingStrategy implements
			ILayoutingStrategy {

		@Override
		public void layout(YLayoutingInfo layoutingInfo) {
			YStrategyLayout cxLayout = layoutingInfo.getLayout();
			layoutingInfo.getActiveSuspectInfos().clear();

			YVerticalLayout content = ExtensionModelFactory.eINSTANCE
					.createYVerticalLayout();

			for (YSuspect suspect : new ArrayList<YSuspect>(
					cxLayout.getSuspects())) {
				YSuspectInfo suspectInfo = layoutingInfo
						.createSuspectInfo(suspect);
				// add the suspectInfo as active suspect
				layoutingInfo.getActiveSuspectInfos().add(suspectInfo);

				YEmbeddable yEmbeddable = prepareElementForSuspect(suspectInfo);
				content.addElement(yEmbeddable);
			}

			layoutingInfo.setContent(content);
		}

		/**
		 * Creates a new element for the given suspect. Handle bindings,...
		 * 
		 * @param suspectInfo
		 * @return
		 */
		protected YEmbeddable prepareElementForSuspect(YSuspectInfo suspectInfo) {
			// create a new element for the given suspect
			YEmbeddable yEmbeddable = createElementForSuspect(suspectInfo);

			// prepares the value bindings
			prepareValueBindings(suspectInfo, yEmbeddable);

			return yEmbeddable;
		}

		protected void prepareValueBindings(YSuspectInfo suspectInfo,
				YEmbeddable yEmbeddable) {
			YSuspect cxSuspect = suspectInfo.getSuspect();
			// iterate over all elements
			for (YBindingEndpoint ep : cxSuspect.getValueBindingEndpoints()) {

				/*
				 * if yEmbeddable is a value bindable and ep a value binding
				 */
				if (ep instanceof YValueBindingEndpoint
						&& yEmbeddable instanceof YValueBindable) {
					YValueBindable yBindable = (YValueBindable) yEmbeddable;
					// make a copy -> otherwise the suspect will be changed
					YBindingEndpoint epCopy = EcoreUtil.copy(ep);

					YValueBindingEndpoint yValueEP = yBindable
							.createValueEndpoint();
					YValueBinding yBinding = BindingFactory.eINSTANCE
							.createYValueBinding();
					yBinding.setModelEndpoint((YValueBindingEndpoint) epCopy);
					yBinding.setTargetEndpoint(yValueEP);

					// register binding add suspect. Will be handled
					// automatically.
					suspectInfo.getBindings().add(yBinding);

					/*
					 * if yEmbeddable is a collection bindable and ep a list
					 * binding
					 */
				} else if (ep instanceof YListBindingEndpoint
						&& yEmbeddable instanceof YCollectionBindable) {
					YCollectionBindable yBindable = (YCollectionBindable) yEmbeddable;
					// make a copy -> otherwise the suspect will be changed
					YBindingEndpoint epCopy = EcoreUtil.copy(ep);

					YEmbeddableCollectionEndpoint yListEP = yBindable
							.createCollectionEndpoint();
					YListBinding yBinding = BindingFactory.eINSTANCE
							.createYListBinding();
					yBinding.setModelEndpoint((YListBindingEndpoint) epCopy);
					yBinding.setTargetEndpoint(yListEP);

					// register binding add suspect. Will be handled
					// automatically.
					suspectInfo.getBindings().add(yBinding);
				}
			}
		}

		protected YEmbeddable createElementForSuspect(YSuspectInfo suspectInfo) {
			YSuspect cxSuspect = suspectInfo.getSuspect();
			YEmbeddable yEmbeddable = null;
			if (cxSuspect.getTags().contains("decimal")) {
				yEmbeddable = ExtensionModelFactory.eINSTANCE
						.createYDecimalField();
			} else {
				yEmbeddable = ExtensionModelFactory.eINSTANCE
						.createYTextField();
			}
			return yEmbeddable;
		}
	}

	protected static class OnlyLayoutTaggedStrategy extends
			DefaultLayoutingStrategy {

		@Override
		public void layout(YLayoutingInfo layoutingInfo) {
			YStrategyLayout cxLayout = layoutingInfo.getLayout();
			layoutingInfo.getActiveSuspectInfos().clear();

			YVerticalLayout content = ExtensionModelFactory.eINSTANCE
					.createYVerticalLayout();

			for (YSuspect suspect : new ArrayList<YSuspect>(
					cxLayout.getSuspects())) {
				if (suspect.getTags().isEmpty()) {
					continue;
				}
				YSuspectInfo suspectInfo = layoutingInfo
						.createSuspectInfo(suspect);
				// add the suspectInfo as active suspect
				layoutingInfo.getActiveSuspectInfos().add(suspectInfo);

				YEmbeddable yEmbeddable = prepareElementForSuspect(suspectInfo);
				content.addElement(yEmbeddable);
			}

			layoutingInfo.setContent(content);
		}
	}

	/**
	 * The default focusing strategy focuses the next field in the order they
	 * appear in the layout.
	 */
	private static class DefaultFocusingStrategy implements IFocusingStrategy {

		protected int calledCount;

		@Override
		public void focus(Object source, Object target, YStrategyLayout cxLayout) {
			calledCount++;

			YView yView = cxLayout.getView();
			IViewContext context = ModelUtil.getViewContext(yView);
			IWidgetAssocationsService<Object, ? extends YElement> service = context
					.getService(IWidgetAssocationsService.ID);
			YEmbeddable yCurrentFocus = (YEmbeddable) service
					.getModelElement(target);
			YEmbeddable yNextFocus = findNextElementToFocus(yCurrentFocus);

			yView.setCurrentFocus((YFocusable) yNextFocus);

		}

		/**
		 * Looks for the next element to be focused. Therefore it uses a round
		 * robin approach. If end of elements are reached, we start by index = 0
		 * again.
		 * 
		 * @param yElement
		 * @return
		 */
		protected YEmbeddable findNextElementToFocus(YEmbeddable yElement) {
			if (yElement == null) {
				return null;
			}
			YLayout yParent = (YLayout) yElement.eContainer();
			int index = yParent.getElements().indexOf(yElement);
			if (index == yParent.getElements().size() - 1) {
				// element is the last -> Start again
				index = 0;
			} else {
				// use the next element
				index = index + 1;
			}

			YEmbeddable nextFocusElement = yParent.getElements().get(index);
			return nextFocusElement;
		}

		@Override
		public KeyStrokeDefinition getKeyStrokeDefinition() {
			// returns the default keystroke definition if nothing else was
			// defined.
			KeyStrokeDefinition result = new KeyStrokeDefinition("TestMe",
					KeyCode.TAB, new int[0]);
			return result;
		}

	}

	private static class OtherFocusingStrategy extends DefaultFocusingStrategy {

	}

}
