/**
 *                                                                            
 *  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.Constraint
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.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.I18nKeyProvider
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.metric.TimeLogger
import org.eclipse.osbp.utils.functionnormalizer.api.FunctionTypingAPI
import org.eclipse.xtext.common.types.JvmDeclaredType
import org.eclipse.xtext.common.types.JvmEnumerationLiteral
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

@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, JvmType dtoType,
		boolean mobile, YTypedCompoundSuspect parentSuspect) {
		if (!dtoType.isEnum) {
			sortedOpInfoMapList.forEach [
				it.createSuspectStructure(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, 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(beanType.toProperties(it.field.declaringType.qualifiedName + "." + it.name))
			}
			if (type.boolean) {
				if(mobile) type.createMobileSwitch(it) else suspect = type.createCheckbox(it)
			} else if (type.numberWithDigits) {
				suspect = type.createDecimalField(it)
				if (beanType.isAttribute(it.name, "NumberToUomo")) {
					suspect.tags += "NumberToUomo"
				} else {
					var dataType = beanType.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) {

				// TODO Pirchner _ fix me with @ID annotation
				if (!it.name.equals("id") && !it.name.equals("uuid")) {
					suspect = type.createNumberField(it)
				}
			} else if (type.string) {
				val fieldType = properties.findFirst[it.key.equals(ILayoutingStrategy.PROPERTY_KEY__FIELD_TYPE)]?.value

				// TODO Pirchner _ fix me with @ID annotation
				if (!it.name.equals("id") && !it.name.equals("uuid")) {
					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(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)
			} else {
				type.completeSuspect(it, suspect, parentSuspect)
			}
			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) {
		if (suspect != null) {
			suspect.id = '''«uiLayout.generateId».«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)
			}

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

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

	def completeSuspect(JvmType type, OperationInfo info, YSuspect suspect, YTypedCompoundSuspect parentSuspect) {
		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.createBinding(info.name, type, "value");
			}

			// 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 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.startsWith(Constraint.canonicalName.toLowerCase)) {
					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) {

		// TODO change me!!! Very bad hack for now! Needs adding an ID annotation to DTOs
		for (OperationInfo info : infos) {
			if (info.name.equals("id") || info.name.equals("uuid")) {
				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 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) {
		val suspect = YECviewFactory.eINSTANCE.createYTypedSuspect
		suspect.type = computer.loadClass(uiLayout.eResource.resourceSet, type.qualifiedName)
		var captionProperty = BeanHelper.findCaptionProperty(suspect.type)
		var captionDescription = BeanHelper.findDescriptionProperty(suspect.type)
		if (captionProperty != null || captionDescription != null) {
			suspect.tags += ILayoutingStrategy.TAG__BEAN_REFERENCE
			suspect.id = '''«uiLayout.generateId».«info.name»'''

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

			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.type.simpleName + "." + nestedInfo.attributePath
							var propList = nestPropMap.get(nestedInfo.name)
							columnInfo.setYColumnInfoProperties(propList)
						}
					}
				} else {
					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 createBinding(YSuspect suspect, String propertyPath, JvmType type, String fieldProperty) {

		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, beanType.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
	}

	/**
	 * 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) {

		// use the autoWireSource as the model endpoint
		val UiBindingEndpointAssignment uiModelEndpoint = uiLayout.autoWireSource as UiBindingEndpointAssignment
		val yModelEndpoint = createListBindingEndpointWithNested(uiModelEndpoint, info.name)

		suspect.getValueBindingEndpoints().add(yModelEndpoint);

		// 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);
		}
	}
}
