/**
 *                                                                            
 *  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_I18N)]) {
						suspect = type.createI18nComboBox(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 createI18nComboBox(JvmType type, OperationInfo info) {
		val suspect = YECviewFactory.eINSTANCE.createYTypedSuspect
		suspect.tags += ILayoutingStrategy.TAG__I18N_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);
				}
			}
		}
		