/**
 *                                                                            
 *  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:                                                      
 * 	   Florian Pirchner - Initial implementation
 * 
 */
package org.eclipse.osbp.ecview.extension.strategy;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeSet;

import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.EMap;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.osbp.dsl.dto.lib.impl.DtoServiceAccess;
import org.eclipse.osbp.ecview.core.common.context.IDialogViewContextCallback;
import org.eclipse.osbp.ecview.core.common.context.IDtoServiceCallback;
import org.eclipse.osbp.ecview.core.common.context.IViewContext;
import org.eclipse.osbp.ecview.core.common.extender.IECViewProviderService;
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.YBindingUpdateStrategy;
import org.eclipse.osbp.ecview.core.common.model.binding.YDetailValueBindingEndpoint;
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.binding.YVisibilityProcessorValueBindingEndpoint;
import org.eclipse.osbp.ecview.core.common.model.core.YAlignment;
import org.eclipse.osbp.ecview.core.common.model.core.YBeanSlot;
import org.eclipse.osbp.ecview.core.common.model.core.YBeanSlotValueBindingEndpoint;
import org.eclipse.osbp.ecview.core.common.model.core.YCollectionBindable;
import org.eclipse.osbp.ecview.core.common.model.core.YConverter;
import org.eclipse.osbp.ecview.core.common.model.core.YDetailBeanSlot;
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.YField;
import org.eclipse.osbp.ecview.core.common.model.core.YFocusable;
import org.eclipse.osbp.ecview.core.common.model.core.YLayout;
import org.eclipse.osbp.ecview.core.common.model.core.YSelectionBindable;
import org.eclipse.osbp.ecview.core.common.model.core.YTaggable;
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.model.datatypes.YDatadescription;
import org.eclipse.osbp.ecview.core.common.model.datatypes.impl.DatatypesFactoryImpl;
import org.eclipse.osbp.ecview.core.common.model.validation.ValidationFactory;
import org.eclipse.osbp.ecview.core.common.model.validation.YBeanValidationValidator;
import org.eclipse.osbp.ecview.core.common.model.validation.YUniqueAttributeValidator;
import org.eclipse.osbp.ecview.core.common.util.ECViewUtil;
import org.eclipse.osbp.ecview.core.extension.model.datatypes.ExtDatatypesFactory;
import org.eclipse.osbp.ecview.core.extension.model.datatypes.YDateTimeDatatype;
import org.eclipse.osbp.ecview.core.extension.model.datatypes.YDateTimeFormat;
import org.eclipse.osbp.ecview.core.extension.model.datatypes.YDateTimeResolution;
import org.eclipse.osbp.ecview.core.extension.model.extension.ExtensionModelFactory;
import org.eclipse.osbp.ecview.core.extension.model.extension.YBeanReferenceField;
import org.eclipse.osbp.ecview.core.extension.model.extension.YButton;
import org.eclipse.osbp.ecview.core.extension.model.extension.YColumn;
import org.eclipse.osbp.ecview.core.extension.model.extension.YComboBox;
import org.eclipse.osbp.ecview.core.extension.model.extension.YDateTime;
import org.eclipse.osbp.ecview.core.extension.model.extension.YDecimalField;
import org.eclipse.osbp.ecview.core.extension.model.extension.YDialogComponent;
import org.eclipse.osbp.ecview.core.extension.model.extension.YEnumComboBox;
import org.eclipse.osbp.ecview.core.extension.model.extension.YEnumOptionsGroup;
import org.eclipse.osbp.ecview.core.extension.model.extension.YFilteringComponent;
import org.eclipse.osbp.ecview.core.extension.model.extension.YFormLayout;
import org.eclipse.osbp.ecview.core.extension.model.extension.YHorizontalLayout;
import org.eclipse.osbp.ecview.core.extension.model.extension.YNumericField;
import org.eclipse.osbp.ecview.core.extension.model.extension.YPanel;
import org.eclipse.osbp.ecview.core.extension.model.extension.YPasswordField;
import org.eclipse.osbp.ecview.core.extension.model.extension.YSlider;
import org.eclipse.osbp.ecview.core.extension.model.extension.YSuggestTextField;
import org.eclipse.osbp.ecview.core.extension.model.extension.YTab;
import org.eclipse.osbp.ecview.core.extension.model.extension.YTabSheet;
import org.eclipse.osbp.ecview.core.extension.model.extension.YTable;
import org.eclipse.osbp.ecview.core.extension.model.extension.YTextArea;
import org.eclipse.osbp.ecview.core.extension.model.extension.YVerticalLayout;
import org.eclipse.osbp.ecview.core.extension.model.extension.YVerticalLayoutCellStyle;
import org.eclipse.osbp.ecview.core.extension.model.extension.impl.ExtensionModelFactoryImpl;
import org.eclipse.osbp.ecview.core.util.emf.ModelUtil;
import org.eclipse.osbp.ecview.extension.api.ILayoutingStrategy;
import org.eclipse.osbp.ecview.extension.grid.CxGrid;
import org.eclipse.osbp.ecview.extension.grid.util.CxGridUtil;
import org.eclipse.osbp.ecview.extension.model.YBlobUploadComponent;
import org.eclipse.osbp.ecview.extension.model.YCollectionSuspect;
import org.eclipse.osbp.ecview.extension.model.YColumnInfo;
import org.eclipse.osbp.ecview.extension.model.YCustomDecimalField;
import org.eclipse.osbp.ecview.extension.model.YECviewFactory;
import org.eclipse.osbp.ecview.extension.model.YI18nComboBox;
import org.eclipse.osbp.ecview.extension.model.YIconComboBox;
import org.eclipse.osbp.ecview.extension.model.YLayoutingInfo;
import org.eclipse.osbp.ecview.extension.model.YMaskedDecimalField;
import org.eclipse.osbp.ecview.extension.model.YMaskedTextField;
import org.eclipse.osbp.ecview.extension.model.YPairComboBox;
import org.eclipse.osbp.ecview.extension.model.YRichTextArea;
import org.eclipse.osbp.ecview.extension.model.YStrategyLayout;
import org.eclipse.osbp.ecview.extension.model.YSubTypeBaseSuspect;
import org.eclipse.osbp.ecview.extension.model.YSubTypeSuspect;
import org.eclipse.osbp.ecview.extension.model.YSuspect;
import org.eclipse.osbp.ecview.extension.model.YSuspectInfo;
import org.eclipse.osbp.ecview.extension.model.YTypedCompoundSuspect;
import org.eclipse.osbp.ecview.extension.model.YTypedSuspect;
import org.eclipse.osbp.ecview.extension.model.converter.YConverterFactory;
import org.eclipse.osbp.ecview.extension.model.converter.YCustomDecimalConverter;
import org.eclipse.osbp.ecview.extension.model.converter.YSimpleDecimalConverter;
import org.eclipse.osbp.ecview.extension.model.visibility.YSubTypeVisibilityProcessor;
import org.eclipse.osbp.ecview.extension.model.visibility.YVisibilityFactory;
import org.eclipse.osbp.ecview.extension.strategy.util.PdfPrintService;
import org.eclipse.osbp.preferences.ProductConfiguration;
import org.eclipse.osbp.runtime.common.filter.IDTOService;
import org.eclipse.osbp.runtime.common.layouting.IPropertyConstants;
import org.eclipse.osbp.ui.api.metadata.IDSLMetadataService;
import org.eclipse.osbp.ui.api.themes.EnumCssClass;
import org.eclipse.osbp.ui.api.themes.IThemeResourceService;
import org.eclipse.osbp.ui.api.themes.IThemeResourceService.ThemeResourceType;
import org.eclipse.osbp.ui.api.user.IUser;
import org.eclipse.osbp.ui.api.useraccess.AbstractAuthorization.Action;
import org.eclipse.osbp.ui.api.useraccess.AbstractAuthorization.Group;
import org.eclipse.osbp.ui.api.useraccess.AbstractSubOrganization;
import org.eclipse.osbp.ui.api.useraccess.IOrganizationService;
import org.eclipse.osbp.ui.api.useraccess.IPosition;
import org.eclipse.osbp.ui.api.useraccess.IUserAccessService;
import org.eclipse.osbp.utils.functionnormalizer.api.FunctionTypingAPI;
import org.eclipse.osbp.utils.functionnormalizer.entities.FunctionType;
import org.eclipse.osbp.utils.themes.ui.VaaclipseUiTheme;
import org.eclipse.osbp.utils.themes.ui.VaaclipseUiTheme.ThemeList;
import org.eclipse.xtext.util.Pair;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * The Class AbstractLayoutingStrategy.
 */
@SuppressWarnings("restriction")
public abstract class AbstractLayoutingStrategy implements ILayoutingStrategy {

	/** The Constant UNGROUPED for attributes not grouped under a groupName. */
	private static final String UNGROUPED = "<ungrouped>";

	/** The filtered category. */
	private final String filteredCategory;

	/** The function typing api. */
	private FunctionTypingAPI functionTypingApi;

	/** The user access service. */
	private IUserAccessService userAccessService;

	/** The view context. */
	private IViewContext viewContext;

	private YLayoutingInfo layoutingInfo;

	private IDSLMetadataService dslMetadataService;

	private GroupInfo currentGroup;

	private int layoutingIndex;

	private List<YLayout> layoutList = new ArrayList<>();

	private int currentIndex = 0;

	private YFormLayout beanLayout;

	private String beanTabName = null;

	private IUser user;

	private IThemeResourceService themeResourceService;

	private static Map<String, Boolean> isSuspectEditable = new HashMap<>();

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

	/**
	 * Only given category is shown.
	 *
	 * @param filteredCategory
	 *            the filtered category
	 */
	public AbstractLayoutingStrategy(String filteredCategory) {
		super();
		this.filteredCategory = filteredCategory;
		this.functionTypingApi = new FunctionTypingAPI();
	}

	public YLayoutingInfo getLayoutingInfo() {
		return layoutingInfo;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.osbp.ecview.extension.api.ILayoutingStrategy#layout(org.
	 * eclipse .osbp.ecview.extension.model.YLayoutingInfo)
	 */
	@Override
	public void layout(YLayoutingInfo layoutingInfo) {
		LOGGER.trace("{}", "layout");
		this.layoutingInfo = layoutingInfo;

		clean();

		YStrategyLayout yLayout = layoutingInfo.getLayout();
		layoutingInfo.getActiveSuspectInfos().clear();
		YLayout layout = null;
		if (yLayout.getNumberColumns() > 0) {
			layout = createColumnedLayout(yLayout.getNumberColumns());
		} else {
			layout = createContentLayout();
		}
		YEmbeddable content;

		layoutingInfo.getView().getTags().add(TAG__AUTOBINDED);

		viewContext = ModelUtil.getViewContext(yLayout);
		userAccessService = viewContext.getService(IUserAccessService.class.getName());
		dslMetadataService = viewContext.getService(IDSLMetadataService.class.getName());
		themeResourceService = viewContext.getService(IThemeResourceService.class.getName());
		user = viewContext.getService(IUser.class.getName());

		// Identify if a TabSheet is necessary due to existing table or grid
		if (isTabSheetNeeded(yLayout.getSuspects())) {
			YTabSheet tabSheet;
			tabSheet = ExtensionModelFactory.eINSTANCE.createYTabSheet();
			YTab tab = ExtensionModelFactory.eINSTANCE.createYTab();
			String[] tokens = yLayout.getView().getViewName().split("\\.");
			tab.setLabelI18nKey(tokens[tokens.length - 1]);
			tab.setEmbeddable(layout);
			tabSheet.getTabs().add(tab);
			content = tabSheet;
		} else {
			content = layout;
		}
		// Creates YEmbeddables from YSuspects
		for (YSuspect suspect : createSuspectList(yLayout)) {
			if (filteredCategory != null && !"".equals(filteredCategory)
					&& !suspect.getTags().contains(filteredCategory)) {
				// filter the suspect
				continue;
			}

			// Create a new suspect info.
			YSuspectInfo suspectInfo = layoutingInfo.createSuspectInfo(suspect);
			// add the suspectInfo as active suspect
			layoutingInfo.getActiveSuspectInfos().add(suspectInfo);

			YEmbeddable yEmbeddable = prepareElementForSuspect(suspectInfo);
			if (yEmbeddable != null) {
				addElement(content, yEmbeddable, suspectInfo, yLayout.getNumberColumns());
			}
		}
		layoutingInfo.setContent(content);

	}

	private YLayout createColumnedLayout(int numberColumns) {
		LOGGER.trace("{}", "createColumnedLayout");
		YHorizontalLayout layout = ExtensionModelFactory.eINSTANCE.createYHorizontalLayout();
		for (int i = 0; i < numberColumns; i++) {
			layoutList.add(ExtensionModelFactory.eINSTANCE.createYVerticalLayout());
		}
		for (YLayout layoutListItem : layoutList) {
			layout.addElement(layoutListItem);
		}
		return layout;
	}

	private void addColumnedElement(final YLayout layout, final YEmbeddable element, int numberColumns) {
		LOGGER.trace("{}", "addColumnedElement");
		int idx = currentIndex % numberColumns;
		int lastAddedIdx = layoutList.get(idx).getElements().size();
		YLayout subLayout = null;
		if (lastAddedIdx == 0) {
			if (element instanceof YPanel) {
				subLayout = ExtensionModelFactory.eINSTANCE.createYVerticalLayout();
			} else {
				subLayout = ExtensionModelFactory.eINSTANCE.createYFormLayout();
			}
		} else {
			subLayout = (YLayout) layoutList.get(idx).getElement(lastAddedIdx - 1);
			if (subLayout instanceof YVerticalLayout && !(element instanceof YPanel)) {
				subLayout = ExtensionModelFactory.eINSTANCE.createYFormLayout();
			}
			if (subLayout instanceof YFormLayout && element instanceof YPanel) {
				subLayout = ExtensionModelFactory.eINSTANCE.createYVerticalLayout();
			}
		}
		subLayout.addElement(element);
		subLayout.setCssClass("os-no-padding");
		layoutList.get(idx).addElement(subLayout);
		currentIndex++;
	}

	/**
	 * Removes elements tagged with #TAG__TO_BE_CLEANED from the view.
	 */
	private void clean() {
		LOGGER.trace("{}", "clean");
		YView view = layoutingInfo.getView();
		TreeIterator<Object> contents = EcoreUtil.getAllContents(view, true);
		while (contents.hasNext()) {
			Object element = contents.next();
			if (element instanceof YTaggable) {
				YTaggable taggable = (YTaggable) element;
				if (taggable.getTags().contains(TAG__TO_BE_CLEANED)) {
					EcoreUtil.remove(taggable);
				}
			}
		}
	}

	/**
	 * Creates the suspect list.
	 *
	 * @param yLayout
	 *            the y layout
	 * @return the array list
	 */
	private ArrayList<YSuspect> createSuspectList(YStrategyLayout yLayout) {
		LOGGER.trace("{}", "createSuspectList");
		ArrayList<YSuspect> suspectList = new ArrayList<>(yLayout.getSuspects().size());
		ArrayList<YSuspect> suspectCollectionList = new ArrayList<>(yLayout.getSuspects().size());
		for (YSuspect ySuspect : yLayout.getSuspects()) {
			if (ySuspect.getTags().contains(TAG__TABLE) || ySuspect.getTags().contains(TAG__GRID)) {
				suspectCollectionList.add(ySuspect);
			} else if (ySuspect instanceof YTypedCompoundSuspect && ySuspect.getTags().contains(TAG__BEANONTAB)) {
				for (YSuspect childSuspect : ((YTypedCompoundSuspect) ySuspect).getChildren()) {
					childSuspect.getTags().add(TAG__BEAN);
					childSuspect.setGroupName(ySuspect.getLabelI18nKey());
					suspectCollectionList.add(childSuspect);
				}
			} else {
				suspectList.add(ySuspect);
			}
		}
		Collections.sort(suspectCollectionList, new SuspectComparator());
		groupSuspects(suspectList, suspectCollectionList);
		return suspectList;
	}

	private void groupSuspects(ArrayList<YSuspect> suspectList, ArrayList<YSuspect> suspectCollectionList) {
		// sort by first appearance in entity
		Map<String, List<YSuspect>> suspectMap = new LinkedHashMap<>();
		List<String> suspectGroupList = new ArrayList<>();
		for (YSuspect suspect : suspectList) {
			if (suspect.getGroupName() == null) {
				String groupName = UNGROUPED;
				if (suspect instanceof YTypedCompoundSuspect && !suspect.getTags().contains(TAG__BEANONTAB)) {
					groupName = suspect.getLabelI18nKey();
				}
				suspectMap.put(groupName, new ArrayList<YSuspect>());
				if (!suspectGroupList.contains(groupName)) {
					suspectGroupList.add(groupName);
				}
			} else {
				suspectMap.put(suspect.getGroupName(), new ArrayList<YSuspect>());
				if (!suspectGroupList.contains(suspect.getGroupName())) {
					suspectGroupList.add(suspect.getGroupName());
				}
			}
		}
		for (YSuspect suspect : suspectList) {
			if (suspect.getGroupName() == null) {
				String groupName = UNGROUPED;
				if (suspect instanceof YTypedCompoundSuspect && !suspect.getTags().contains(TAG__BEANONTAB)) {
					groupName = suspect.getLabelI18nKey();
				}
				suspectMap.get(groupName).add(suspect);
			} else {
				suspectMap.get(suspect.getGroupName()).add(suspect);
			}
		}
		suspectList.clear();
		for (String suspectGroup : suspectGroupList) {
			suspectList.addAll(suspectMap.get(suspectGroup));
		}
		// add the collections for the following tabs
		suspectList.addAll(suspectCollectionList);
	}

	/**
	 * Adds the element.
	 *
	 * @param content
	 *            the content
	 * @param element
	 *            the element
	 * @param suspectInfo
	 *            the suspect info
	 */
	private void addElement(YEmbeddable content, YEmbeddable element, YSuspectInfo suspectInfo, int numberColumns) {
		LOGGER.trace("{}", "addElement");
		if (content instanceof YTabSheet) {
			EList<YTab> tabs = ((YTabSheet) content).getTabs();
			if (suspectInfo.getSuspect().getTags().contains(TAG__TABLE)
					|| suspectInfo.getSuspect().getTags().contains(TAG__GRID)) {
				YTab tab = ExtensionModelFactory.eINSTANCE.createYTab();
				tab.setLabelI18nKey(suspectInfo.getSuspect().getLabelI18nKey());
				YVerticalLayout layout = ExtensionModelFactory.eINSTANCE.createYVerticalLayout();
				layout.addElement(element);
				YVerticalLayoutCellStyle cellStyle = layout.addCellStyle(element);
				cellStyle.setAlignment(YAlignment.FILL_FILL);
				tab.setEmbeddable(layout);
				tabs.add(tab);
			} else if (suspectInfo.getSuspect().getTags().contains(TAG__BEAN)) {
				if (beanTabName == null || !suspectInfo.getSuspect().getGroupName().equals(beanTabName)) {
					YTab tab = ExtensionModelFactory.eINSTANCE.createYTab();
					tab.setLabelI18nKey(suspectInfo.getSuspect().getGroupName());
					beanLayout = ExtensionModelFactory.eINSTANCE.createYFormLayout();
					tab.setEmbeddable(beanLayout);
					tabs.add(tab);
					beanTabName = suspectInfo.getSuspect().getGroupName();
				}
				beanLayout.addElement(element);
			} else {
				if (suspectInfo.getSuspect().getTags().contains(TAG__GROUP)) {
					createGrouping(tabs.get(0).getEmbeddable(), element, suspectInfo, numberColumns);
				} else {
					// Gets the YLayout of the first tab to add the element
					if (numberColumns > 0) {
						addColumnedElement((YLayout) tabs.get(0).getEmbeddable(), element, numberColumns);
					} else {
						addElement((YLayout) tabs.get(0).getEmbeddable(), element);
					}
				}
			}
		} else {
			if (suspectInfo.getSuspect().getTags().contains(TAG__GROUP)) {
				createGrouping(content, element, suspectInfo, numberColumns);
			} else {
				if (numberColumns > 0) {
					addColumnedElement((YLayout) content, element, numberColumns);
				} else {
					addElement((YLayout) content, element);
				}
			}

		}
		if (element instanceof YFocusable) {
			applyNextLayoutingIndex((YFocusable) element);
		}
	}

	private void createGrouping(YEmbeddable content, YEmbeddable element, YSuspectInfo suspectInfo, int numberColumns) {
		LOGGER.trace("{}", "createGrouping");
		String group = suspectInfo.getSuspect().getGroupName();
		YFormLayout groupLayout = null;
		if (currentGroup == null || !currentGroup.name.equals(group)) {
			YPanel panel = ExtensionModelFactory.eINSTANCE.createYPanel();
			panel.setCssClass("os-group-panel os-caption-large");
			panel.setLabelI18nKey(group);
			groupLayout = ExtensionModelFactory.eINSTANCE.createYFormLayout();
			panel.addElement(groupLayout);
			currentGroup = new GroupInfo(group, groupLayout);
			if (numberColumns > 0) {
				addColumnedElement((YLayout) content, panel, numberColumns);
			} else {
				addElement((YLayout) content, panel);
			}
		} else {
			groupLayout = currentGroup.group;
		}
		groupLayout.addElement(element);
		if (element instanceof YFocusable) {
			applyNextLayoutingIndex((YFocusable) element);
		}
	}

	/**
	 * Creates the content layout.
	 *
	 * @return the y layout
	 */
	protected abstract YLayout createContentLayout();

	/**
	 * Adds the element.
	 *
	 * @param layout
	 *            the layout
	 * @param element
	 *            the element
	 */
	protected abstract void addElement(YLayout layout, YEmbeddable element);

	protected void applyNextLayoutingIndex(YFocusable focusable) {
		if (focusable instanceof YPanel) {
			return;
		}
		focusable.setLayoutIdx(layoutingIndex);
		layoutingIndex++;
	}

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

		return yEmbeddable;
	}

	/**
	 * Create the value or list bindings for the given element.
	 *
	 * @param suspectInfo
	 *            the suspect info
	 * @param yEmbeddable
	 *            the y embeddable
	 */
	protected void prepareValueBindings(YSuspectInfo suspectInfo, YEmbeddable yEmbeddable) {
		LOGGER.trace("{}", "prepareValueBinding");
		YSuspect ySuspect = suspectInfo.getSuspect();
		// iterate over all elements
		for (YBindingEndpoint ep : ySuspect.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;
				if (suspectInfo.getTags().contains(ILayoutingStrategy.TAG__RICH_TEXT__BLOB)) {
					// if we need to bind the blob value, then we need to use a
					// different endpoint
					YRichTextArea richtText = (YRichTextArea) yEmbeddable;
					yValueEP = richtText.createBlobValueEndpoint();
				} else if (suspectInfo.getTags().contains(ILayoutingStrategy.TAG__SUGGEST_TEXT)) {
					if (ep.getTags().contains("dtoBinding")) {
						// if we need to bind the blob value, then we need to use a
						// different endpoint
						YSuggestTextField suggestText = (YSuggestTextField) yEmbeddable;
						yValueEP = suggestText.createSelectionEndpoint();
					} else {
						yValueEP = yBindable.createValueEndpoint();
					}
				} else {
					yValueEP = yBindable.createValueEndpoint();
				}

				YValueBinding yBinding = BindingFactory.eINSTANCE.createYValueBinding();

				// copy all tags from original bindingEndpoint to targets
				//
				yBinding.getTags().addAll(epCopy.getTags());
				epCopy.getTags().addAll(epCopy.getTags());
				yValueEP.getTags().addAll(epCopy.getTags());

				yBinding.setModelEndpoint((YValueBindingEndpoint) epCopy);
				yBinding.setTargetEndpoint(yValueEP);

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

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

				YValueBindingEndpoint yValueEP = yBindable.createSelectionEndpoint();
				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);
			}
		}

	}

	/**
	 * Creates the element for suspect.
	 *
	 * @param suspectInfo
	 *            the suspect info
	 * @return the y embeddable
	 */
	protected YEmbeddable createElementForSuspect(YSuspectInfo suspectInfo) {
		LOGGER.trace("{}", "createElementForSuspect");
		YSuspect ySuspect = suspectInfo.getSuspect();
		YEmbeddable yEmbeddable = null;
		if (ySuspect.getTags().contains(TAG__DECIMAL)) {
			if (existFunctionsInProperties(ySuspect)) {
				yEmbeddable = YECviewFactory.eINSTANCE.createYCustomDecimalField();
				setCustomDecimalConverter(yEmbeddable, ySuspect);
			} else {
				yEmbeddable = ExtensionModelFactory.eINSTANCE.createYDecimalField();
				((YDecimalField) yEmbeddable).setConverter(getConverter(ySuspect.getProperties()));
			}
		} else if (ySuspect.getTags().contains(TAG__TEXT)) {
			yEmbeddable = ExtensionModelFactory.eINSTANCE.createYTextField();
		} else if (ySuspect.getTags().contains(TAG__PASSWORD)) {
			yEmbeddable = createPasswordField(ySuspect);
		} else if (ySuspect.getTags().contains(TAG__SAVEANDNEW)) {
			yEmbeddable = createSaveAndNew(ySuspect);
		} else if (ySuspect.getTags().contains(TAG__SUGGEST_TEXT)) {
			YTypedSuspect typedSuspect = (YTypedSuspect) ySuspect;
			YSuggestTextField yField = ExtensionModelFactory.eINSTANCE.createYSuggestTextField();
			suspectInfo.getTags().add(TAG__SUGGEST_TEXT);
			// the type the field will query for matching entries
			yField.setType(typedSuspect.getType());
			yField.setTypeQualifiedName(typedSuspect.getTypeQualifiedName());
			yField.setUseSuggestions(true);
			// the caption and filter property
			yField.setItemCaptionProperty(typedSuspect.getProperties().get(IPropertyConstants.PROPERTY__ITEM_CAPTION));
			yField.setItemFilterProperty(typedSuspect.getProperties().get(IPropertyConstants.PROPERTY__ITEM_FILTER));
			yField.setItemUUIDProperty(typedSuspect.getProperties().get(IPropertyConstants.PROPERTY__ITEM_UUID));
			yEmbeddable = yField;
		} else if (ySuspect.getTags().contains(TAG__TEXTAREA)) {
			yEmbeddable = ExtensionModelFactory.eINSTANCE.createYTextArea();
			if (!ySuspect.getProperties().isEmpty()) {
				try {
					int rows = new Integer(ySuspect.getProperties().get(IPropertyConstants.PROPERTY_TEXTAREA));
					((YTextArea) yEmbeddable).setRows(rows);
				} catch (NumberFormatException ex) {
					// Do nothing!!!
				}
			}
			yEmbeddable.getProperties().addAll(ySuspect.getProperties());
		} else if (ySuspect.getTags().contains(TAG__NUMBER)) {
			yEmbeddable = ExtensionModelFactory.eINSTANCE.createYNumericField();
		} else if (ySuspect.getTags().contains(TAG__SLIDER)) {
			YSlider slider = ExtensionModelFactory.eINSTANCE.createYSlider();
			slider.setMinValue(Integer.valueOf(ySuspect.getProperties().get("min")));
			slider.setMaxValue(Integer.valueOf(ySuspect.getProperties().get("max")));
			yEmbeddable = slider;
		} else if (ySuspect.getTags().contains(TAG__DATE)) {
			yEmbeddable = ExtensionModelFactory.eINSTANCE.createYDateTime();
			for (Entry<String, String> prop : ySuspect.getProperties()) {
				if (YDateTimeFormat.get(prop.getKey().toUpperCase()) != null) {
					YDateTimeDatatype yDt = ExtDatatypesFactory.eINSTANCE.createYDateTimeDatatype();
					yDt.setFormat(YDateTimeFormat.get(prop.getKey().toUpperCase()));
					if (YDateTimeResolution.get(prop.getValue().toUpperCase()) != null) {
						yDt.setResolution(YDateTimeResolution.get(prop.getValue().toUpperCase()));
					}
					if (ySuspect.getProperties().containsKey(YDateTimeDatatype.SHOWWEEKNUMBERS)) {
						yDt.setShowISOWeeknumbers(true);
					}
					((YDateTime) yEmbeddable).setDatatype(yDt);
					// we found a format - ignore the rest if any
					break;
				}
			}
		} else if (ySuspect.getTags().contains(TAG__BOOLEAN)) {
			yEmbeddable = ExtensionModelFactory.eINSTANCE.createYCheckBox();
		} else if (ySuspect.getTags().contains(TAG__BLOB)) {
			yEmbeddable = createYBlobUploadComponent(ySuspect);
		} else if (ySuspect.getTags().contains(TAG__GRID)) {
			yEmbeddable = createGrid(ySuspect);
		} else if (ySuspect.getTags().contains(TAG__BEAN_REFERENCE)) {
			yEmbeddable = createYBeanReference(ySuspect);
		} else if (ySuspect.getTags().contains(TAG__TABLE)) {
			yEmbeddable = createTable(ySuspect);
		} else if (ySuspect.getTags().contains(TAG__ENUM_OPTIONS)) {
			yEmbeddable = createEnumOptions(ySuspect);
		} else if (ySuspect.getTags().contains(TAG__ENUM_COMBO)) {
			yEmbeddable = createEnumCombo(ySuspect);
		} else if (ySuspect.getTags().contains(TAG__RICH_TEXT__STRING)) {
			yEmbeddable = createRichTextFieldString(ySuspect);
		} else if (ySuspect.getTags().contains(TAG__MASKED_TEXT_FIELD)) {
			yEmbeddable = createMaskedTextField(ySuspect);
		} else if (ySuspect.getTags().contains(TAG__MASKED_DECIMAL_FIELD)) {
			yEmbeddable = createMaskedDecimalField(ySuspect);
		} else if (ySuspect.getTags().contains(TAG__RICH_TEXT__BLOB)) {
			yEmbeddable = createRichTextFieldBlob(ySuspect);
			suspectInfo.getTags().add(TAG__RICH_TEXT__BLOB);
		} else if (ySuspect.getTags().contains(TAG__ORGANIZATION_COMBO)) {
			yEmbeddable = createOrganizationCombo(ySuspect);
		} else if (ySuspect.getTags().contains(TAG__PERSPECTIVE_COMBO)) {
			yEmbeddable = createPerspectiveCombo(ySuspect);
		} else if (ySuspect.getTags().contains(TAG__PRINTSERVICE_COMBO)) {
			yEmbeddable = createPrintServiceCombo(ySuspect);
		} else if (ySuspect.getTags().contains(TAG__THEME_COMBO)) {
			yEmbeddable = createThemeCombo(ySuspect);
		} else if (ySuspect.getTags().contains(TAG__I18N_COMBO)) {
			yEmbeddable = createI18nCombo(ySuspect);
		} else if (ySuspect.getTags().contains(TAG__MODEL_COMBO)) {
			yEmbeddable = createModelCombo(ySuspect);
		} else if (ySuspect.getTags().contains(TAG__IMAGE_PICKER)) {
			yEmbeddable = createIconComboBox(ySuspect);
		} else if (ySuspect.getTags().contains(TAG__SUBTYPES_ROOT)) {
			createSubTypeElements((YSubTypeBaseSuspect) ySuspect);
		} else if (ySuspect.getTags().contains(TAG__DTO) && !ySuspect.getTags().contains(TAG__BEANONTAB)) {
			createNestedBeanElements((YTypedCompoundSuspect) ySuspect);
		} else {
			yEmbeddable = ExtensionModelFactory.eINSTANCE.createYTextField();
		}
		if (yEmbeddable != null) {
			yEmbeddable.setLabelI18nKey(ySuspect.getLabelI18nKey());
			yEmbeddable.setLabel(ySuspect.getLabel());
			yEmbeddable.setId(ySuspect.getId());
			if (ySuspect.getTags().contains(TAG__EXTRASTYLE)) {
				yEmbeddable.setCssClass(EnumCssClass.BOX.styleName()+" "+ySuspect.getStyleName());
			} else {
				yEmbeddable.setCssClass(EnumCssClass.BOX.styleName());
			}
			if (ySuspect.getTags().contains(TAG__READONLY)) {
				yEmbeddable.setReadonly(true);
			}

			suspectInfo.setTarget(yEmbeddable);

			if (ySuspect.getTags().contains(TAG__ON_KANBAN_CARD)) {
				yEmbeddable.getTags().add(TAG__ON_KANBAN_CARD);
			}

			// --- Required for validation ---
			if (ySuspect.getTags().contains(TAG__CONSTRAINT)) {
				if (yEmbeddable instanceof YField) {
					YBeanValidationValidator validator = ValidationFactory.eINSTANCE.createYBeanValidationValidator();
					validator.setBvalClassFullyQualifiedName(
							ySuspect.getProperties().get(IPropertyConstants.PROPERTY_CLASS));
					validator.setBvalProperty(ySuspect.getProperties().get(IPropertyConstants.PROPERTY_NAME));
					((YField) yEmbeddable).getValidators().add(validator);
					yEmbeddable.setCssClass(yEmbeddable.getCssClass() + " os-constraint");
				}
			}

			if (ySuspect.getTags().contains(TAG__UNIQUE)) {
				if (yEmbeddable instanceof YField) {
					YUniqueAttributeValidator validator = ValidationFactory.eINSTANCE.createYUniqueAttributeValidator();
					validator.setValTypeFullyQualifiedName(
							ySuspect.getProperties().get(IPropertyConstants.PROPERTY_CLASS));
					validator.setPropertyPath(ySuspect.getProperties().get(IPropertyConstants.PROPERTY_NAME));
					// this endpoint gains access to the bound bean
					validator.setContainerValueBindingEndpoint(
							EcoreUtil.copy(ySuspect.getContainerValueBindingEndpoint()));
					((YField) yEmbeddable).getValidators().add(validator);
					yEmbeddable.setCssClass(yEmbeddable.getCssClass() + " os-constraint");
				}
			}

			if (ySuspect.getTags().contains(TAG__NUMBER_TO_UOMO)) {
				((YNumericField) yEmbeddable).setConverter(YConverterFactory.eINSTANCE.createYNumericToUomoConverter());
			}

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

			// required step to enable the permissions managed by the visibility
			// processors
			yEmbeddable.setAuthorizationGroup(ySuspect.getAuthorizationGroup());
			yEmbeddable.setAuthorizationId(ySuspect.getAuthorizationId());

		}
		return yEmbeddable;
	}

	/**
	 * Helper method to find out if the suspect properties keys contains a
	 * function normalizer entry
	 * 
	 * @param ySuspect
	 * @return
	 */
	private boolean existFunctionsInProperties(YSuspect ySuspect) {
		LOGGER.trace("{}", "existFuntionInProperties");
		for (FunctionType functionType : functionTypingApi.getTypes()) {
			if (existInProperties(ySuspect, functionType.getName().toLowerCase())) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Creates the icon combo box.
	 *
	 * @param ySuspect
	 *            the y suspect
	 * @return the y embeddable
	 */
	private YEmbeddable createIconComboBox(YSuspect ySuspect) {
		LOGGER.trace("{}", "createIconComboBox");
		YTypedSuspect yTypedSuspect = (YTypedSuspect) ySuspect;
		YIconComboBox yIconCombo = YECviewFactory.eINSTANCE.createYIconComboBox();
		yIconCombo.setType(yTypedSuspect.getType());
		yIconCombo.setTypeQualifiedName(yTypedSuspect.getTypeQualifiedName());
		// AVOID to use the origin properties map into the addAll-Method!!!!!
		// Afterwards the content of ySuspect.getProperties() is EMPTY!!!!
		// Don´t think even to clone the properties EMap. Same result.
		// Preferred way is as follows.
		EMap<String, String> yEmbeddableProps = yIconCombo.getProperties();
		for (Entry<String, String> prop : ySuspect.getProperties()) {
			yEmbeddableProps.put(prop.getKey(), prop.getValue());
		}
		return yIconCombo;
	}

	/**
	 * Creates elements for a dtos subtype.
	 *
	 * @param ySuspect
	 *            the y suspect
	 * @return the y embeddable
	 */
	private YEmbeddable createSubTypeElements(YSubTypeBaseSuspect ySuspect) {
		LOGGER.trace("{}", "createSbTypeElement");
		for (YSuspect temp : ySuspect.getChildren()) {
			YSubTypeSuspect childSuspect = (YSubTypeSuspect) temp;

			YDetailBeanSlot beanSlot = (YDetailBeanSlot) childSuspect.getBeanSlot();
			for (YSuspect suspect : childSuspect.getChildren()) {
				// Create a new suspect info.
				YSuspectInfo suspectInfo = layoutingInfo.createSuspectInfo(suspect);
				// add the suspectInfo as active suspect
				layoutingInfo.getActiveSuspectInfos().add(suspectInfo);

				YEmbeddable yEmbeddable = prepareElementForSuspect(suspectInfo);
				addElement(null, yEmbeddable, suspectInfo, layoutingInfo.getLayout().getNumberColumns());

				// create VP
				// we are using the master beanslot for it. The subtypeSlot will
				// only be invoked, if the type matches the type of the
				// beanslot.
				// but for visible=false we also need a not type-matching dto
				suspectInfo.getVisibilityProcessors()
						.add(createSubTypeVisibilityProcessor(yEmbeddable, childSuspect, beanSlot.getMasterBeanSlot()));
			}
		}

		return null;
	}

	/**
	 * Creates elements for nested types in the dto.
	 *
	 * @param ySuspect
	 *            the y suspect
	 * @return the yEmbeddable
	 */
	private YEmbeddable createNestedBeanElements(YTypedCompoundSuspect ySuspect) {
		LOGGER.trace("{}", "createNestedBeanElements");
		for (YSuspect childSuspect : ySuspect.getChildren()) {
			childSuspect.setGroupName(ySuspect.getLabelI18nKey());
			childSuspect.getTags().add(TAG__GROUP);
			// Create a new suspect info.
			YSuspectInfo suspectInfo = layoutingInfo.createSuspectInfo(childSuspect);
			// add the suspectInfo as active suspect
			layoutingInfo.getActiveSuspectInfos().add(suspectInfo);

			YEmbeddable yEmbeddable = prepareElementForSuspect(suspectInfo);
			addElement(null, yEmbeddable, suspectInfo, layoutingInfo.getLayout().getNumberColumns());
		}

		return null;
	}

	/**
	 * Create a VP which reacts to the type of the value in the beanslot. And
	 * matches it against the type of the child suspect.
	 * 
	 * @param yEmbeddable
	 * 
	 * @param childSuspect
	 * @param beanSlot
	 * 
	 * @return the vp
	 */
	private YSubTypeVisibilityProcessor createSubTypeVisibilityProcessor(YEmbeddable yEmbeddable,
			YSubTypeSuspect childSuspect, YBeanSlot beanSlot) {
		LOGGER.trace("{}", "createSubTypeVisibilityProcessor");
		// create a VP which sets the element visible true/false if the
		// type of the bound dto matches the expected or not
		YSubTypeVisibilityProcessor yVp = YVisibilityFactory.eINSTANCE.createYSubTypeVisibilityProcessor();
		yVp.setType(childSuspect.getType());
		yVp.setTypeQualifiedName(childSuspect.getTypeQualifiedName());
		yVp.setTarget(yEmbeddable);

		// the binding endpoint for the slot
		YBeanSlotValueBindingEndpoint slotEP = beanSlot.createBindingEndpoint("");

		// the binding endpoint for the vp
		YVisibilityProcessorValueBindingEndpoint vbEndpoint = BindingFactory.eINSTANCE
				.createYVisibilityProcessorValueBindingEndpoint();
		vbEndpoint.setProperty("input");

		YValueBinding yBinding = BindingFactory.eINSTANCE.createYValueBinding();
		yBinding.setModelEndpoint(slotEP);
		yBinding.setTargetEndpoint(vbEndpoint);
		yBinding.setModelToTargetStrategy(YBindingUpdateStrategy.UPDATE);
		yBinding.setTargetToModelStrategy(YBindingUpdateStrategy.NEVER);
		yVp.getDataUsed().add(yBinding);

		return yVp;
	}

	/**
	 * Creates the y blob upload component.
	 *
	 * @param ySuspect
	 *            the y suspect
	 * @return the y embeddable
	 */
	// Helper Methods
	private YEmbeddable createYBlobUploadComponent(YSuspect ySuspect) {
		LOGGER.trace("{}", "createYBlobUploadComponent");
		YEmbeddable yEmbeddable = YECviewFactory.eINSTANCE.createYBlobUploadComponent();
		if (existInProperties(ySuspect, IPropertyConstants.PROPERTY_BLOB)) {
			try {
				((YBlobUploadComponent) yEmbeddable).setDisplayResolutionId(
						Integer.parseInt(ySuspect.getProperties().get(IPropertyConstants.PROPERTY_BLOB)));
			} catch (NumberFormatException nfe) {
				// TODO (JCD): ExceptionHandling
				LOGGER.error("blob property is not from type int!");
			}
			if (existInProperties(ySuspect, IPropertyConstants.PROPERTY_BLOB_FIRMLY_LINKED)) {
				((YBlobUploadComponent) yEmbeddable).setFirmlyLinked(true);
			}
			if (existInProperties(ySuspect, IPropertyConstants.PROPERTY_BLOB_UNIQUE_NAMED)) {
				((YBlobUploadComponent) yEmbeddable).setUniqueNameEnabled(true);
			}
		}
		return yEmbeddable;
	}

	/**
	 * Creates a new {@link YRichTextArea} and configures it to use blob
	 * binding. See {@link YRichTextArea#createBlobValueEndpoint()}.
	 * 
	 * @param ySuspect
	 * @return
	 */
	private YEmbeddable createRichTextFieldBlob(YSuspect ySuspect) {
		LOGGER.trace("{}", "createRichTextFieldBlob");
		YRichTextArea yRichText = YECviewFactory.eINSTANCE.createYRichTextArea();
		yRichText.setUseBlob(true);
		return yRichText;
	}

	/**
	 * Creates a new {@link YRichTextArea} and configures it to use blob
	 * binding. See {@link YRichTextArea#createValueEndpoint()}.
	 * 
	 * @param ySuspect
	 * @return
	 */
	private YEmbeddable createRichTextFieldString(YSuspect ySuspect) {
		LOGGER.trace("{}", "createRichTextFieldString");
		YRichTextArea yRichText = YECviewFactory.eINSTANCE.createYRichTextArea();
		yRichText.setUseBlob(false);
		return yRichText;
	}

	/**
	 * Creates a new {@link YMaskedTextField}.
	 * 
	 * @param ySuspect
	 * @return
	 */
	private YEmbeddable createMaskedTextField(YSuspect ySuspect) {
		LOGGER.trace("{}", "createMaskedTextField");
		YMaskedTextField yRichText = YECviewFactory.eINSTANCE.createYMaskedTextField();
		yRichText.setMask(ySuspect.getProperties().get(IPropertyConstants.PROPERTY_MASK));
		return yRichText;
	}

	/**
	 * Creates a new {@link YMaskedDecimalField}.
	 * 
	 * @param ySuspect
	 * @return
	 */
	private YEmbeddable createMaskedDecimalField(YSuspect ySuspect) {
		LOGGER.trace("{}", "createMaskedDecimalField");
		YMaskedDecimalField yRichText = YECviewFactory.eINSTANCE.createYMaskedDecimalField();
		yRichText.setMask(ySuspect.getProperties().get(IPropertyConstants.PROPERTY_MASK));

		return yRichText;
	}

	/**
	 * Creates a new {@link YPasswordField} and configures it to use blob
	 * binding. See {@link YPasswordField#createValueEndpoint()}.
	 * 
	 * @param ySuspect
	 * @return
	 */
	private YEmbeddable createPasswordField(YSuspect ySuspect) {
		LOGGER.trace("{}", "createPasswordField");
		YPasswordField yPasswordField = ExtensionModelFactory.eINSTANCE.createYPasswordField();
		return yPasswordField;
	}

	/**
	 * Creates the save and new button.
	 *
	 * @param ySuspect the y suspect
	 * @return the y embeddable
	 */
	private YEmbeddable createSaveAndNew(YSuspect ySuspect) {
		LOGGER.trace("{}", "createSaveAndNew");
		YButton yButton = ExtensionModelFactory.eINSTANCE.createYButton();
		yButton.setLabel(ySuspect.getLabel());
		yButton.setLabelI18nKey(ySuspect.getLabelI18nKey());
		yButton.setImage(themeResourceService.getThemeResource("dssaveandnew", ThemeResourceType.ICON));
		yButton.getTags().addAll(ySuspect.getTags());
		return yButton;
	}
	
	/**
	 * Creates the y bean reference.
	 *
	 * @param ySuspect
	 *            the y suspect
	 * @return the y embeddable
	 */
	private YEmbeddable createYBeanReference(YSuspect ySuspect) {
		LOGGER.trace("{}", "createYBeanReference");
		YTypedSuspect yTypedSuspect = (YTypedSuspect) ySuspect;
		EMap<String, String> suspectProperties = yTypedSuspect.getProperties();
		YEmbeddable yEmbeddable = null;
		if (isEditable(ySuspect)) {
			if (suspectProperties.containsKey(IPropertyConstants.PROPERTY__ITEM_CAPTION)) {
				yEmbeddable = ExtensionModelFactory.eINSTANCE.createYBeanReferenceField();
				YBeanReferenceField beanReferenceField = (YBeanReferenceField) yEmbeddable;
				beanReferenceField.setType(yTypedSuspect.getType());
				beanReferenceField.setTypeQualifiedName(yTypedSuspect.getTypeQualifiedName());
				beanReferenceField.setCaptionPropertyPath(getCaptionPropertyPath(suspectProperties));

				// create search dialog
				Class<?> type = yTypedSuspect.getType();
				YFilteringComponent yFilterComponent = ExtensionModelFactory.eINSTANCE.createYFilteringComponent();
				String filterDepthString = suspectProperties.get(IPropertyConstants.PROPERTY__FILTER_DEPTH);
				int depth = 0;
				if (filterDepthString != null) {
					depth = Integer.valueOf(filterDepthString);
				}

				ECViewUtil.fill(type, depth, yFilterComponent);

				if (!yFilterComponent.getFilterDescriptors().isEmpty()) {
					beanReferenceField.setFilteringComponent(yFilterComponent);
				}

				if (ySuspect.getTags().contains(TAG__SIDEKICK)) {
					YDialogComponent yDialogComponent = ExtensionModelFactory.eINSTANCE.createYDialogComponent();
					yDialogComponent.setType(type);
					yDialogComponent.setViewContextCallback(new DialogViewContextCallback());
					yDialogComponent.setUpdateCallback(new DtoServiceCallback());
					beanReferenceField.setDialogComponent(yDialogComponent);
				}

				if (ySuspect.getProperties().containsKey("TargetEnumRefClass")) {
					beanReferenceField
							.setReferenceSourceTypeQualifiedName(ySuspect.getProperties().get("TargetEnumRefClass"));
					beanReferenceField
							.setReferenceSourceTypeProperty(ySuspect.getProperties().get("TargetEnumRefField"));
				}

			}

			// Alternative for non editable bean references is a non editable
			// Textfield.
		} else {
			yEmbeddable = ExtensionModelFactory.eINSTANCE.createYTextField();
			for (YBindingEndpoint vEndPoint : yTypedSuspect.getValueBindingEndpoints()) {
				if (vEndPoint instanceof YDetailValueBindingEndpoint) {
					YDetailValueBindingEndpoint detailedVEndpoint = (YDetailValueBindingEndpoint) vEndPoint;
					detailedVEndpoint.setPropertyPath(detailedVEndpoint.getPropertyPath().concat(".")
							.concat(getCaptionPropertyPath(suspectProperties)));
				}
			}
			yTypedSuspect.setId(ySuspect.getId().concat(".").concat(yTypedSuspect.getTypeQualifiedName()).concat(".")
					.concat(getCaptionPropertyPath(suspectProperties)));
			yTypedSuspect.setTypeQualifiedName(String.class.getCanonicalName());
			yTypedSuspect.setType(String.class);
		}
		// TODO: check if yEmbeddable might be set by some other condition.
		// Otherwise it might be null.
		return yEmbeddable;
	}

	/**
	 * Gets the bean slot name.
	 *
	 * @param properties
	 *            the properties
	 * @return the bean slot name
	 */
	protected String getBeanSlotName(Map<String, Object> properties) {
		return (String) properties.get(IViewContext.PROP_SLOT);
	}

	public IViewContext getAutobindedDialogModel(Class<?> dtoType) {
		LOGGER.trace("{}", "getAutobindedDialogModel");
		IViewContext viewContext = null;
		BundleContext bc = FrameworkUtil.getBundle(getClass()).getBundleContext();
		ServiceReference<IECViewProviderService> ref = bc.getServiceReference(IECViewProviderService.class);
		if (ref != null) {
			IECViewProviderService service = bc.getService(ref);
			viewContext = service.getViewContext(dtoType, IViewContext.MAIN_BEAN_SLOT);
			bc.ungetService(ref);
		} else {
			LOGGER.error("{}", "IECViewProviderService not found");
		}
		if (viewContext != null) {
			return viewContext;
		} else {
			LOGGER.error("No view found for dto {}", dtoType.getCanonicalName());
		}
		return null;
	}

	class DialogViewContextCallback implements IDialogViewContextCallback {
		@Override
		public IViewContext getDialogViewContext(Class<?> type) {
			IViewContext dialogViewContext = getAutobindedDialogModel(type);
			if (dialogViewContext != null) {
				dialogViewContext.setLocale(user.getLocale());
				dialogViewContext.setRenderingParams(viewContext.getRenderingParams());
				try {
					Object newDto = type.newInstance();
					dialogViewContext.setBean(getBeanSlotName(dialogViewContext.getRenderingParams()), newDto);
				} catch (InstantiationException | IllegalAccessException e) {
					LOGGER.error("{}", e);
				}
			}
			return dialogViewContext;
		}
	}

	class DtoServiceCallback implements IDtoServiceCallback {
		@Override
		public void persist(IViewContext dialogViewContext) {
			Object dto = dialogViewContext.getBean(getBeanSlotName(dialogViewContext.getRenderingParams()));
			IDTOService<?> dtoService = DtoServiceAccess.getService(dto.getClass());
			if (dtoService != null) {
				dtoService.persist(dto);
			}
		}
	}

	private String getCaptionPropertyPath(EMap<String, String> suspectProperties) {
		String captionPropertyPath = suspectProperties.get(IPropertyConstants.PROPERTY__ITEM_CAPTION);
		if (captionPropertyPath == null || captionPropertyPath.isEmpty()) {
			captionPropertyPath = suspectProperties.get(IPropertyConstants.PROPERTY__ITEM_DESCRIPTION);
		}
		return captionPropertyPath;
	}

	/**
	 * Creates the table.
	 *
	 * @param ySuspect
	 *            the y suspect
	 * @return the y embeddable
	 */
	private YEmbeddable createTable(YSuspect ySuspect) {
		LOGGER.trace("{}", "createTable");
		YEmbeddable yEmbeddable;
		YCollectionSuspect yCollectionSuspect = (YCollectionSuspect) ySuspect;
		yEmbeddable = ExtensionModelFactory.eINSTANCE.createYTable();

		YTable table = (YTable) yEmbeddable;
		table.setType(yCollectionSuspect.getType());
		table.setTypeQualifiedName(yCollectionSuspect.getTypeQualifiedName());
		table.setUseBeanService(false);
		EList<YColumn> columns = table.getColumns();
		for (YColumnInfo columnInfo : yCollectionSuspect.getColumns()) {
			YColumn column = ExtensionModelFactoryImpl.eINSTANCE.createYColumn();
			column.setPropertyPath(columnInfo.getName());
			column.setLabel(columnInfo.getName());
			column.setType(columnInfo.getType());
			column.setTypeQualifiedName(columnInfo.getTypeQualifiedName());
			column.setConverter(getConverter(columnInfo.getProperties()));
			YDatadescription datadescription = DatatypesFactoryImpl.eINSTANCE.createYDatadescription();
			datadescription.setLabelI18nKey(columnInfo.getLabelI18nKey());
			column.setDatadescription(datadescription);
			if (columnInfo.getProperties() != null && !columnInfo.getProperties().isEmpty()) {
				column.getProperties().addAll(columnInfo.getProperties());
			}
			columns.add(column);
		}
		for (YColumn yColumn : table.getColumns()) {
			yColumn.setVisible(true);
		}
		return yEmbeddable;
	}

	/**
	 * Creates the grid.
	 *
	 * @param ySuspect
	 *            the y suspect
	 * @return the y embeddable
	 */
	private YEmbeddable createGrid(YSuspect ySuspect) {
		LOGGER.trace("{}", "createGrid");
		YEmbeddable yEmbeddable;
		YCollectionSuspect yTypedSuspect = (YCollectionSuspect) ySuspect;
		GridFactory gFactory = new GridFactory();
		CxGrid grid = gFactory.createGrid(yTypedSuspect);
		grid = CxGridUtil.setPermissions(userAccessService, grid);
		yEmbeddable = grid;
		return yEmbeddable;
	}

	/**
	 * Creates the enum options.
	 *
	 * @param ySuspect
	 *            the y suspect
	 * @return the y embeddable
	 */
	private YEmbeddable createEnumOptions(YSuspect ySuspect) {
		LOGGER.trace("{}", "createEnumOptions");
		YEmbeddable yEmbeddable;
		yEmbeddable = ExtensionModelFactory.eINSTANCE.createYEnumOptionsGroup();
		YEnumOptionsGroup enumOptionsGroup = (YEnumOptionsGroup) yEmbeddable;
		YTypedSuspect yTypedSuspect = (YTypedSuspect) ySuspect;
		enumOptionsGroup.setType(yTypedSuspect.getType());
		enumOptionsGroup.setTypeQualifiedName(yTypedSuspect.getTypeQualifiedName());
		return yEmbeddable;
	}

	/**
	 * Creates the enum combo boxes.
	 *
	 * @param ySuspect
	 *            the y suspect
	 * @return the y embeddable
	 */
	private YEmbeddable createEnumCombo(YSuspect ySuspect) {
		LOGGER.trace("{}", "createEnumCombo");
		YEmbeddable yEmbeddable;
		yEmbeddable = ExtensionModelFactory.eINSTANCE.createYEnumComboBox();
		YEnumComboBox yEnumCombo = (YEnumComboBox) yEmbeddable;
		YTypedSuspect yTypedSuspect = (YTypedSuspect) ySuspect;
		yEnumCombo.setType(yTypedSuspect.getType());
		yEnumCombo.setTypeQualifiedName(yTypedSuspect.getTypeQualifiedName());
		return yEmbeddable;
	}

	/**
	 * Creates the organization combo box inclosing organization positions.
	 *
	 * @param ySuspect
	 *            the y suspect
	 * @return the y embeddable
	 */
	private YEmbeddable createOrganizationCombo(YSuspect ySuspect) {
		LOGGER.trace("{}", "createOrganizationCombo");
		YEmbeddable yEmbeddable;
		yEmbeddable = ExtensionModelFactory.eINSTANCE.createYComboBox();
		YComboBox yCombo = (YComboBox) yEmbeddable;
		yCombo.setUseBeanService(false);
		YTypedSuspect yTypedSuspect = (YTypedSuspect) ySuspect;
		yCombo.setType(yTypedSuspect.getType());
		yCombo.setTypeQualifiedName(yTypedSuspect.getTypeQualifiedName());
		Collection<String> positionNames = getOrganizationPositionNames(
				ProductConfiguration.getAuthenticationOrganizationId());
		if (positionNames.isEmpty()) {
			yCombo.getCollection().add(IUserAccessService.NAME_ADMINISTRATOR);
			yCombo.setSelection(IUserAccessService.NAME_ADMINISTRATOR);
			yCombo.setEditable(false);
		} else {
			yCombo.getCollection()
					.addAll(getOrganizationPositionNames(ProductConfiguration.getAuthenticationOrganizationId()));
		}
		return yEmbeddable;
	}

	/**
	 * Creates the perspective combo box inclosing perspectives.
	 *
	 * @param ySuspect
	 *            the y suspect
	 * @return the y embeddable
	 */
	private YEmbeddable createPerspectiveCombo(YSuspect ySuspect) {
		LOGGER.trace("{}", "createPerspectiveCombo");
		YEmbeddable yEmbeddable;
		yEmbeddable = YECviewFactory.eINSTANCE.createYPairComboBox();
		YPairComboBox yCombo = (YPairComboBox) yEmbeddable;
		yCombo.setUseBeanService(false);
		yCombo.setType(Pair.class);
		yCombo.setTypeQualifiedName(Pair.class.getCanonicalName());
		yCombo.getCollection().addAll(getPerspectiveNames());
		yCombo.setCaptionProperty("first");
		return yEmbeddable;
	}

	/**
	 * Creates the theme combo box inclosing themes.
	 *
	 * @param ySuspect
	 *            the y suspect
	 * @return the y embeddable
	 */
	private YEmbeddable createThemeCombo(YSuspect ySuspect) {
		LOGGER.trace("{}", "createThemeCombo");
		YEmbeddable yEmbeddable;
		yEmbeddable = ExtensionModelFactory.eINSTANCE.createYComboBox();
		YComboBox yCombo = (YComboBox) yEmbeddable;
		yCombo.setUseBeanService(false);
		yCombo.setCaptionProperty("label");
		yCombo.setType(VaaclipseUiTheme.class);
		yCombo.setTypeQualifiedName(VaaclipseUiTheme.class.getCanonicalName());
		yCombo.setModelSelectionType(String.class);
		yCombo.setModelSelectionTypeQualifiedName(String.class.getCanonicalName());
		yCombo.getCollection().addAll(getThemes());
		YConverter conv = YConverterFactory.eINSTANCE.createYVaaclipseUiThemeToStringConverter();
		yCombo.setConverter(conv);
		return yEmbeddable;
	}

	/**
	 * Creates the print service combo box inclosing print services.
	 *
	 * @param ySuspect
	 *            the y suspect
	 * @return the y embeddable
	 */
	private YEmbeddable createPrintServiceCombo(YSuspect ySuspect) {
		LOGGER.trace("{}", "createPrintServiceCombo");
		YEmbeddable yEmbeddable;
		yEmbeddable = ExtensionModelFactory.eINSTANCE.createYComboBox();
		YComboBox yCombo = (YComboBox) yEmbeddable;
		yCombo.setUseBeanService(false);
		yCombo.setType(String.class);
		yCombo.setTypeQualifiedName(String.class.getCanonicalName());
		yCombo.setModelSelectionType(String.class);
		yCombo.setModelSelectionTypeQualifiedName(String.class.getCanonicalName());
		yCombo.getCollection().addAll(PdfPrintService.reLookupPrintServiceNames());
		return yEmbeddable;
	}

	/**
	 * Creates the print service combo box inclosing DSL grammar model parts.
	 *
	 * @param ySuspect
	 *            the y suspect
	 * @return the y embeddable
	 */
	private YEmbeddable createModelCombo(YSuspect ySuspect) {
		LOGGER.trace("{}", "createModelCombo");
		YEmbeddable yEmbeddable;
		yEmbeddable = ExtensionModelFactory.eINSTANCE.createYComboBox();
		YComboBox yCombo = (YComboBox) yEmbeddable;
		yCombo.setUseBeanService(false);
		yCombo.setType(String.class);
		yCombo.setTypeQualifiedName(String.class.getCanonicalName());
		yCombo.setModelSelectionType(String.class);
		yCombo.setModelSelectionTypeQualifiedName(String.class.getCanonicalName());
		if (existInProperties(ySuspect, IPropertyConstants.PROPERTY_MODEL)) {
			IPropertyConstants.DSLModelsEnum modelEnum = IPropertyConstants.DSLModelsEnum
					.valueOf(ySuspect.getProperties().get(IPropertyConstants.PROPERTY_MODEL));
			EPackage ePackage = EPackage.Registry.INSTANCE.getEPackage(modelEnum.getNsUri());
			for (EClassifier classifier : ePackage.getEClassifiers()) {
				if (classifier.getName().equalsIgnoreCase(modelEnum.getKey())) {
					for (EObject eObject : dslMetadataService.getAll((EClass) classifier)) {
						yCombo.getCollection().add(eObject);
					}
				}
			}
		}
		return yEmbeddable;
	}

	/**
	 * Creates the i18n combo box inclosing the available languages.
	 *
	 * @param ySuspect
	 *            the y suspect
	 * @return the y embeddable
	 */
	private YEmbeddable createI18nCombo(YSuspect ySuspect) {
		LOGGER.trace("{}", "createI18nCombo");
		YEmbeddable yEmbeddable;
		yEmbeddable = YECviewFactory.eINSTANCE.createYI18nComboBox();
		YI18nComboBox yCombo = (YI18nComboBox) yEmbeddable;
		yCombo.setType(String.class);
		yCombo.setTypeQualifiedName(String.class.getCanonicalName());
		return yEmbeddable;
	}

	private Collection<String> getOrganizationPositionNames(String organizationName) {
		LOGGER.trace("{}", "getOrganizationPositionNames");
		Collection<String> positionNames = new TreeSet<>();
		for(IOrganizationService organizationService:ServiceListener.getOrganizationServices().values()) {
			AbstractSubOrganization organization = organizationService.getOrganization(organizationName);
			if (organization != null) {
				for (IPosition position : organization.getPositions()) {
					positionNames.add(position.getLinkAlias());
				}
			}
		}
		return positionNames;
	}

	@SuppressWarnings("rawtypes")
	private Collection<Pair> getPerspectiveNames() {
		return dslMetadataService.getDslGrammarElementNames(IDSLMetadataService.DSLLiterals.PERSPECTIVES);
	}

	private Set<VaaclipseUiTheme> getThemes() {
		return VaaclipseUiTheme.values(ThemeList.forProduct);
	}

	/**
	 * Sets the custom decimal converter.
	 *
	 * @param yEmbeddable
	 *            the y embeddable
	 * @param ySuspect
	 *            the y suspect
	 */
	private void setCustomDecimalConverter(YEmbeddable yEmbeddable, YSuspect ySuspect) {
		LOGGER.trace("{}", "setCustomDecimalConverter");
		if (existFunctionsInProperties(ySuspect)) {
			YCustomDecimalConverter converter = YConverterFactory.eINSTANCE.createYCustomDecimalConverter();
			converter.getProperties().addAll(ySuspect.getProperties());
			((YCustomDecimalField) yEmbeddable).setConverter(converter);
		}
	}

	/**
	 * Checks if is tab sheet needed.
	 *
	 * @param suspects
	 *            the suspects
	 * @return true, if is tab sheet needed
	 */
	private boolean isTabSheetNeeded(EList<YSuspect> suspects) {
		for (YSuspect suspect : suspects) {
			if (suspect.getTags().contains(TAG__TABLE) || suspect.getTags().contains(TAG__GRID)) {
				return true;
			}
			if (suspect instanceof YTypedCompoundSuspect && suspect.getTags().contains(TAG__BEANONTAB)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Checks for existing suspect property
	 */
	private boolean existInProperties(YElement ySuspect, String propConstant) {
		if (!ySuspect.getProperties().isEmpty()) {
			String propertyValue = ySuspect.getProperties().get(propConstant);
			if (propertyValue != null) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Gets the converter.
	 *
	 * @param properties
	 *            the properties
	 * @return the converter
	 */
	public static YConverter getConverter(EMap<String, String> properties) {
		LOGGER.trace("{}", "getConverter");
		String decimalformatPropertyValue = properties.get(IPropertyConstants.PROPERTY_DECIMALFORMAT);
		if (decimalformatPropertyValue != null) {
			YSimpleDecimalConverter yConverter = YConverterFactory.eINSTANCE.createYSimpleDecimalConverter();
			yConverter.setNumberFormatPattern(decimalformatPropertyValue);
			return yConverter;
		} else {
			return null;
		}

	}

	/**
	 * Helper class to determine if the component is editable due to the
	 * existing user permissions
	 */
	private boolean isEditable(YSuspect ySuspect) {
		LOGGER.trace("{}", "isEditable");
		String dtoName = ySuspect.getAuthorizationGroup();
		String dtoProperty = ySuspect.getAuthorizationId();

		if(ySuspect.getTags().contains(TAG__READONLY)) {
			return false;
		}
		Boolean result = false;
		String grantKey = dtoName + "." + dtoProperty + "###EDITABLE";
		if (isSuspectEditable.containsKey(grantKey)) {
			result = isSuspectEditable.get(grantKey);
		} else {
			if (userAccessService.isGranted(Group.DTO, Action.READABLE, dtoName)) {
				boolean invisible = userAccessService.isVetoed(Group.DTO, Action.INVISIBLE, dtoName, dtoProperty);
				boolean enabled = false;
				boolean editable = false;
				if (!invisible) {
					enabled = !userAccessService.isVetoed(Group.DTO, Action.DISABLED, dtoName, dtoProperty);
					if (enabled) {
						editable = !userAccessService.isVetoed(Group.DTO, Action.NONEDITABLE, dtoName, dtoProperty);
					}
				}
				result = !invisible && enabled && editable;
			}
			isSuspectEditable.put(grantKey, result);
		}
		return result;
	}

	/**
	 * Helper Comparator to allow to sort a list of suspects due to their table
	 * or grid property value. Sort criteria is that the highest value became
	 * the first of the list followed by the suspects with decreasing value. In
	 * case of same values the order between the compared suspects will be
	 * maintained and in case of no value the suspect gets the value 0 and
	 * became the last elements of the list.
	 * 
	 * @author Jose C. Dominguez
	 *
	 */
	class SuspectComparator implements Comparator<YSuspect> {

		/*
		 * (non-Javadoc)
		 * 
		 * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
		 */
		@Override
		public int compare(YSuspect suspect1, YSuspect suspect2) {
			if (suspect1 == null && suspect2 == null) {
				return 0;
			} else if (suspect1 == null) { // && suspect2 != null
				return (-1);
			} else if (suspect2 == null) { // suspect1 != null &&
				return 1;
			} else { // this means: (suspect1 != null && suspect2 != null)
				boolean lessThan = getValue(suspect1).compareTo(getValue(suspect2)) < 0;
				if (lessThan) {
					return 1;
				} else {
					boolean greaterThan = getValue(suspect1).compareTo(getValue(suspect2)) > 0;
					if (greaterThan) {
						return (-1);
					} else {
						return 0;
					}
				}
			}
		}

		/**
		 * Gets the value.
		 *
		 * @param suspect
		 *            the suspect
		 * @return the value
		 */
		private Integer getValue(YSuspect suspect) {
			try {
				String value = suspect.getProperties().get(IPropertyConstants.PROPERTY_TABLE);
				if (value == null) {
					value = suspect.getProperties().get(IPropertyConstants.PROPERTY_GRID);
				}
				return Integer.valueOf(value);
			} catch (NumberFormatException nfe) {
				return 0;
			}
		}

	}

	static class GroupInfo {
		String name;
		YFormLayout group;

		public GroupInfo(String name, YFormLayout group) {
			super();
			this.name = name;
			this.group = group;
		}

	}

}
