/**
 *                                                                            
 *  Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany) 
 *                                                                            
 *  All rights reserved. This program and the accompanying materials           
 *  are made available under the terms of the Eclipse Public License v1.0       
 *  which accompanies this distribution, and is available at                  
 *  http://www.eclipse.org/legal/epl-v10.html                                 
 *                                                                            
 *  Contributors:                                                      
 * 	   Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
 * 
 * 
 *  This copyright notice shows up in the generated Java code
 * 
 */
package org.eclipse.osbp.autowirehelper

import com.google.inject.Inject
import com.google.inject.Injector
import java.util.Collection
import java.util.LinkedList
import java.util.List
import java.util.Map
import java.util.Set
import java.util.Stack
import javax.validation.Valid
import org.eclipse.emf.common.util.URI
import org.eclipse.emf.ecore.EObject
import org.eclipse.emf.ecore.InternalEObject
import org.eclipse.emf.ecore.resource.Resource
import org.eclipse.emf.ecore.resource.ResourceSet
import org.eclipse.emf.ecore.util.EcoreUtil
import org.eclipse.osbp.autowirehelper.utils.AutowireUtil
import org.eclipse.osbp.dsl.common.datatypes.IDto
import org.eclipse.osbp.ecview.core.common.model.binding.BindingFactory
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.YECViewModelListBindingEndpoint
import org.eclipse.osbp.ecview.core.common.model.binding.YListBindingEndpoint
import org.eclipse.osbp.ecview.core.common.model.binding.YValueBindingEndpoint
import org.eclipse.osbp.ecview.core.common.model.core.YAlignment
import org.eclipse.osbp.ecview.core.common.model.core.YAlignmentContainer
import org.eclipse.osbp.ecview.core.common.model.core.YAuthorizationable
import org.eclipse.osbp.ecview.core.common.model.core.YBeanSlot
import org.eclipse.osbp.ecview.core.common.model.core.YBeanSlotListBindingEndpoint
import org.eclipse.osbp.ecview.core.common.model.core.YDetailBeanSlot
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddable
import org.eclipse.osbp.ecview.core.common.model.core.YLayout
import org.eclipse.osbp.ecview.core.common.model.core.YView
import org.eclipse.osbp.ecview.core.^extension.model.^extension.util.SimpleExtensionModelFactory
import org.eclipse.osbp.ecview.dsl.autowire.IAutowireDelegate
import org.eclipse.osbp.ecview.dsl.derivedstate.UiModelDerivedStateComputerx
import org.eclipse.osbp.ecview.dsl.extensions.BeanHelper
import org.eclipse.osbp.ecview.dsl.extensions.BindableTypeResolver
import org.eclipse.osbp.ecview.dsl.extensions.BindingInfoHelper
import org.eclipse.osbp.ecview.dsl.extensions.BindingInfoHelper.BindingInfo
import org.eclipse.osbp.ecview.dsl.extensions.OperationExtensions
import org.eclipse.osbp.ecview.dsl.extensions.OperationExtensions.OperationInfo
import org.eclipse.osbp.ecview.dsl.extensions.SuperTypeCollector
import org.eclipse.osbp.ecview.dsl.extensions.TypeHelper
import org.eclipse.osbp.ecview.^extension.api.ILayoutingStrategy
import org.eclipse.osbp.ecview.^extension.model.YColumnInfo
import org.eclipse.osbp.ecview.^extension.model.YECviewFactory
import org.eclipse.osbp.ecview.^extension.model.YStrategyLayout
import org.eclipse.osbp.ecview.^extension.model.YSubTypeSuspect
import org.eclipse.osbp.ecview.^extension.model.YSuspect
import org.eclipse.osbp.ecview.^extension.model.YTypedCompoundSuspect
import org.eclipse.osbp.ecview.^extension.model.YTypedSuspect
import org.eclipse.osbp.ecview.^extension.model.visibility.YVisibilityFactory
import org.eclipse.osbp.ecview.semantic.uimodel.UiBeanSlot
import org.eclipse.osbp.ecview.semantic.uimodel.UiBindingEndpointAssignment
import org.eclipse.osbp.ecview.semantic.uimodel.UiEmbeddable
import org.eclipse.osbp.ecview.semantic.uimodel.UiHorizontalLayout
import org.eclipse.osbp.ecview.semantic.uimodel.UiLayout
import org.eclipse.osbp.mobile.vaadin.ecview.model.VMVerticalComponentGroup
import org.eclipse.osbp.mobile.vaadin.ecview.model.VaadinMobileFactory
import org.eclipse.osbp.runtime.common.annotations.DomainDescription
import org.eclipse.osbp.runtime.common.annotations.DomainKey
import org.eclipse.osbp.runtime.common.annotations.FilterDepth
import org.eclipse.osbp.runtime.common.annotations.UniqueEntry
import org.eclipse.osbp.runtime.common.metric.TimeLogger
import org.eclipse.osbp.utils.functionnormalizer.api.FunctionTypingAPI
import org.eclipse.xtext.common.types.JvmDeclaredType
import org.eclipse.xtext.common.types.JvmGenericType
import org.eclipse.xtext.common.types.JvmParameterizedTypeReference
import org.eclipse.xtext.common.types.JvmPrimitiveType
import org.eclipse.xtext.common.types.JvmType
import org.eclipse.xtext.common.types.JvmTypeReference
import org.eclipse.xtext.common.types.TypesFactory
import org.eclipse.xtext.common.types.TypesPackage
import org.eclipse.xtext.naming.IQualifiedNameProvider
import org.eclipse.xtext.resource.IReferenceDescription
import org.eclipse.xtext.ui.editor.findrefs.IReferenceFinder
import org.eclipse.xtext.util.IAcceptor
import org.eclipse.xtext.util.concurrent.IUnitOfWork
import org.eclipse.osbp.runtime.common.annotations.OnKanbanCard

@SuppressWarnings("restriction")
class AutowireHelper implements IAutowireDelegate {

	@Inject extension TypeHelper
	@Inject extension AutowireUtil
	@Inject extension IQualifiedNameProvider
	@Inject BindingInfoHelper bindingInfoHelper;
	@Inject
	private IReferenceFinder referenceFinder;
	@Inject
	private Injector injector

	private VaadinMobileFactory vFactory = VaadinMobileFactory.eINSTANCE

	UiModelDerivedStateComputerx computer
	boolean mobile

	YLayout yLayout
	UiLayout uiLayout

	Layouter layouter

	JvmDeclaredType beanType

	final SimpleExtensionModelFactory factory = new SimpleExtensionModelFactory

	YView yView

	YBeanSlot yMainBeanslot

	override autowire(UiLayout uiLayout, UiModelDerivedStateComputerx computer, boolean mobile) {
		if (!uiLayout.autowire) {
			return
		}

		val logger = TimeLogger.start(typeof(AutowireHelper))

		this.computer = computer;
		this.mobile = mobile;

		this.uiLayout = uiLayout;
		this.yLayout = computer.associatedUi(uiLayout)
		this.yView = yLayout.view
		this.yMainBeanslot = getBeanSlot(uiLayout)
		switch (uiLayout) {
			UiHorizontalLayout: {
				layouter = if(!mobile) new StrategyLayoutLayouter else new MobileLayouter
				layouter.setup(uiLayout, yLayout)
			}
			default:
				return
		}

		// val userAccessService = UserServiceBinder.getUserAccessService
		// val userName = userAccessService.user.userName
		// val permissionList = userAccessService.findPermissionsForUser(userName)
		// for (permission : permissionList.permissions){
		// println(permission)
		// }
		val BindableTypeResolver resolver = new BindableTypeResolver
		var resolvedType = resolver.resolveType(uiLayout.autoWireSource)
		if (resolvedType instanceof JvmDeclaredType) {
			beanType = resolvedType as JvmDeclaredType

			// Gets the operation infos for the given type in form of a map
			val opInfoMap = OperationExtensions.getOperationInfos(beanType)

			// operation info map sorted in a list
			val sortedOpInfoMapList = createSortedMapList(opInfoMap)

			// creates the a suspect structure based on the operation infos
			sortedOpInfoMapList.createSuspectStructure(beanType, mobile, null)

		}

	}

	/**
	 * Finds all sub types of the beanType
	 */
	def findSubTypes(JvmType dtoType, Resource resource) {
		val Set<URI> result = newHashSet()
		val Set<URI> jvmTypeURIs = newHashSet()
		jvmTypeURIs += EcoreUtil.getURI(dtoType)
		val IAcceptor<IReferenceDescription> acceptor = [
			val IReferenceDescription desc = it
			if (desc.EReference === TypesPackage.Literals.JVM_PARAMETERIZED_TYPE_REFERENCE__TYPE) {
				if (sourceEObjectUri.fragment.endsWith("/@superTypes.0")) {
					val URI uri = desc.sourceEObjectUri;
					result += URI.createURI(uri.toString.replace("/@superTypes.0", ""))
				}
			}
		]
		referenceFinder.findAllReferences(jvmTypeURIs, new LocalResourceAccess(resource.resourceSet), acceptor, null)
		result
	}

	def YBeanSlot getBeanSlot(UiLayout uiLayout) {
		var autoWireSourceTemp = uiLayout.autoWireSource
		if (autoWireSourceTemp instanceof UiBindingEndpointAssignment) {
			var alias = (autoWireSourceTemp as UiBindingEndpointAssignment).typedBindableAlias
			if (alias instanceof UiBeanSlot) {
				return computer.associatedUi(alias as UiBeanSlot)
			}
		}
		return null
	}

	def createSuspectStructure(JvmDeclaredType type, boolean mobile, YTypedCompoundSuspect parentSuspect) {

		// Gets the operation infos for the given type in form of a map
		val opInfoMap = OperationExtensions.getOperationInfos(type)

		// operation info map sorted in a list
		val sortedOpInfoMapList = createSortedMapList(opInfoMap)

		sortedOpInfoMapList.createSuspectStructure(type, mobile, parentSuspect)
	}

	def createSuspectStructure(LinkedList<Map<String, OperationInfo>> sortedOpInfoMapList, JvmDeclaredType dtoType,
		boolean mobile, YTypedCompoundSuspect parentSuspect) {
		if (!dtoType.isEnum) {
			sortedOpInfoMapList.forEach [
				it.createSuspectStructure(dtoType, mobile, parentSuspect)
			]
		}

		// lets create a new suspect in form of a tree to add the sub types to it
		val subTypeURIs = findSubTypes(dtoType, uiLayout.eResource)
		if (!subTypeURIs.empty) {
			val subtypeRootSuspect = YECviewFactory.eINSTANCE.createYSubTypeBaseSuspect
			subtypeRootSuspect.tags += ILayoutingStrategy.TAG__SUBTYPES_ROOT

			// TODO load the class
			subtypeRootSuspect.typeQualifiedName = dtoType.qualifiedName
			layouter.add(subtypeRootSuspect)
			layouter.pushHierarchy(subtypeRootSuspect)
		}
		subTypeURIs.forEach [
			val JvmDeclaredType subDtoJvmType = uiLayout.eResource.resourceSet.getEObject(it, true) as JvmDeclaredType
			subDtoJvmType.createSubTypeDtoSuspect()
		]
		if (!subTypeURIs.empty) {
			layouter.popHierarchy
		}
	}

	def createSuspectStructure(Map<String, OperationInfo> opInfoMap, JvmDeclaredType dtoType, boolean mobile,
		YTypedCompoundSuspect parentSuspect) {

		opInfoMap.values.forEach [
			var JvmType type = null
			try {
				type = getter.returnType.type
			} catch (NullPointerException e) {
				return
			}
			var YSuspect suspect
			var properties = newArrayList()
			if (it.field !== null) {
				properties.addAll(dtoType.toProperties(it.field.declaringType.qualifiedName + "." + it.name))
			}
			if (type.boolean && !it.isDirtyMark) {
				if(mobile) type.createMobileSwitch(it) else suspect = type.createCheckbox(it)
			} else if (type.numberWithDigits) {
				suspect = type.createDecimalField(it)
				if (dtoType.isAttribute(it.name, "NumberToUomo")) {
					suspect.tags += "NumberToUomo"
				} else {
					var dataType = dtoType.toDataType(it.name)
					if (dataType !== null) {
						var dataTypeName = dataType.jvmTypeReference.type.identifier
						if (dataTypeName.equals(Double.canonicalName)) {
							suspect = type.createCustomDecimalField(it)
						}
					}
				}
			} else if (type.numberWithoutDigits) {

				if (!it.idOrUUID && !it.version && !it.dirtyMark) {
					suspect = type.createNumberField(it)
				}
			} else if (type.string) {
				val fieldType = properties.findFirst[it.key.equals(ILayoutingStrategy.PROPERTY_KEY__FIELD_TYPE)]?.value

				if (!it.idOrUUID && !it.version && !it.dirtyMark) {
					var functionTypingAPI = new FunctionTypingAPI()
					val functionImagePicker = functionTypingAPI.functionImagePickerTypeName
					if (it.isDomainKey || it.isDomainDescription ||
						(!fieldType.nullOrEmpty && fieldType.equals(ILayoutingStrategy.PROPERTY_SUGGESTTEXT))) {
						suspect = type.createSuggestTextField(it, opInfoMap)
					} else if (properties.exists[key.toLowerCase.equals(ILayoutingStrategy.PROPERTY_BLOB)]) {
						suspect = type.createBlopUploadComponent(it)
					} else if (!fieldType.nullOrEmpty && fieldType.equals(ILayoutingStrategy.PROPERTY_RICH_TEXT)) {
						suspect = type.createRichTextField(it)
					} else if (!fieldType.nullOrEmpty && fieldType.equals(ILayoutingStrategy.PROPERTY_MASKED_TEXT)) {
						val mask = properties.findFirst[it.key.equals(ILayoutingStrategy.PROPERTY_MASK)]?.value
						suspect = type.createMaskedTextField(it, mask)
					} else if (!fieldType.nullOrEmpty && fieldType.equals(ILayoutingStrategy.PROPERTY_PASSWORD)) {
						suspect = type.createPasswordField(it)
					} else if (properties.exists[key.equalsIgnoreCase(ILayoutingStrategy.PROPERTY_TEXTAREA)]) {
						suspect = type.createTextAreaField(it)
					} else if (properties.exists[key.equalsIgnoreCase(ILayoutingStrategy.PROPERTY_ORGANIZATION)]) {
						suspect = type.createOrganizationComboBox(it)
					} else if (properties.exists[key.equalsIgnoreCase(ILayoutingStrategy.PROPERTY_PERSPECTIVE)]) {
						suspect = type.createPerspectiveComboBox(it)
					} else if (properties.exists[key.equalsIgnoreCase(ILayoutingStrategy.PROPERTY_PRINTSERVICE)]) {
						suspect = type.createPrintServiceComboBox(it)
					} else if (properties.exists[key.equalsIgnoreCase(ILayoutingStrategy.PROPERTY_THEME)]) {
						suspect = type.createThemeComboBox(it)
					} else if (properties.exists[key.equalsIgnoreCase(functionImagePicker)]) {
						suspect = type.createIconComboBox(it)
					} else {
						suspect = type.createTextField(it)
					}
				}
			} else if (type.date) {
				suspect = type.createDateField(it)
			} else if (type.enum) {
				if (properties.exists[key.toLowerCase.equals(ILayoutingStrategy.PROPERTY_OPTION_GROUP)]) {
					suspect = type.createEnumOptionsGroup(it)
				} else {
					suspect = type.createEnumComboBox(it)
				}
			} else if (type.byteArray) {
				val fieldType = properties.findFirst[it.key.equals(ILayoutingStrategy.PROPERTY_KEY__FIELD_TYPE)]?.value
				if (!fieldType.nullOrEmpty && fieldType.equals(ILayoutingStrategy.PROPERTY_RICH_TEXT)) {
					suspect = type.createRichTextField(it)
				} else {
					suspect = type.createBlopUploadComponent(it)
				}
			} else if (it.domainReference) {
				suspect = type.createBeanReferenceField(it)
			} else if (it.field !== null && it.field.collection) {
				if (properties.exists[key.toLowerCase.equals(ILayoutingStrategy.PROPERTY_GRID)]) {
					suspect = type.createGrid(it)
				} else if (properties.exists[key.equalsIgnoreCase(ILayoutingStrategy.PROPERTY_TABLE)]) {
					suspect = type.createTableField(it)
				}
			} else if (type.dto) {
				suspect = type.createDtoSuspect(it)
			}
			if (parentSuspect === null) {
				type.completeSuspect(it, suspect, dtoType)
			} else {
				type.completeSuspect(it, suspect, parentSuspect, dtoType)
			}
			for (keyAndValue : properties) {
				if(suspect !== null) suspect.properties.put(keyAndValue.key.toLowerCase, keyAndValue.value)
			}
		]
	}

	def createAuthorizationVisibilityProcessor(YAuthorizationable element, OperationInfo info) {
		if (info.field !== null) {
			val type = info.field.eContainer as JvmGenericType
			if (!info.getter.returnType.type.isClass && info.getter.returnType.type.isAllowed(type, info)) {
				element.authorizationGroup = type.fullyQualifiedName.toString
				element.authorizationId = info.field.simpleName
			}
		}
	}

	def YSuspect createDtoSuspect(JvmType type, OperationInfo info) {
		val dtoSuspect = YECviewFactory.eINSTANCE.createYTypedCompoundSuspect
		dtoSuspect.tags += ILayoutingStrategy.TAG__DTO
		if (type instanceof JvmDeclaredType) {
			type.createSuspectStructure(false, dtoSuspect)
		}

		return dtoSuspect
	}

	/**
	 * A suspect that is created for each sub type of beanType.<br>
	 * 1) we create a compound suspect<br>
	 * 2) we add the compound suspect to the layout<br>
	 * 3) we create a typed suspect for each operation info<br>
	 * 4) we add the new typed suspect to the compound suspect and create a tree<br>
	 */
	def YSuspect createSubTypeDtoSuspect(JvmDeclaredType subDtoJvmType) {
		val subTypeSuspect = YECviewFactory.eINSTANCE.createYSubTypeSuspect
		subTypeSuspect.tags += ILayoutingStrategy.TAG__SUBTYPE
		subTypeSuspect.typeQualifiedName = subDtoJvmType.qualifiedName
		subTypeSuspect.type = computer.loadClass(uiLayout.eResource.resourceSet, subTypeSuspect.typeQualifiedName)

		// create a new beanslot with the subtype. The main slot will become bound to this slot
		val YView view = computer.currentView
		val YDetailBeanSlot detailSlot = view.addDetailBeanSlot(subTypeSuspect.typeQualifiedName, subTypeSuspect.type,
			yMainBeanslot, "");
		detailSlot.tags += ILayoutingStrategy.TAG__SUBTYPE

		// assign the detail bean slot to the sub type suspect for bindings later
		subTypeSuspect.beanSlot = detailSlot

		// add the new suspect to the layout
		layouter.add(subTypeSuspect)

		// create a new child node in the suspect hierarchy
		layouter.pushHierarchy(subTypeSuspect)

		// create a hierarchy for the sub dto suspects
		// Gets the operation infos for the given type in form of a map and converts the
		// operation info map into a sorted list
		val subTypeInfos = createSortedMapList(OperationExtensions.getOperationInfos(subDtoJvmType, false))

		subTypeInfos.createSuspectStructure(subDtoJvmType, mobile, subTypeSuspect)

		// pop the latest subDtoSuspect
		layouter.popHierarchy

		return subTypeSuspect
	}

	/**
	 * Returns true, if the type is a dto.
	 */
	def boolean isDto(JvmType type) {
		val collector = new SuperTypeCollector()
		val superTypes = collector.collectSuperTypeNames(type)

		// if any of the supertype names equals org.eclipse.osbp.dsl.common.datatypes.IDto
		return superTypes.contains(typeof(IDto).name)
	}

	def completeSuspect(JvmType type, OperationInfo info, YSuspect suspect, JvmType parentType) {
		if (suspect !== null) {
			suspect.id = '''«uiLayout.generateId».«info.name»'''

			if (info.readonly) {
				suspect.tags += "readonly"
			}

			if(info.isOnKanbanCard) {
				suspect.tags += "onKanbanCard"
			}

			if (info.isUniqueEntry) {
				suspect.tags += "unique"
				var splittedId = info.id.split(":")
				if (splittedId.length > 1) {
					var fqClassName = splittedId.get(0)
					suspect.properties.put("class", fqClassName)
				}
				suspect.properties.put("name", info.name)

				// register the container of the binding to the suspect. Otherwise we can not check for the uniqueness
				suspect.createModelValueContainerBinding(info.name, type, "value")
			}

			if (isValidationConstraint(info)) {
				suspect.tags += "constraint"
				var splittedId = info.id.split(":")
				if (splittedId.length > 1) {
					var fqClassName = splittedId.get(0)
					suspect.properties.put("class", fqClassName)
				}
				suspect.properties.put("name", info.name)
			}

			layouter.add(suspect)
			if (info.field !== null && info.field.collection) {
				suspect.createModelListBinding(info, type, "list");
			} else {
				suspect.createModelValueBinding(info.name, type, "value", parentType);
			}

			// fix the masterDetailBinding endpoint of the child suspects
			if (suspect instanceof YTypedCompoundSuspect) {
				val masterValueEP = suspect.valueBindingEndpoints.get(0)
				if (!suspect.valueBindingEndpoints.isEmpty) {
					for (child : suspect.children) {
						child.id = suspect.id + child.id
						if (!child.valueBindingEndpoints.isEmpty) {
							val childValueEP = child.valueBindingEndpoints.get(0)
							if (childValueEP instanceof YDetailValueBindingEndpoint) {
								childValueEP.masterObservable = EcoreUtil.copy(masterValueEP) as YValueBindingEndpoint
							}
						}
					}
				}

			}

			// create the authorization infos
			suspect.createAuthorizationVisibilityProcessor(info)
		}
	}

	def completeSuspect(JvmType type, OperationInfo info, YSuspect suspect, YTypedCompoundSuspect parentSuspect, JvmType parentType) {
		if (suspect !== null) {
			suspect.id = '''«parentSuspect.id».«info.name»'''

			if (info.readonly) {
				suspect.tags += "readonly"
			}

			if (isValidationConstraint(info)) {
				suspect.tags += "constraint"
				var splittedId = info.id.split(":")
				if (splittedId.length > 1) {
					var fqClassName = splittedId.get(0)
					suspect.properties.put("class", fqClassName)
				}
				suspect.properties.put("name", info.name)
			}

			parentSuspect.children.add(suspect)
			if (info.field !== null && info.field.collection) {
				suspect.createModelListBinding(info, type, "list");
			} else {
				suspect.createModelValueBinding(info.name, type, "value", parentType);
			}

			// create the authorization infos
			suspect.createAuthorizationVisibilityProcessor(info)
		}
	}

	/**
	 * Sorted the attributes with the primitive types first and the rest after. Also all collections were left out. 
	 */
	def createSortedOpInfoMapForCollections(Map<String, OperationInfo> opInfoMap) {
		val sortedOpInfoList = <String, OperationInfo>newLinkedHashMap()
		val nonPrimitiveOpInfoMap = <String, OperationInfo>newLinkedHashMap()
		opInfoMap.forEach [ key, opInfo |
			var JvmType detailType
			// do not create a column if field is a collection
			if (opInfo.field !== null && !opInfo.field.collection) {
				detailType = opInfo.getter.returnType.type

				val isPrimitive = detailType instanceof JvmPrimitiveType || detailType.getQualifiedName().equals(
					typeof(String).getName());

				if (isPrimitive) {
					sortedOpInfoList.put(key, opInfo)
				} else {
					nonPrimitiveOpInfoMap.put(key, opInfo)
				}
			}
		]
		sortedOpInfoList.putAll(nonPrimitiveOpInfoMap)
		sortedOpInfoList
	}

	/**
	 * Sorted the attributes in a individual but fix order. 
	 */
	def createSortedMapList(Map<String, OperationInfo> opInfoMap) {
		val sortedOpInfoList = <Map<String, OperationInfo>>newLinkedList()

		// At this moment the order of the following method is not desired. See #203.
		// +++++ Due to the not existing sorting the following lines of code are replaced by ...
		/*
		 * val domainKeyOpInfoMap = <String, OperationInfo>newHashMap()
		 * val constraintsOpInfoMap = <String, OperationInfo>newHashMap()
		 * val indexOpInfoMap = <String, OperationInfo>newHashMap()
		 * val stringOpInfoMap = <String, OperationInfo>newHashMap()
		 * val restOpInfoMap = <String, OperationInfo>newHashMap()

		 * // extract String-OperationInfos into a new Map to display later and display all string attributes first.
		 * opInfoMap.forEach [ key, opInfo |
		 * 	val type = opInfo.getter.returnType.type
		 * 	if (opInfo !== null && isDomainKey(opInfo)) {
		 * 		domainKeyOpInfoMap.put(key, opInfo)
		 * 	} else if (opInfo !== null && isIndex(opInfo)) {
		 * 		indexOpInfoMap.put(key, opInfo)
		 * 	} else if (type.string) {
		 * 		stringOpInfoMap.put(key, opInfo)
		 * 	} else {
		 * 		restOpInfoMap.put(key, opInfo)
		 * 	}
		 * ]
		 * sortedOpInfoList.add(domainKeyOpInfoMap)
		 * sortedOpInfoList.add(indexOpInfoMap)
		 * sortedOpInfoList.add(stringOpInfoMap)
		 * sortedOpInfoList.add(constraintsOpInfoMap)
		 * sortedOpInfoList.add(restOpInfoMap)
		 */
		// ++++ ... this line.
		sortedOpInfoList.add(opInfoMap)
		sortedOpInfoList
	}

	def isDomainKey(OperationInfo info) {
		if (info !== null && info.field !== null) {
			for (annotationRefs : info.field.annotations) {
				if (DomainKey.canonicalName.equals(annotationRefs.annotation.identifier)) {
					return true
				}
			}
		}
		return false
	}
	
	def isOnKanbanCard(OperationInfo info) {
		if (info !== null && info.field !== null) {
			for (annotationRefs : info.field.annotations) {
				if (OnKanbanCard.canonicalName.equals(annotationRefs.annotation.identifier)) {
					return true
				}
			}
		}
		return false
	}

	def isDomainDescription(OperationInfo info) {
		if (info !== null && info.field !== null) {
			for (annotationRefs : info.field.annotations) {
				if (DomainDescription.canonicalName.equals(annotationRefs.annotation.identifier)) {
					return true
				}
			}
		}
		return false
	}

	def isValidationConstraint(OperationInfo info) {
		if (info !== null && info.field !== null) {
			for (annotationRefs : info.field.annotations) {
				if (annotationRefs.annotation.identifier !== null &&
					annotationRefs.annotation.identifier.equals(Valid.canonicalName)) {
					return true
				}
			}
		}
		return false
	}

	def isUniqueEntry(OperationInfo info) {
		if (info !== null && info.field !== null) {
			for (annotationRefs : info.field.annotations) {
				if (annotationRefs.annotation.identifier !== null &&
					annotationRefs.annotation.identifier.equals(UniqueEntry.canonicalName)) {
					return true
				}
			}
		}
		return false
	}

	def isIndex(OperationInfo info) {
		if (info !== null && info.field !== null) {
			for (annotationRefs : info.field.annotations) {
				if (DomainKey.canonicalName.equals(annotationRefs.annotation.identifier)) {
					return true
				}
			}
		}
		return false
	}

	/**
	 * Returns true, if the type is boolean
	 * 
	 * @param type
	 * @return
	 */
	def isByteArray(JvmType type) {
		if (type === null)
			return false;
		if (isArray(type, Byte) || isArray(type, Byte.TYPE)) {
			return true;
		}
		return false;
	}

	def isArray(JvmType type, Class<?> clazz) {
		if (type === null)
			return false;
		var className = clazz.getName();
		if (className.charAt(0) == '[') {
			className = clazz.getCanonicalName();
		}
		className = className.concat("[]")
		var result = className.equals(type.getIdentifier());
		return result;
	}

	def YTypedSuspect createTextField(JvmType type, OperationInfo info) {
		val suspect = YECviewFactory.eINSTANCE.createYTypedSuspect
		suspect.tags += ILayoutingStrategy.TAG__TEXT
		suspect.type = computer.loadClass(uiLayout.eResource.resourceSet, type.qualifiedName)
		suspect.typeQualifiedName = type.qualifiedName
		suspect
	}

	def YTypedSuspect createSuggestTextField(JvmType type, OperationInfo info, Map<String, OperationInfo> opInfoMap) {
		val OperationInfo idAttInfo = opInfoMap.values.toIdInfo
		if (idAttInfo === null) {
			return createTextField(type, info)
		}

		val suspect = YECviewFactory.eINSTANCE.createYTypedSuspect
		suspect.tags += ILayoutingStrategy.TAG__SUGGEST_TEXT
		suspect.type = computer.loadClass(uiLayout.eResource.resourceSet, beanType.qualifiedName)
		suspect.typeQualifiedName = beanType.qualifiedName

		suspect.properties.put(ILayoutingStrategy.PROPERTY__ITEM_CAPTION, info.name)
		suspect.properties.put(ILayoutingStrategy.PROPERTY__ITEM_FILTER, info.name)
		suspect.properties.put(ILayoutingStrategy.PROPERTY__ITEM_UUID, idAttInfo.name)

		suspect
	}

	/** 
	 * Returns the operation info for the id property.  
	 */
	def OperationInfo getToIdInfo(Collection<OperationInfo> infos) {

		for (OperationInfo info : infos) {
			if (info.idOrUUID) {
				return info
			}
		}
		return null
	}

	def YTypedSuspect createTextAreaField(JvmType type, OperationInfo info) {
		val suspect = YECviewFactory.eINSTANCE.createYTypedSuspect
		suspect.tags += ILayoutingStrategy.TAG__TEXTAREA
		suspect.type = computer.loadClass(uiLayout.eResource.resourceSet, type.qualifiedName)
		suspect.typeQualifiedName = type.qualifiedName
		suspect
	}

	def YTypedSuspect createDecimalField(JvmType type, OperationInfo info) {
		val suspect = YECviewFactory.eINSTANCE.createYTypedSuspect
		suspect.tags += ILayoutingStrategy.TAG__DECIMAL
		suspect.type = computer.loadClass(uiLayout.eResource.resourceSet, type.qualifiedName)
		suspect.typeQualifiedName = type.qualifiedName
		suspect
	}

	def YTypedSuspect createNumberField(JvmType type, OperationInfo info) {
		val suspect = YECviewFactory.eINSTANCE.createYTypedSuspect
		suspect.tags += ILayoutingStrategy.TAG__NUMBER
		suspect.type = computer.loadClass(uiLayout.eResource.resourceSet, type.qualifiedName)
		suspect.typeQualifiedName = type.qualifiedName
		suspect
	}

	def YTypedSuspect createCheckbox(JvmType type, OperationInfo info) {
		val suspect = YECviewFactory.eINSTANCE.createYTypedSuspect
		suspect.tags += ILayoutingStrategy.TAG__BOOLEAN
		suspect.type = computer.loadClass(uiLayout.eResource.resourceSet, type.qualifiedName)
		suspect.typeQualifiedName = type.qualifiedName
		suspect
	}

	def YTypedSuspect createDateField(JvmType type, OperationInfo info) {
		val suspect = YECviewFactory.eINSTANCE.createYTypedSuspect
		suspect.tags += ILayoutingStrategy.TAG__DATE
		suspect.type = computer.loadClass(uiLayout.eResource.resourceSet, type.qualifiedName)
		suspect.typeQualifiedName = type.qualifiedName
		suspect
	}

	def YTypedSuspect createIconComboBox(JvmType type, OperationInfo info) {
		val suspect = YECviewFactory.eINSTANCE.createYTypedSuspect
		suspect.tags += ILayoutingStrategy.TAG__IMAGE_PICKER
		suspect.type = computer.loadClass(uiLayout.eResource.resourceSet, type.qualifiedName)
		suspect.typeQualifiedName = type.qualifiedName
		suspect
	}

	def YTypedSuspect createEnumComboBox(JvmType type, OperationInfo info) {
		val suspect = YECviewFactory.eINSTANCE.createYTypedSuspect
		suspect.tags += ILayoutingStrategy.TAG__ENUM_COMBO
		suspect.type = computer.loadClass(uiLayout.eResource.resourceSet, type.qualifiedName)
		suspect.typeQualifiedName = type.qualifiedName
		if (info.readonly) {
			suspect.tags += "readonly"
		}
		suspect
	}

	def YTypedSuspect createOrganizationComboBox(JvmType type, OperationInfo info) {
		val suspect = YECviewFactory.eINSTANCE.createYTypedSuspect
		suspect.tags += ILayoutingStrategy.TAG__ORGANIZATION_COMBO
		suspect.type = typeof(String)
		suspect.typeQualifiedName = typeof(String).name
		if (info.readonly) {
			suspect.tags += "readonly"
		}
		suspect
	}

	def YTypedSuspect createPerspectiveComboBox(JvmType type, OperationInfo info) {
		val suspect = YECviewFactory.eINSTANCE.createYTypedSuspect
		suspect.tags += ILayoutingStrategy.TAG__PERSPECTIVE_COMBO
		suspect.type = typeof(String)
		suspect.typeQualifiedName = typeof(String).name
		if (info.readonly) {
			suspect.tags += "readonly"
		}
		suspect
	}

	def YTypedSuspect createThemeComboBox(JvmType type, OperationInfo info) {
		val suspect = YECviewFactory.eINSTANCE.createYTypedSuspect
		suspect.tags += ILayoutingStrategy.TAG__THEME_COMBO
		suspect.type = typeof(String)
		suspect.typeQualifiedName = typeof(String).name
		if (info.readonly) {
			suspect.tags += "readonly"
		}
		suspect
	}

	def YTypedSuspect createPrintServiceComboBox(JvmType type, OperationInfo info) {
		val suspect = YECviewFactory.eINSTANCE.createYTypedSuspect
		suspect.tags += ILayoutingStrategy.TAG__PRINTSERVICE_COMBO
		suspect.type = typeof(String)
		suspect.typeQualifiedName = typeof(String).name
		if (info.readonly) {
			suspect.tags += "readonly"
		}
		suspect
	}

	def YTypedSuspect createEnumOptionsGroup(JvmType type, OperationInfo info) {
		val suspect = YECviewFactory.eINSTANCE.createYTypedSuspect
		suspect.tags += ILayoutingStrategy.TAG__ENUM_OPTIONS
		suspect.type = computer.loadClass(uiLayout.eResource.resourceSet, type.qualifiedName)
		suspect.typeQualifiedName = type.qualifiedName
		suspect.id = '''«uiLayout.generateId».«info.name»'''
		if (info.readonly) {
			suspect.tags += "readonly"
		}
		suspect
	}

	def YTypedSuspect createBeanReferenceField(JvmType type, OperationInfo info) {
		var YTypedSuspect suspect = null
		var suspectType = computer.loadClass(uiLayout.eResource.resourceSet, type.qualifiedName)
		var captionProperty = BeanHelper.findCaptionProperty(suspectType)
		var captionDescription = BeanHelper.findDescriptionProperty(suspectType)
		if (captionProperty !== null || captionDescription !== null) {
			suspect = YECviewFactory.eINSTANCE.createYTypedSuspect
			suspect.type = suspectType
			suspect.tags += ILayoutingStrategy.TAG__BEAN_REFERENCE
			suspect.id = '''«uiLayout.generateId».«info.name»'''

			if (info.readonly) {
				suspect.tags += "readonly"
			}

			if (info.hasAnnotation(FilterDepth)) {
				val depth = toFilterDepth(info.field)
				suspect.properties.put(ILayoutingStrategy.PROPERTY__FILTER_DEPTH, Integer.toString(depth))
			}

			suspect.typeQualifiedName = type.qualifiedName
			suspect.properties.put(ILayoutingStrategy.PROPERTY__ITEM_CAPTION, captionProperty)
			suspect.properties.put(ILayoutingStrategy.PROPERTY__ITEM_DESCRIPTION, captionDescription)
		}

		suspect
	}

	def YTypedSuspect createTableField(JvmType type, OperationInfo info) {
		type.createCollection(info, ILayoutingStrategy.TAG__TABLE)
	}

	def YTypedSuspect createGrid(JvmType type, OperationInfo info) {
		type.createCollection(info, ILayoutingStrategy.TAG__GRID)
	}

	def YTypedSuspect createCollection(JvmType type, OperationInfo info, String tag) {
		val suspect = YECviewFactory.eINSTANCE.createYCollectionSuspect
		val JvmParameterizedTypeReference collectionType = info.getter.returnType as JvmParameterizedTypeReference
		val JvmTypeReference typeInCollection = collectionType.arguments.get(0)
		suspect.type = computer.loadClass(uiLayout.eResource.resourceSet, typeInCollection.type.qualifiedName)
		suspect.tags += tag
		suspect.typeQualifiedName = typeInCollection.type.qualifiedName

		// Not used! Has to be removed!
		// var typeRef = info.field.type
		// var JvmDeclaredType argType
		if (typeInCollection.type instanceof JvmDeclaredType) {
			val castedType = typeInCollection.type as JvmDeclaredType

			// TODO get props from JVMType
			val propMap = castedType.toFieldProperties
			val opInfoMap = OperationExtensions.getOperationInfos(castedType)
			val sortedOpInfoMap = createSortedOpInfoMapForCollections(opInfoMap)
			sortedOpInfoMap.values.forEach [
				var JvmType detailType = it.getter.returnType.type
				var YColumnInfo columnInfo = null
				val isPrimitive = detailType instanceof JvmPrimitiveType;
				if (it.isDomainReference) {

					// else use the domain key field and reserve them till the end 
					for (nestedInfo : JvmTypeProperties.getOperationInfos(detailType as JvmDeclaredType).values) {
						if (nestedInfo.hasAnnotation(typeof(DomainKey))) {
							val nestPropMap = (detailType as JvmDeclaredType).toFieldProperties
							columnInfo = nestedInfo.type.createYColumnInfo
							columnInfo.name = it.field.simpleName + "." + nestedInfo.attributePath
							var propList = nestPropMap.get(nestedInfo.name)
							columnInfo.setYColumnInfoProperties(propList)
						}
					}
				} else if (!it.idOrUUID && !it.version && !it.dirtyMark) {
					var JvmType objectType = it.field.type.type;
					if (isPrimitive) {
						val primitiveTypeName = it.field.type.type.qualifiedName
						val InternalEObject proxy = TypesFactory.eINSTANCE.createJvmVoid as InternalEObject
						proxy.eSetProxyURI(URI.createURI(toObjectProxy(primitiveTypeName)))
						objectType = EcoreUtil.resolve(proxy, uiLayout.eResource) as JvmType
					}
					columnInfo = objectType.createYColumnInfo
					columnInfo.name = it.name
					var propList = propMap.get(it.field.identifier)
					columnInfo.setYColumnInfoProperties(propList)
				}
				if (columnInfo !== null) {

					// TODO (JCD): Simple name instead of FQN till solution of ticket - #581
					columnInfo.labelI18nKey = columnInfo.name
					suspect.columns += columnInfo
				}
			]
		}
		suspect
	}

	/** 
	 * Creates a proxy object 
	 **/
	def toObjectProxy(String primitiveTypeName) {
		switch (primitiveTypeName) {
			case "int":
				return '''java:/Objects/java.lang.Integer#java.lang.Integer'''
			default:
				return '''java:/Objects/java.lang.«primitiveTypeName.toFirstUpper»#java.lang.«primitiveTypeName.
					toFirstUpper»'''
		}
	}

	def void createMobileSwitch(JvmType type, OperationInfo info) {
		val yField = vFactory.createVMSwitch
		yField.initialEnabled = !info.readonly

		// yField.labelI18nKey = i18nRootKey + "." + info.name
		yField.label = info.name

		layouter.add(yField)

		yField.createBinding(info, type, "value");
	}

	def YSuspect createRichTextField(JvmType type, OperationInfo info) {
		val suspect = YECviewFactory.eINSTANCE.createYTypedSuspect

		if (type.string) {
			suspect.tags += ILayoutingStrategy.TAG__RICH_TEXT__STRING
		} else if (type.byteArray) {
			suspect.tags += ILayoutingStrategy.TAG__RICH_TEXT__BLOB
		} else {
			throw new IllegalArgumentException(
				"RichTextFields need to be bound to String or byte[]. " + type.qualifiedName +
					" is not a valid option.")
				}

				suspect.type = computer.loadClass(uiLayout.eResource.resourceSet, type.qualifiedName)
				suspect.typeQualifiedName = type.qualifiedName
				suspect
			}

			def YSuspect createMaskedTextField(JvmType type, OperationInfo info, String mask) {
				val suspect = YECviewFactory.eINSTANCE.createYTypedSuspect
				suspect.tags += ILayoutingStrategy.TAG__MASKED_TEXT_FIELD
				suspect.properties.put(ILayoutingStrategy.PROPERTY_MASK, mask)
				suspect.type = computer.loadClass(uiLayout.eResource.resourceSet, type.qualifiedName)
				suspect.typeQualifiedName = type.qualifiedName
				suspect
			}

			def YSuspect createMaskedDecimalField(JvmType type, OperationInfo info, String mask) {
				val suspect = YECviewFactory.eINSTANCE.createYTypedSuspect
				suspect.tags += ILayoutingStrategy.TAG__MASKED_DECIMAL_FIELD
				suspect.properties.put(ILayoutingStrategy.PROPERTY_MASK, mask)
				suspect.type = computer.loadClass(uiLayout.eResource.resourceSet, type.qualifiedName)
				suspect.typeQualifiedName = type.qualifiedName
				suspect
			}

			def YSuspect createPasswordField(JvmType type, OperationInfo info) {
				val suspect = YECviewFactory.eINSTANCE.createYTypedSuspect

				if (type.string) {
					suspect.tags += ILayoutingStrategy.TAG__PASSWORD
				} else {
					throw new IllegalArgumentException(
						"PasswordField need to be bound to String. " + type.qualifiedName + " is not a valid option.")
				}

				suspect.type = computer.loadClass(uiLayout.eResource.resourceSet, type.qualifiedName)
				suspect.typeQualifiedName = type.qualifiedName
				suspect
			}

			def YSuspect createBlopUploadComponent(JvmType type, OperationInfo info) {
				val suspect = YECviewFactory.eINSTANCE.createYTypedSuspect
				suspect.tags += ILayoutingStrategy.TAG__BLOB
				suspect.type = computer.loadClass(uiLayout.eResource.resourceSet, type.qualifiedName)
				suspect.typeQualifiedName = type.qualifiedName
				suspect
			}

			def YSuspect createCustomDecimalField(JvmType type, OperationInfo info) {
				val suspect = YECviewFactory.eINSTANCE.createYTypedSuspect
				suspect.tags += ILayoutingStrategy.TAG__DECIMAL
				suspect.type = computer.loadClass(uiLayout.eResource.resourceSet, type.qualifiedName)
				suspect.typeQualifiedName = type.qualifiedName
				suspect
			}

			/**
			 * Create the bindings and install at the view
			 */
			def createBinding(YEmbeddable yField, OperationInfo info, JvmType type, String fieldProperty) {

				// use the autoWireSource as the model endpoint
				val UiBindingEndpointAssignment uiModelEndpoint = uiLayout.autoWireSource as UiBindingEndpointAssignment
				val yModelEndpoint = computer.createValueBindingEndpoint(uiModelEndpoint)
				val detailValueEndpoint = yModelEndpoint.createDetailValueEndpoint
				detailValueEndpoint.propertyPath = info.name
				detailValueEndpoint.type = computer.loadClass(uiLayout.eResource.resourceSet, beanType.qualifiedName)

				// create the field endpoint
				val yFieldEndpoint = BindingFactory.eINSTANCE.createYECViewModelValueBindingEndpoint
				yFieldEndpoint.element = yField
				yFieldEndpoint.propertyPath = fieldProperty
				yFieldEndpoint.typeQualifiedName = beanType.qualifiedName
				yFieldEndpoint.type = computer.loadClass(uiLayout.eResource.resourceSet, beanType.qualifiedName)
				if (yFieldEndpoint.type !== null && yFieldEndpoint.type.isAssignableFrom(typeof(EObject))) {
					yFieldEndpoint.emfNsURI = yField.eClass.EPackage.nsURI
				}

				// bind model to target		
				val yBinding = BindingFactory.eINSTANCE.createYValueBinding();
				yBinding.setTargetEndpoint(yFieldEndpoint);
				yBinding.setModelEndpoint(detailValueEndpoint);
				yBinding.setModelToTargetStrategy(YBindingUpdateStrategy.UPDATE);
				yBinding.setTargetToModelStrategy(
					if(info.readonly) YBindingUpdateStrategy.NEVER else YBindingUpdateStrategy.UPDATE)

				// register the binding at the current view
				yLayout.view.orCreateBindingSet.bindings += yBinding

				// set the i18n key based on the binding
				// yField.labelI18nKey = I18nKeyProvider.toI18nKey(beanType.qualifiedName, detailValueEndpoint.propertyPath)
				yField.labelI18nKey = detailValueEndpoint.propertyPath
			}

			/**
			 * Create the bindings and install at the view
			 */
			def createModelValueBinding(YSuspect suspect, String propertyPath, JvmType type, String fieldProperty, JvmType parentType) {

				val YBeanSlot subTypeBeanSlot = suspect.findSubTypeBeanSlot
				var YValueBindingEndpoint endpoint = null
				var path = ""

				// If a subTypeBeanSlot could be found, then we need to create a binding endpoint against this beanslot.
				// The main slot has a different type then detail beanslot. And we can not bind fields contained in the subtype
				// to the main bean slot. Eclipse databinding requires a proper type at binding creation.
				if (subTypeBeanSlot === null) {

					// use the autoWireSource as the model endpoint
					val UiBindingEndpointAssignment uiModelEndpoint = uiLayout.
						autoWireSource as UiBindingEndpointAssignment
					val yModelEndpoint = computer.createValueBindingEndpoint(uiModelEndpoint)
					val detailValueEndpoint = yModelEndpoint.createDetailValueEndpoint
					detailValueEndpoint.propertyPath = propertyPath
					detailValueEndpoint.type = computer.loadClass(uiLayout.eResource.resourceSet,
						parentType.qualifiedName)
					endpoint = detailValueEndpoint
					path = detailValueEndpoint.propertyPath
				} else {
					endpoint = subTypeBeanSlot.createBindingEndpoint(propertyPath)
					path = propertyPath
				}

				suspect.getValueBindingEndpoints().add(endpoint);

				// set the i18n key based on the binding
				// suspect.labelI18nKey = I18nKeyProvider.toI18nKey(beanType.qualifiedName, path)
				suspect.labelI18nKey = path
				suspect.label = propertyPath
			}

			/**
			 * Creates a binding which points to the container of the property
			 */
			def createModelValueContainerBinding(YSuspect suspect, String propertyPath, JvmType type, String property) {

				var fieldProperty = property
				if (fieldProperty.contains(".")) {
					fieldProperty = fieldProperty.substring(0, fieldProperty.lastIndexOf("."))
				} else {
					fieldProperty = null
				}

				val YBeanSlot subTypeBeanSlot = suspect.findSubTypeBeanSlot
				var YValueBindingEndpoint endpoint = null

				// If a subTypeBeanSlot could be found, then we need to create a binding endpoint against this beanslot.
				// The main slot has a different type then detail beanslot. And we can not bind fields contained in the subtype
				// to the main bean slot. Eclipse databinding requires a proper type at binding creation.
				if (subTypeBeanSlot === null) {

					// use the autoWireSource as the model endpoint
					val UiBindingEndpointAssignment uiModelEndpoint = uiLayout.
						autoWireSource as UiBindingEndpointAssignment
					val yModelEndpoint = computer.createValueBindingEndpoint(uiModelEndpoint)
					endpoint = yModelEndpoint
					if (fieldProperty !== null) {
						val detailValueEndpoint = yModelEndpoint.createDetailValueEndpoint
						detailValueEndpoint.propertyPath = propertyPath
						detailValueEndpoint.type = computer.loadClass(uiLayout.eResource.resourceSet,
							beanType.qualifiedName)
						endpoint = detailValueEndpoint
					}
				} else {
					endpoint = subTypeBeanSlot.createBindingEndpoint(propertyPath)
				}

				suspect.containerValueBindingEndpoint = endpoint
			}

			/**
			 * Checks if the suspect is contained in an YSubTypeSuspect. <br>
			 * If so, then the detail beanslot of the YSubTypeSuspect is returned. Null otherwise.
			 */
			def YBeanSlot findSubTypeBeanSlot(YSuspect suspect) {
				if (suspect === null) {
					return null
				}
				if (suspect instanceof YSubTypeSuspect) {
					return suspect.beanSlot
				}

				val parent = suspect.eContainer
				if (parent instanceof YSuspect) {
					return parent.findSubTypeBeanSlot
				}
				return null
			}

			/**
			 * Create the bindings and install at the view
			 */
			def createModelListBinding(YSuspect suspect, OperationInfo info, JvmType type, String fieldProperty) {

				val YBeanSlot subTypeBeanSlot = suspect.findSubTypeBeanSlot
				var YListBindingEndpoint endpoint = null
				if (subTypeBeanSlot === null) {
					// use the autoWireSource as the model endpoint
					val UiBindingEndpointAssignment uiModelEndpoint = uiLayout.
						autoWireSource as UiBindingEndpointAssignment
					endpoint = createListBindingEndpointWithNested(uiModelEndpoint, info.name)
				} else {
					endpoint = subTypeBeanSlot.createListBindingEndpoint(info.name, subTypeBeanSlot.valueType)
				}

				suspect.getValueBindingEndpoints().add(endpoint);

				// set the i18n key based on the binding
				// suspect.labelI18nKey = I18nKeyProvider.toI18nKey(beanType.qualifiedName, info.name)
				suspect.labelI18nKey = info.name
				suspect.label = info.name
			}

			/**
			 * Creates a listbinding with respect to nested collection fields. <p>
			 * For instance:<br>
			 * beanSlot contains Person. We want to bind the children of persons father to a table.
			 * So we need to access the children collection of the beanslot by a nested property path: <code>beanslot.father.children</code>
			 */
			def YListBindingEndpoint createListBindingEndpointWithNested(UiBindingEndpointAssignment epDef,
				String attributePath) {
				if (epDef === null) {
					return null
				}

				var YListBindingEndpoint result = null;
				val BindingInfoHelper.BindingInfo info = new BindingInfoHelper.BindingInfo()
				bindingInfoHelper.collectBindingInfo(epDef, info);

				if (info.bindingRoot instanceof UiBeanSlot) {
					val uiBeanSlot = info.bindingRoot as UiBeanSlot

					val YBeanSlot yBeanSlot = computer.associatedUi(uiBeanSlot)
					val YBeanSlotListBindingEndpoint ep = factory.createBeanSlotListBindingEndpoint
					ep.beanSlot = yBeanSlot

					ep.attributePath = toNestedCollectionPath(info, attributePath)
					result = ep
				} else if (info.bindingRoot instanceof UiEmbeddable) {
					val YEmbeddable yElement = computer.associatedUi(info.bindingRoot)
					val YECViewModelListBindingEndpoint ep = factory.createECViewModelListBindingEndpoint
					ep.element = yElement
					ep.propertyPath = toNestedCollectionPath(info, attributePath)
					if (info.typeForBinding !== null) {
						ep.typeQualifiedName = info.typeForBinding.qualifiedName
						ep.type = computer.loadClass(epDef.eResource.resourceSet, ep.typeQualifiedName)
					}
					if (yElement !== null) {
						ep.emfNsURI = yElement.eClass.EPackage.nsURI
					}
					result = ep
				}

				return result
			}

			def toNestedCollectionPath(BindingInfo info, String attributePath) {
				val StringBuilder b = new StringBuilder
				if (!info.path.toString.nullOrEmpty) {
					b.append(info.path.toString)
				}

				if (!attributePath.nullOrEmpty) {
					if (b.length > 0) {
						b.append(".")
					}
					b.append(attributePath)
				}
				val pathResult = b.toString
				pathResult
			}

			/**
			 * Creates y column info element 
			 */
			def YColumnInfo createYColumnInfo(JvmType type) {
				val YColumnInfo columnInfo = YECviewFactory.eINSTANCE.createYColumnInfo

				columnInfo.typeQualifiedName = type.qualifiedName
				columnInfo.type = computer.loadClass(uiLayout.eResource.resourceSet, columnInfo.typeQualifiedName)
				columnInfo
			}

			/**
			 * Sets properties into y column info
			 */
			def setYColumnInfoProperties(YColumnInfo columnInfo, List<AutowireUtil.Pair> propList) {
				var properties = columnInfo.properties
				if (propList !== null) {
					for (prop : propList) {
						properties.put(prop.key, prop.value)
					}
				}
			}

			public interface Layouter {
				def void setup(UiLayout uiRootLayout, YLayout yRootLayout)

				def void add(YEmbeddable element);

				def void add(YSuspect suspect);

				def void pushHierarchy(YTypedCompoundSuspect suspect);

				def void popHierarchy();

			}

			public static class MobileLayouter implements Layouter {

				VMVerticalComponentGroup group

				override setup(UiLayout uiRootLayout, YLayout yRootLayout) {
					group = VaadinMobileFactory.eINSTANCE.createVMVerticalComponentGroup

					yRootLayout.elements += group
				}

				override add(YEmbeddable element) {
					group.addElement(element)
				}

				override add(YSuspect ySuspect) {
					// layout.suspects += ySuspect
				}

				override pushHierarchy(YTypedCompoundSuspect suspect) {
					throw new UnsupportedOperationException("TODO: auto-generated method stub")
				}

				override popHierarchy() {
					throw new UnsupportedOperationException("TODO: auto-generated method stub")
				}

			}

			public static class StrategyLayoutLayouter implements Layouter {

				Stack<YTypedCompoundSuspect> currentSubDtoSuspect = new Stack
				YStrategyLayout layout

				override setup(UiLayout uiRootLayout, YLayout yRootLayout) {
					layout = YECviewFactory.eINSTANCE.createYStrategyLayout
					layout.id = "cx-StrategyLayout"

					yRootLayout.elements += layout
					yRootLayout.view.visibilityProcessors +=
						YVisibilityFactory.eINSTANCE.createYAuthorizationVisibilityProcessor
					if (yRootLayout instanceof YAlignmentContainer) {
						yRootLayout.applyAlignment(layout, YAlignment.FILL_FILL)
					}
				}

				override add(YEmbeddable element) {
				}

				override add(YSuspect ySuspect) {
					if (!currentSubDtoSuspect.isEmpty) {
						currentSubDtoSuspect.peek.children += ySuspect
					} else {
						layout.suspects += ySuspect
					}
				}

				override pushHierarchy(YTypedCompoundSuspect suspect) {
					currentSubDtoSuspect.push(suspect)
				}

				override popHierarchy() {
					currentSubDtoSuspect.pop
				}

			}

			/**
			 * The Class LocalResourceAccess.
			 */
			public static class LocalResourceAccess implements IReferenceFinder.ILocalResourceAccess {

				ResourceSet rs

				new(ResourceSet rs) {
					this.rs = rs
				}

				/*
				 * (non-Javadoc)
				 * 
				 * @see
				 * org.eclipse.xtext.findReferences.IReferenceFinder.IResourceAccess
				 * #readOnly(org.eclipse.emf.common.util.URI,
				 * org.eclipse.xtext.util.concurrent.IUnitOfWork)
				 */
				override <R> R readOnly(URI targetURI, IUnitOfWork<R, ResourceSet> work) {
					return work.exec(rs);
				}
			}
		}
		