/**
 * 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.common.base.Objects;
import com.google.inject.Inject;
import com.google.inject.Injector;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import javax.validation.Valid;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.EMap;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
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.JvmTypeProperties;
import org.eclipse.osbp.autowirehelper.utils.AutowireUtil;
import org.eclipse.osbp.dsl.common.datatypes.IDto;
import org.eclipse.osbp.dsl.semantic.common.types.LDataType;
import org.eclipse.osbp.ecview.core.common.model.binding.BindingFactory;
import org.eclipse.osbp.ecview.core.common.model.binding.YBinding;
import org.eclipse.osbp.ecview.core.common.model.binding.YBindingEndpoint;
import org.eclipse.osbp.ecview.core.common.model.binding.YBindingUpdateStrategy;
import org.eclipse.osbp.ecview.core.common.model.binding.YDetailValueBindingEndpoint;
import org.eclipse.osbp.ecview.core.common.model.binding.YECViewModelListBindingEndpoint;
import org.eclipse.osbp.ecview.core.common.model.binding.YECViewModelValueBindingEndpoint;
import org.eclipse.osbp.ecview.core.common.model.binding.YListBindingEndpoint;
import org.eclipse.osbp.ecview.core.common.model.binding.YValueBinding;
import org.eclipse.osbp.ecview.core.common.model.binding.YValueBindingEndpoint;
import org.eclipse.osbp.ecview.core.common.model.core.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.common.model.visibility.YVisibilityProcessor;
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.OperationExtensions;
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.YCollectionSuspect;
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.YSubTypeBaseSuspect;
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.YAuthorizationVisibilityProcessor;
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.UiBindingExpression;
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.ecview.semantic.uimodel.UiTypedBindable;
import org.eclipse.osbp.mobile.vaadin.ecview.model.VMSwitch;
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.OnKanbanCard;
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.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.common.types.JvmAnnotationReference;
import org.eclipse.xtext.common.types.JvmDeclaredType;
import org.eclipse.xtext.common.types.JvmField;
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.JvmVoid;
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.xtext.xbase.lib.CollectionLiterals;
import org.eclipse.xtext.xbase.lib.Exceptions;
import org.eclipse.xtext.xbase.lib.Extension;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.StringExtensions;

@SuppressWarnings("restriction")
public class AutowireHelper implements IAutowireDelegate {
  public interface Layouter {
    public abstract void setup(final UiLayout uiRootLayout, final YLayout yRootLayout);
    
    public abstract void add(final YEmbeddable element);
    
    public abstract void add(final YSuspect suspect);
    
    public abstract void pushHierarchy(final YTypedCompoundSuspect suspect);
    
    public abstract void popHierarchy();
  }
  
  public static class MobileLayouter implements AutowireHelper.Layouter {
    private VMVerticalComponentGroup group;
    
    @Override
    public void setup(final UiLayout uiRootLayout, final YLayout yRootLayout) {
      this.group = VaadinMobileFactory.eINSTANCE.createVMVerticalComponentGroup();
      EList<YEmbeddable> _elements = yRootLayout.getElements();
      _elements.add(this.group);
    }
    
    @Override
    public void add(final YEmbeddable element) {
      this.group.addElement(element);
    }
    
    @Override
    public void add(final YSuspect ySuspect) {
    }
    
    @Override
    public void pushHierarchy(final YTypedCompoundSuspect suspect) {
      throw new UnsupportedOperationException("TODO: auto-generated method stub");
    }
    
    @Override
    public void popHierarchy() {
      throw new UnsupportedOperationException("TODO: auto-generated method stub");
    }
  }
  
  public static class StrategyLayoutLayouter implements AutowireHelper.Layouter {
    private Stack<YTypedCompoundSuspect> currentSubDtoSuspect = new Stack<YTypedCompoundSuspect>();
    
    private YStrategyLayout layout;
    
    @Override
    public void setup(final UiLayout uiRootLayout, final YLayout yRootLayout) {
      this.layout = YECviewFactory.eINSTANCE.createYStrategyLayout();
      this.layout.setId("cx-StrategyLayout");
      EList<YEmbeddable> _elements = yRootLayout.getElements();
      _elements.add(this.layout);
      EList<YVisibilityProcessor> _visibilityProcessors = yRootLayout.getView().getVisibilityProcessors();
      YAuthorizationVisibilityProcessor _createYAuthorizationVisibilityProcessor = YVisibilityFactory.eINSTANCE.createYAuthorizationVisibilityProcessor();
      _visibilityProcessors.add(_createYAuthorizationVisibilityProcessor);
      if ((yRootLayout instanceof YAlignmentContainer)) {
        ((YAlignmentContainer)yRootLayout).applyAlignment(this.layout, YAlignment.FILL_FILL);
      }
    }
    
    @Override
    public void add(final YEmbeddable element) {
    }
    
    @Override
    public void add(final YSuspect ySuspect) {
      boolean _isEmpty = this.currentSubDtoSuspect.isEmpty();
      boolean _not = (!_isEmpty);
      if (_not) {
        EList<YSuspect> _children = this.currentSubDtoSuspect.peek().getChildren();
        _children.add(ySuspect);
      } else {
        EList<YSuspect> _suspects = this.layout.getSuspects();
        _suspects.add(ySuspect);
      }
    }
    
    @Override
    public void pushHierarchy(final YTypedCompoundSuspect suspect) {
      this.currentSubDtoSuspect.push(suspect);
    }
    
    @Override
    public void popHierarchy() {
      this.currentSubDtoSuspect.pop();
    }
  }
  
  /**
   * The Class LocalResourceAccess.
   */
  public static class LocalResourceAccess implements IReferenceFinder.ILocalResourceAccess {
    private ResourceSet rs;
    
    public LocalResourceAccess(final 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
    public <R extends Object> R readOnly(final URI targetURI, final IUnitOfWork<R, ResourceSet> work) {
      try {
        return work.exec(this.rs);
      } catch (Throwable _e) {
        throw Exceptions.sneakyThrow(_e);
      }
    }
  }
  
  @Inject
  @Extension
  private TypeHelper _typeHelper;
  
  @Inject
  @Extension
  private AutowireUtil _autowireUtil;
  
  @Inject
  @Extension
  private IQualifiedNameProvider _iQualifiedNameProvider;
  
  @Inject
  private BindingInfoHelper bindingInfoHelper;
  
  @Inject
  private IReferenceFinder referenceFinder;
  
  @Inject
  private Injector injector;
  
  private VaadinMobileFactory vFactory = VaadinMobileFactory.eINSTANCE;
  
  private UiModelDerivedStateComputerx computer;
  
  private boolean mobile;
  
  private YLayout yLayout;
  
  private UiLayout uiLayout;
  
  private AutowireHelper.Layouter layouter;
  
  private JvmDeclaredType beanType;
  
  private final SimpleExtensionModelFactory factory = new SimpleExtensionModelFactory();
  
  private YView yView;
  
  private YBeanSlot yMainBeanslot;
  
  @Override
  public void autowire(final UiLayout uiLayout, final UiModelDerivedStateComputerx computer, final boolean mobile) {
    boolean _isAutowire = uiLayout.isAutowire();
    boolean _not = (!_isAutowire);
    if (_not) {
      return;
    }
    final TimeLogger logger = TimeLogger.start(AutowireHelper.class);
    this.computer = computer;
    this.mobile = mobile;
    this.uiLayout = uiLayout;
    this.yLayout = computer.<YLayout>associatedUi(uiLayout);
    this.yView = this.yLayout.getView();
    this.yMainBeanslot = this.getBeanSlot(uiLayout);
    boolean _matched = false;
    if (uiLayout instanceof UiHorizontalLayout) {
      _matched=true;
      AutowireHelper.Layouter _xifexpression = null;
      if ((!mobile)) {
        _xifexpression = new AutowireHelper.StrategyLayoutLayouter();
      } else {
        _xifexpression = new AutowireHelper.MobileLayouter();
      }
      this.layouter = _xifexpression;
      this.layouter.setup(uiLayout, this.yLayout);
    }
    if (!_matched) {
      return;
    }
    final BindableTypeResolver resolver = new BindableTypeResolver();
    JvmType resolvedType = resolver.resolveType(uiLayout.getAutoWireSource());
    if ((resolvedType instanceof JvmDeclaredType)) {
      this.beanType = ((JvmDeclaredType) resolvedType);
      final Map<String, OperationExtensions.OperationInfo> opInfoMap = OperationExtensions.getOperationInfos(this.beanType);
      final LinkedList<Map<String, OperationExtensions.OperationInfo>> sortedOpInfoMapList = this.createSortedMapList(opInfoMap);
      this.createSuspectStructure(sortedOpInfoMapList, this.beanType, mobile, null);
    }
  }
  
  /**
   * Finds all sub types of the beanType
   */
  public Set<URI> findSubTypes(final JvmType dtoType, final Resource resource) {
    Set<URI> _xblockexpression = null;
    {
      final Set<URI> result = CollectionLiterals.<URI>newHashSet();
      final Set<URI> jvmTypeURIs = CollectionLiterals.<URI>newHashSet();
      URI _uRI = EcoreUtil.getURI(dtoType);
      jvmTypeURIs.add(_uRI);
      final IAcceptor<IReferenceDescription> _function = (IReferenceDescription it) -> {
        final IReferenceDescription desc = it;
        EReference _eReference = desc.getEReference();
        boolean _tripleEquals = (_eReference == TypesPackage.Literals.JVM_PARAMETERIZED_TYPE_REFERENCE__TYPE);
        if (_tripleEquals) {
          boolean _endsWith = it.getSourceEObjectUri().fragment().endsWith("/@superTypes.0");
          if (_endsWith) {
            final URI uri = desc.getSourceEObjectUri();
            URI _createURI = URI.createURI(uri.toString().replace("/@superTypes.0", ""));
            result.add(_createURI);
          }
        }
      };
      final IAcceptor<IReferenceDescription> acceptor = _function;
      ResourceSet _resourceSet = resource.getResourceSet();
      AutowireHelper.LocalResourceAccess _localResourceAccess = new AutowireHelper.LocalResourceAccess(_resourceSet);
      this.referenceFinder.findAllReferences(jvmTypeURIs, _localResourceAccess, acceptor, null);
      _xblockexpression = result;
    }
    return _xblockexpression;
  }
  
  public YBeanSlot getBeanSlot(final UiLayout uiLayout) {
    UiBindingExpression autoWireSourceTemp = uiLayout.getAutoWireSource();
    if ((autoWireSourceTemp instanceof UiBindingEndpointAssignment)) {
      UiTypedBindable alias = ((UiBindingEndpointAssignment) autoWireSourceTemp).getTypedBindableAlias();
      if ((alias instanceof UiBeanSlot)) {
        return this.computer.<YBeanSlot>associatedUi(((UiBeanSlot) alias));
      }
    }
    return null;
  }
  
  public void createSuspectStructure(final JvmDeclaredType type, final boolean mobile, final YTypedCompoundSuspect parentSuspect) {
    final Map<String, OperationExtensions.OperationInfo> opInfoMap = OperationExtensions.getOperationInfos(type);
    final LinkedList<Map<String, OperationExtensions.OperationInfo>> sortedOpInfoMapList = this.createSortedMapList(opInfoMap);
    this.createSuspectStructure(sortedOpInfoMapList, type, mobile, parentSuspect);
  }
  
  public void createSuspectStructure(final LinkedList<Map<String, OperationExtensions.OperationInfo>> sortedOpInfoMapList, final JvmDeclaredType dtoType, final boolean mobile, final YTypedCompoundSuspect parentSuspect) {
    boolean _isEnum = this._typeHelper.isEnum(dtoType);
    boolean _not = (!_isEnum);
    if (_not) {
      final Consumer<Map<String, OperationExtensions.OperationInfo>> _function = (Map<String, OperationExtensions.OperationInfo> it) -> {
        this.createSuspectStructure(it, dtoType, mobile, parentSuspect);
      };
      sortedOpInfoMapList.forEach(_function);
    }
    final Set<URI> subTypeURIs = this.findSubTypes(dtoType, this.uiLayout.eResource());
    boolean _isEmpty = subTypeURIs.isEmpty();
    boolean _not_1 = (!_isEmpty);
    if (_not_1) {
      final YSubTypeBaseSuspect subtypeRootSuspect = YECviewFactory.eINSTANCE.createYSubTypeBaseSuspect();
      EList<String> _tags = subtypeRootSuspect.getTags();
      _tags.add(ILayoutingStrategy.TAG__SUBTYPES_ROOT);
      subtypeRootSuspect.setTypeQualifiedName(dtoType.getQualifiedName());
      this.layouter.add(subtypeRootSuspect);
      this.layouter.pushHierarchy(subtypeRootSuspect);
    }
    final Consumer<URI> _function_1 = (URI it) -> {
      EObject _eObject = this.uiLayout.eResource().getResourceSet().getEObject(it, true);
      final JvmDeclaredType subDtoJvmType = ((JvmDeclaredType) _eObject);
      this.createSubTypeDtoSuspect(subDtoJvmType);
    };
    subTypeURIs.forEach(_function_1);
    boolean _isEmpty_1 = subTypeURIs.isEmpty();
    boolean _not_2 = (!_isEmpty_1);
    if (_not_2) {
      this.layouter.popHierarchy();
    }
  }
  
  public void createSuspectStructure(final Map<String, OperationExtensions.OperationInfo> opInfoMap, final JvmDeclaredType dtoType, final boolean mobile, final YTypedCompoundSuspect parentSuspect) {
    final Consumer<OperationExtensions.OperationInfo> _function = (OperationExtensions.OperationInfo it) -> {
      JvmType type = null;
      try {
        type = it.getGetter().getReturnType().getType();
      } catch (final Throwable _t) {
        if (_t instanceof NullPointerException) {
          final NullPointerException e = (NullPointerException)_t;
          return;
        } else {
          throw Exceptions.sneakyThrow(_t);
        }
      }
      YSuspect suspect = null;
      ArrayList<AutowireUtil.Pair> properties = CollectionLiterals.<AutowireUtil.Pair>newArrayList();
      JvmField _field = it.getField();
      boolean _tripleNotEquals = (_field != null);
      if (_tripleNotEquals) {
        String _qualifiedName = it.getField().getDeclaringType().getQualifiedName();
        String _plus = (_qualifiedName + ".");
        String _name = it.getName();
        String _plus_1 = (_plus + _name);
        properties.addAll(this._autowireUtil.toProperties(dtoType, _plus_1));
      }
      if ((this._typeHelper.isBoolean(type) && (!it.isDirtyMark()))) {
        if (mobile) {
          this.createMobileSwitch(type, it);
        } else {
          suspect = this.createCheckbox(type, it);
        }
      } else {
        boolean _isNumberWithDigits = this._typeHelper.isNumberWithDigits(type);
        if (_isNumberWithDigits) {
          suspect = this.createDecimalField(type, it);
          boolean _isAttribute = this._autowireUtil.isAttribute(dtoType, it.getName(), "NumberToUomo");
          if (_isAttribute) {
            EList<String> _tags = suspect.getTags();
            _tags.add("NumberToUomo");
          } else {
            LDataType dataType = this._autowireUtil.toDataType(dtoType, it.getName());
            if ((dataType != null)) {
              String dataTypeName = dataType.getJvmTypeReference().getType().getIdentifier();
              boolean _equals = dataTypeName.equals(Double.class.getCanonicalName());
              if (_equals) {
                suspect = this.createCustomDecimalField(type, it);
              }
            }
          }
        } else {
          boolean _isNumberWithoutDigits = this._typeHelper.isNumberWithoutDigits(type);
          if (_isNumberWithoutDigits) {
            if ((((!it.isIdOrUUID()) && (!it.isVersion())) && (!it.isDirtyMark()))) {
              suspect = this.createNumberField(type, it);
            }
          } else {
            boolean _isString = this._typeHelper.isString(type);
            if (_isString) {
              final Function1<AutowireUtil.Pair, Boolean> _function_1 = (AutowireUtil.Pair it_1) -> {
                return Boolean.valueOf(it_1.key.equals(ILayoutingStrategy.PROPERTY_KEY__FIELD_TYPE));
              };
              AutowireUtil.Pair _findFirst = IterableExtensions.<AutowireUtil.Pair>findFirst(properties, _function_1);
              String _value = null;
              if (_findFirst!=null) {
                _value=_findFirst.value;
              }
              final String fieldType = _value;
              if ((((!it.isIdOrUUID()) && (!it.isVersion())) && (!it.isDirtyMark()))) {
                FunctionTypingAPI functionTypingAPI = new FunctionTypingAPI();
                final String functionImagePicker = functionTypingAPI.getFunctionImagePickerTypeName();
                if (((this.isDomainKey(it) || this.isDomainDescription(it)) || ((!StringExtensions.isNullOrEmpty(fieldType)) && fieldType.equals(ILayoutingStrategy.PROPERTY_SUGGESTTEXT)))) {
                  suspect = this.createSuggestTextField(type, it, opInfoMap);
                } else {
                  final Function1<AutowireUtil.Pair, Boolean> _function_2 = (AutowireUtil.Pair it_1) -> {
                    return Boolean.valueOf(it_1.key.toLowerCase().equals(ILayoutingStrategy.PROPERTY_BLOB));
                  };
                  boolean _exists = IterableExtensions.<AutowireUtil.Pair>exists(properties, _function_2);
                  if (_exists) {
                    suspect = this.createBlopUploadComponent(type, it);
                  } else {
                    if (((!StringExtensions.isNullOrEmpty(fieldType)) && fieldType.equals(ILayoutingStrategy.PROPERTY_RICH_TEXT))) {
                      suspect = this.createRichTextField(type, it);
                    } else {
                      if (((!StringExtensions.isNullOrEmpty(fieldType)) && fieldType.equals(ILayoutingStrategy.PROPERTY_MASKED_TEXT))) {
                        final Function1<AutowireUtil.Pair, Boolean> _function_3 = (AutowireUtil.Pair it_1) -> {
                          return Boolean.valueOf(it_1.key.equals(ILayoutingStrategy.PROPERTY_MASK));
                        };
                        AutowireUtil.Pair _findFirst_1 = IterableExtensions.<AutowireUtil.Pair>findFirst(properties, _function_3);
                        String _value_1 = null;
                        if (_findFirst_1!=null) {
                          _value_1=_findFirst_1.value;
                        }
                        final String mask = _value_1;
                        suspect = this.createMaskedTextField(type, it, mask);
                      } else {
                        if (((!StringExtensions.isNullOrEmpty(fieldType)) && fieldType.equals(ILayoutingStrategy.PROPERTY_PASSWORD))) {
                          suspect = this.createPasswordField(type, it);
                        } else {
                          final Function1<AutowireUtil.Pair, Boolean> _function_4 = (AutowireUtil.Pair it_1) -> {
                            return Boolean.valueOf(it_1.key.equalsIgnoreCase(ILayoutingStrategy.PROPERTY_TEXTAREA));
                          };
                          boolean _exists_1 = IterableExtensions.<AutowireUtil.Pair>exists(properties, _function_4);
                          if (_exists_1) {
                            suspect = this.createTextAreaField(type, it);
                          } else {
                            final Function1<AutowireUtil.Pair, Boolean> _function_5 = (AutowireUtil.Pair it_1) -> {
                              return Boolean.valueOf(it_1.key.equalsIgnoreCase(ILayoutingStrategy.PROPERTY_ORGANIZATION));
                            };
                            boolean _exists_2 = IterableExtensions.<AutowireUtil.Pair>exists(properties, _function_5);
                            if (_exists_2) {
                              suspect = this.createOrganizationComboBox(type, it);
                            } else {
                              final Function1<AutowireUtil.Pair, Boolean> _function_6 = (AutowireUtil.Pair it_1) -> {
                                return Boolean.valueOf(it_1.key.equalsIgnoreCase(ILayoutingStrategy.PROPERTY_PERSPECTIVE));
                              };
                              boolean _exists_3 = IterableExtensions.<AutowireUtil.Pair>exists(properties, _function_6);
                              if (_exists_3) {
                                suspect = this.createPerspectiveComboBox(type, it);
                              } else {
                                final Function1<AutowireUtil.Pair, Boolean> _function_7 = (AutowireUtil.Pair it_1) -> {
                                  return Boolean.valueOf(it_1.key.equalsIgnoreCase(ILayoutingStrategy.PROPERTY_PRINTSERVICE));
                                };
                                boolean _exists_4 = IterableExtensions.<AutowireUtil.Pair>exists(properties, _function_7);
                                if (_exists_4) {
                                  suspect = this.createPrintServiceComboBox(type, it);
                                } else {
                                  final Function1<AutowireUtil.Pair, Boolean> _function_8 = (AutowireUtil.Pair it_1) -> {
                                    return Boolean.valueOf(it_1.key.equalsIgnoreCase(ILayoutingStrategy.PROPERTY_THEME));
                                  };
                                  boolean _exists_5 = IterableExtensions.<AutowireUtil.Pair>exists(properties, _function_8);
                                  if (_exists_5) {
                                    suspect = this.createThemeComboBox(type, it);
                                  } else {
                                    final Function1<AutowireUtil.Pair, Boolean> _function_9 = (AutowireUtil.Pair it_1) -> {
                                      return Boolean.valueOf(it_1.key.equalsIgnoreCase(functionImagePicker));
                                    };
                                    boolean _exists_6 = IterableExtensions.<AutowireUtil.Pair>exists(properties, _function_9);
                                    if (_exists_6) {
                                      suspect = this.createIconComboBox(type, it);
                                    } else {
                                      suspect = this.createTextField(type, it);
                                    }
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            } else {
              boolean _isDate = this._typeHelper.isDate(type);
              if (_isDate) {
                suspect = this.createDateField(type, it);
              } else {
                boolean _isEnum = this._typeHelper.isEnum(type);
                if (_isEnum) {
                  final Function1<AutowireUtil.Pair, Boolean> _function_10 = (AutowireUtil.Pair it_1) -> {
                    return Boolean.valueOf(it_1.key.toLowerCase().equals(ILayoutingStrategy.PROPERTY_OPTION_GROUP));
                  };
                  boolean _exists_7 = IterableExtensions.<AutowireUtil.Pair>exists(properties, _function_10);
                  if (_exists_7) {
                    suspect = this.createEnumOptionsGroup(type, it);
                  } else {
                    suspect = this.createEnumComboBox(type, it);
                  }
                } else {
                  boolean _isByteArray = this.isByteArray(type);
                  if (_isByteArray) {
                    final Function1<AutowireUtil.Pair, Boolean> _function_11 = (AutowireUtil.Pair it_1) -> {
                      return Boolean.valueOf(it_1.key.equals(ILayoutingStrategy.PROPERTY_KEY__FIELD_TYPE));
                    };
                    AutowireUtil.Pair _findFirst_2 = IterableExtensions.<AutowireUtil.Pair>findFirst(properties, _function_11);
                    String _value_2 = null;
                    if (_findFirst_2!=null) {
                      _value_2=_findFirst_2.value;
                    }
                    final String fieldType_1 = _value_2;
                    if (((!StringExtensions.isNullOrEmpty(fieldType_1)) && fieldType_1.equals(ILayoutingStrategy.PROPERTY_RICH_TEXT))) {
                      suspect = this.createRichTextField(type, it);
                    } else {
                      suspect = this.createBlopUploadComponent(type, it);
                    }
                  } else {
                    boolean _isDomainReference = this._typeHelper.isDomainReference(it);
                    if (_isDomainReference) {
                      suspect = this.createBeanReferenceField(type, it);
                    } else {
                      if (((it.getField() != null) && this._typeHelper.isCollection(it.getField()))) {
                        final Function1<AutowireUtil.Pair, Boolean> _function_12 = (AutowireUtil.Pair it_1) -> {
                          return Boolean.valueOf(it_1.key.toLowerCase().equals(ILayoutingStrategy.PROPERTY_GRID));
                        };
                        boolean _exists_8 = IterableExtensions.<AutowireUtil.Pair>exists(properties, _function_12);
                        if (_exists_8) {
                          suspect = this.createGrid(type, it);
                        } else {
                          final Function1<AutowireUtil.Pair, Boolean> _function_13 = (AutowireUtil.Pair it_1) -> {
                            return Boolean.valueOf(it_1.key.equalsIgnoreCase(ILayoutingStrategy.PROPERTY_TABLE));
                          };
                          boolean _exists_9 = IterableExtensions.<AutowireUtil.Pair>exists(properties, _function_13);
                          if (_exists_9) {
                            suspect = this.createTableField(type, it);
                          }
                        }
                      } else {
                        boolean _isDto = this.isDto(type);
                        if (_isDto) {
                          suspect = this.createDtoSuspect(type, it);
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
      if ((parentSuspect == null)) {
        this.completeSuspect(type, it, suspect, dtoType);
      } else {
        this.completeSuspect(type, it, suspect, parentSuspect, dtoType);
      }
      for (final AutowireUtil.Pair keyAndValue : properties) {
        if ((suspect != null)) {
          suspect.getProperties().put(keyAndValue.key.toLowerCase(), keyAndValue.value);
        }
      }
    };
    opInfoMap.values().forEach(_function);
  }
  
  public void createAuthorizationVisibilityProcessor(final YAuthorizationable element, final OperationExtensions.OperationInfo info) {
    JvmField _field = info.getField();
    boolean _tripleNotEquals = (_field != null);
    if (_tripleNotEquals) {
      EObject _eContainer = info.getField().eContainer();
      final JvmGenericType type = ((JvmGenericType) _eContainer);
      if (((!this._autowireUtil.isClass(info.getGetter().getReturnType().getType())) && this._autowireUtil.isAllowed(info.getGetter().getReturnType().getType(), type, info))) {
        element.setAuthorizationGroup(this._iQualifiedNameProvider.getFullyQualifiedName(type).toString());
        element.setAuthorizationId(info.getField().getSimpleName());
      }
    }
  }
  
  public YSuspect createDtoSuspect(final JvmType type, final OperationExtensions.OperationInfo info) {
    final YTypedCompoundSuspect dtoSuspect = YECviewFactory.eINSTANCE.createYTypedCompoundSuspect();
    EList<String> _tags = dtoSuspect.getTags();
    _tags.add(ILayoutingStrategy.TAG__DTO);
    if ((type instanceof JvmDeclaredType)) {
      this.createSuspectStructure(((JvmDeclaredType)type), 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>
   */
  public YSuspect createSubTypeDtoSuspect(final JvmDeclaredType subDtoJvmType) {
    final YSubTypeSuspect subTypeSuspect = YECviewFactory.eINSTANCE.createYSubTypeSuspect();
    EList<String> _tags = subTypeSuspect.getTags();
    _tags.add(ILayoutingStrategy.TAG__SUBTYPE);
    subTypeSuspect.setTypeQualifiedName(subDtoJvmType.getQualifiedName());
    subTypeSuspect.setType(this.computer.loadClass(this.uiLayout.eResource().getResourceSet(), subTypeSuspect.getTypeQualifiedName()));
    final YView view = this.computer.getCurrentView();
    final YDetailBeanSlot detailSlot = view.addDetailBeanSlot(subTypeSuspect.getTypeQualifiedName(), subTypeSuspect.getType(), 
      this.yMainBeanslot, "");
    EList<String> _tags_1 = detailSlot.getTags();
    _tags_1.add(ILayoutingStrategy.TAG__SUBTYPE);
    subTypeSuspect.setBeanSlot(detailSlot);
    this.layouter.add(subTypeSuspect);
    this.layouter.pushHierarchy(subTypeSuspect);
    final LinkedList<Map<String, OperationExtensions.OperationInfo>> subTypeInfos = this.createSortedMapList(OperationExtensions.getOperationInfos(subDtoJvmType, false));
    this.createSuspectStructure(subTypeInfos, subDtoJvmType, this.mobile, subTypeSuspect);
    this.layouter.popHierarchy();
    return subTypeSuspect;
  }
  
  /**
   * Returns true, if the type is a dto.
   */
  public boolean isDto(final JvmType type) {
    final SuperTypeCollector collector = new SuperTypeCollector();
    final Set<String> superTypes = collector.collectSuperTypeNames(type);
    return superTypes.contains(IDto.class.getName());
  }
  
  public void completeSuspect(final JvmType type, final OperationExtensions.OperationInfo info, final YSuspect suspect, final JvmType parentType) {
    if ((suspect != null)) {
      StringConcatenation _builder = new StringConcatenation();
      String _generateId = this._autowireUtil.generateId(this.uiLayout);
      _builder.append(_generateId);
      _builder.append(".");
      String _name = info.getName();
      _builder.append(_name);
      suspect.setId(_builder.toString());
      boolean _isReadonly = info.isReadonly();
      if (_isReadonly) {
        EList<String> _tags = suspect.getTags();
        _tags.add("readonly");
      }
      boolean _isOnKanbanCard = this.isOnKanbanCard(info);
      if (_isOnKanbanCard) {
        EList<String> _tags_1 = suspect.getTags();
        _tags_1.add("onKanbanCard");
      }
      boolean _isUniqueEntry = this.isUniqueEntry(info);
      if (_isUniqueEntry) {
        EList<String> _tags_2 = suspect.getTags();
        _tags_2.add("unique");
        String[] splittedId = info.getId().split(":");
        int _length = splittedId.length;
        boolean _greaterThan = (_length > 1);
        if (_greaterThan) {
          String fqClassName = splittedId[0];
          suspect.getProperties().put("class", fqClassName);
        }
        suspect.getProperties().put("name", info.getName());
        this.createModelValueContainerBinding(suspect, info.getName(), type, "value");
      }
      boolean _isValidationConstraint = this.isValidationConstraint(info);
      if (_isValidationConstraint) {
        EList<String> _tags_3 = suspect.getTags();
        _tags_3.add("constraint");
        String[] splittedId_1 = info.getId().split(":");
        int _length_1 = splittedId_1.length;
        boolean _greaterThan_1 = (_length_1 > 1);
        if (_greaterThan_1) {
          String fqClassName_1 = splittedId_1[0];
          suspect.getProperties().put("class", fqClassName_1);
        }
        suspect.getProperties().put("name", info.getName());
      }
      this.layouter.add(suspect);
      if (((info.getField() != null) && this._typeHelper.isCollection(info.getField()))) {
        this.createModelListBinding(suspect, info, type, "list");
      } else {
        this.createModelValueBinding(suspect, info.getName(), type, "value", parentType);
      }
      if ((suspect instanceof YTypedCompoundSuspect)) {
        final YBindingEndpoint masterValueEP = ((YTypedCompoundSuspect)suspect).getValueBindingEndpoints().get(0);
        boolean _isEmpty = ((YTypedCompoundSuspect)suspect).getValueBindingEndpoints().isEmpty();
        boolean _not = (!_isEmpty);
        if (_not) {
          EList<YSuspect> _children = ((YTypedCompoundSuspect)suspect).getChildren();
          for (final YSuspect child : _children) {
            {
              String _id = ((YTypedCompoundSuspect)suspect).getId();
              String _id_1 = child.getId();
              String _plus = (_id + _id_1);
              child.setId(_plus);
              boolean _isEmpty_1 = child.getValueBindingEndpoints().isEmpty();
              boolean _not_1 = (!_isEmpty_1);
              if (_not_1) {
                final YBindingEndpoint childValueEP = child.getValueBindingEndpoints().get(0);
                if ((childValueEP instanceof YDetailValueBindingEndpoint)) {
                  YBindingEndpoint _copy = EcoreUtil.<YBindingEndpoint>copy(masterValueEP);
                  ((YDetailValueBindingEndpoint)childValueEP).setMasterObservable(((YValueBindingEndpoint) _copy));
                }
              }
            }
          }
        }
      }
      this.createAuthorizationVisibilityProcessor(suspect, info);
    }
  }
  
  public void completeSuspect(final JvmType type, final OperationExtensions.OperationInfo info, final YSuspect suspect, final YTypedCompoundSuspect parentSuspect, final JvmType parentType) {
    if ((suspect != null)) {
      StringConcatenation _builder = new StringConcatenation();
      String _id = parentSuspect.getId();
      _builder.append(_id);
      _builder.append(".");
      String _name = info.getName();
      _builder.append(_name);
      suspect.setId(_builder.toString());
      boolean _isReadonly = info.isReadonly();
      if (_isReadonly) {
        EList<String> _tags = suspect.getTags();
        _tags.add("readonly");
      }
      boolean _isValidationConstraint = this.isValidationConstraint(info);
      if (_isValidationConstraint) {
        EList<String> _tags_1 = suspect.getTags();
        _tags_1.add("constraint");
        String[] splittedId = info.getId().split(":");
        int _length = splittedId.length;
        boolean _greaterThan = (_length > 1);
        if (_greaterThan) {
          String fqClassName = splittedId[0];
          suspect.getProperties().put("class", fqClassName);
        }
        suspect.getProperties().put("name", info.getName());
      }
      parentSuspect.getChildren().add(suspect);
      if (((info.getField() != null) && this._typeHelper.isCollection(info.getField()))) {
        this.createModelListBinding(suspect, info, type, "list");
      } else {
        this.createModelValueBinding(suspect, info.getName(), type, "value", parentType);
      }
      this.createAuthorizationVisibilityProcessor(suspect, info);
    }
  }
  
  /**
   * Sorted the attributes with the primitive types first and the rest after. Also all collections were left out.
   */
  public LinkedHashMap<String, OperationExtensions.OperationInfo> createSortedOpInfoMapForCollections(final Map<String, OperationExtensions.OperationInfo> opInfoMap) {
    LinkedHashMap<String, OperationExtensions.OperationInfo> _xblockexpression = null;
    {
      final LinkedHashMap<String, OperationExtensions.OperationInfo> sortedOpInfoList = CollectionLiterals.<String, OperationExtensions.OperationInfo>newLinkedHashMap();
      final LinkedHashMap<String, OperationExtensions.OperationInfo> nonPrimitiveOpInfoMap = CollectionLiterals.<String, OperationExtensions.OperationInfo>newLinkedHashMap();
      final BiConsumer<String, OperationExtensions.OperationInfo> _function = (String key, OperationExtensions.OperationInfo opInfo) -> {
        JvmType detailType = null;
        if (((opInfo.getField() != null) && (!this._typeHelper.isCollection(opInfo.getField())))) {
          detailType = opInfo.getGetter().getReturnType().getType();
          final boolean isPrimitive = ((detailType instanceof JvmPrimitiveType) || detailType.getQualifiedName().equals(
            String.class.getName()));
          if (isPrimitive) {
            sortedOpInfoList.put(key, opInfo);
          } else {
            nonPrimitiveOpInfoMap.put(key, opInfo);
          }
        }
      };
      opInfoMap.forEach(_function);
      sortedOpInfoList.putAll(nonPrimitiveOpInfoMap);
      _xblockexpression = sortedOpInfoList;
    }
    return _xblockexpression;
  }
  
  /**
   * Sorted the attributes in a individual but fix order.
   */
  public LinkedList<Map<String, OperationExtensions.OperationInfo>> createSortedMapList(final Map<String, OperationExtensions.OperationInfo> opInfoMap) {
    LinkedList<Map<String, OperationExtensions.OperationInfo>> _xblockexpression = null;
    {
      final LinkedList<Map<String, OperationExtensions.OperationInfo>> sortedOpInfoList = CollectionLiterals.<Map<String, OperationExtensions.OperationInfo>>newLinkedList();
      sortedOpInfoList.add(opInfoMap);
      _xblockexpression = sortedOpInfoList;
    }
    return _xblockexpression;
  }
  
  public boolean isDomainKey(final OperationExtensions.OperationInfo info) {
    if (((info != null) && (info.getField() != null))) {
      EList<JvmAnnotationReference> _annotations = info.getField().getAnnotations();
      for (final JvmAnnotationReference annotationRefs : _annotations) {
        boolean _equals = DomainKey.class.getCanonicalName().equals(annotationRefs.getAnnotation().getIdentifier());
        if (_equals) {
          return true;
        }
      }
    }
    return false;
  }
  
  public boolean isOnKanbanCard(final OperationExtensions.OperationInfo info) {
    if (((info != null) && (info.getField() != null))) {
      EList<JvmAnnotationReference> _annotations = info.getField().getAnnotations();
      for (final JvmAnnotationReference annotationRefs : _annotations) {
        boolean _equals = OnKanbanCard.class.getCanonicalName().equals(annotationRefs.getAnnotation().getIdentifier());
        if (_equals) {
          return true;
        }
      }
    }
    return false;
  }
  
  public boolean isDomainDescription(final OperationExtensions.OperationInfo info) {
    if (((info != null) && (info.getField() != null))) {
      EList<JvmAnnotationReference> _annotations = info.getField().getAnnotations();
      for (final JvmAnnotationReference annotationRefs : _annotations) {
        boolean _equals = DomainDescription.class.getCanonicalName().equals(annotationRefs.getAnnotation().getIdentifier());
        if (_equals) {
          return true;
        }
      }
    }
    return false;
  }
  
  public boolean isValidationConstraint(final OperationExtensions.OperationInfo info) {
    if (((info != null) && (info.getField() != null))) {
      EList<JvmAnnotationReference> _annotations = info.getField().getAnnotations();
      for (final JvmAnnotationReference annotationRefs : _annotations) {
        if (((annotationRefs.getAnnotation().getIdentifier() != null) && 
          annotationRefs.getAnnotation().getIdentifier().equals(Valid.class.getCanonicalName()))) {
          return true;
        }
      }
    }
    return false;
  }
  
  public boolean isUniqueEntry(final OperationExtensions.OperationInfo info) {
    if (((info != null) && (info.getField() != null))) {
      EList<JvmAnnotationReference> _annotations = info.getField().getAnnotations();
      for (final JvmAnnotationReference annotationRefs : _annotations) {
        if (((annotationRefs.getAnnotation().getIdentifier() != null) && 
          annotationRefs.getAnnotation().getIdentifier().equals(UniqueEntry.class.getCanonicalName()))) {
          return true;
        }
      }
    }
    return false;
  }
  
  public boolean isIndex(final OperationExtensions.OperationInfo info) {
    if (((info != null) && (info.getField() != null))) {
      EList<JvmAnnotationReference> _annotations = info.getField().getAnnotations();
      for (final JvmAnnotationReference annotationRefs : _annotations) {
        boolean _equals = DomainKey.class.getCanonicalName().equals(annotationRefs.getAnnotation().getIdentifier());
        if (_equals) {
          return true;
        }
      }
    }
    return false;
  }
  
  /**
   * Returns true, if the type is boolean
   * 
   * @param type
   * @return
   */
  public boolean isByteArray(final JvmType type) {
    if ((type == null)) {
      return false;
    }
    if ((this.isArray(type, Byte.class) || this.isArray(type, Byte.TYPE))) {
      return true;
    }
    return false;
  }
  
  public boolean isArray(final JvmType type, final Class<?> clazz) {
    if ((type == null)) {
      return false;
    }
    String className = clazz.getName();
    char _charAt = className.charAt(0);
    boolean _equals = Objects.equal(Character.valueOf(_charAt), "[");
    if (_equals) {
      className = clazz.getCanonicalName();
    }
    className = className.concat("[]");
    boolean result = className.equals(type.getIdentifier());
    return result;
  }
  
  public YTypedSuspect createTextField(final JvmType type, final OperationExtensions.OperationInfo info) {
    YTypedSuspect _xblockexpression = null;
    {
      final YTypedSuspect suspect = YECviewFactory.eINSTANCE.createYTypedSuspect();
      EList<String> _tags = suspect.getTags();
      _tags.add(ILayoutingStrategy.TAG__TEXT);
      suspect.setType(this.computer.loadClass(this.uiLayout.eResource().getResourceSet(), type.getQualifiedName()));
      suspect.setTypeQualifiedName(type.getQualifiedName());
      _xblockexpression = suspect;
    }
    return _xblockexpression;
  }
  
  public YTypedSuspect createSuggestTextField(final JvmType type, final OperationExtensions.OperationInfo info, final Map<String, OperationExtensions.OperationInfo> opInfoMap) {
    YTypedSuspect _xblockexpression = null;
    {
      final OperationExtensions.OperationInfo idAttInfo = this.getToIdInfo(opInfoMap.values());
      if ((idAttInfo == null)) {
        return this.createTextField(type, info);
      }
      final YTypedSuspect suspect = YECviewFactory.eINSTANCE.createYTypedSuspect();
      EList<String> _tags = suspect.getTags();
      _tags.add(ILayoutingStrategy.TAG__SUGGEST_TEXT);
      suspect.setType(this.computer.loadClass(this.uiLayout.eResource().getResourceSet(), this.beanType.getQualifiedName()));
      suspect.setTypeQualifiedName(this.beanType.getQualifiedName());
      suspect.getProperties().put(ILayoutingStrategy.PROPERTY__ITEM_CAPTION, info.getName());
      suspect.getProperties().put(ILayoutingStrategy.PROPERTY__ITEM_FILTER, info.getName());
      suspect.getProperties().put(ILayoutingStrategy.PROPERTY__ITEM_UUID, idAttInfo.getName());
      _xblockexpression = suspect;
    }
    return _xblockexpression;
  }
  
  /**
   * Returns the operation info for the id property.
   */
  public OperationExtensions.OperationInfo getToIdInfo(final Collection<OperationExtensions.OperationInfo> infos) {
    for (final OperationExtensions.OperationInfo info : infos) {
      boolean _isIdOrUUID = info.isIdOrUUID();
      if (_isIdOrUUID) {
        return info;
      }
    }
    return null;
  }
  
  public YTypedSuspect createTextAreaField(final JvmType type, final OperationExtensions.OperationInfo info) {
    YTypedSuspect _xblockexpression = null;
    {
      final YTypedSuspect suspect = YECviewFactory.eINSTANCE.createYTypedSuspect();
      EList<String> _tags = suspect.getTags();
      _tags.add(ILayoutingStrategy.TAG__TEXTAREA);
      suspect.setType(this.computer.loadClass(this.uiLayout.eResource().getResourceSet(), type.getQualifiedName()));
      suspect.setTypeQualifiedName(type.getQualifiedName());
      _xblockexpression = suspect;
    }
    return _xblockexpression;
  }
  
  public YTypedSuspect createDecimalField(final JvmType type, final OperationExtensions.OperationInfo info) {
    YTypedSuspect _xblockexpression = null;
    {
      final YTypedSuspect suspect = YECviewFactory.eINSTANCE.createYTypedSuspect();
      EList<String> _tags = suspect.getTags();
      _tags.add(ILayoutingStrategy.TAG__DECIMAL);
      suspect.setType(this.computer.loadClass(this.uiLayout.eResource().getResourceSet(), type.getQualifiedName()));
      suspect.setTypeQualifiedName(type.getQualifiedName());
      _xblockexpression = suspect;
    }
    return _xblockexpression;
  }
  
  public YTypedSuspect createNumberField(final JvmType type, final OperationExtensions.OperationInfo info) {
    YTypedSuspect _xblockexpression = null;
    {
      final YTypedSuspect suspect = YECviewFactory.eINSTANCE.createYTypedSuspect();
      EList<String> _tags = suspect.getTags();
      _tags.add(ILayoutingStrategy.TAG__NUMBER);
      suspect.setType(this.computer.loadClass(this.uiLayout.eResource().getResourceSet(), type.getQualifiedName()));
      suspect.setTypeQualifiedName(type.getQualifiedName());
      _xblockexpression = suspect;
    }
    return _xblockexpression;
  }
  
  public YTypedSuspect createCheckbox(final JvmType type, final OperationExtensions.OperationInfo info) {
    YTypedSuspect _xblockexpression = null;
    {
      final YTypedSuspect suspect = YECviewFactory.eINSTANCE.createYTypedSuspect();
      EList<String> _tags = suspect.getTags();
      _tags.add(ILayoutingStrategy.TAG__BOOLEAN);
      suspect.setType(this.computer.loadClass(this.uiLayout.eResource().getResourceSet(), type.getQualifiedName()));
      suspect.setTypeQualifiedName(type.getQualifiedName());
      _xblockexpression = suspect;
    }
    return _xblockexpression;
  }
  
  public YTypedSuspect createDateField(final JvmType type, final OperationExtensions.OperationInfo info) {
    YTypedSuspect _xblockexpression = null;
    {
      final YTypedSuspect suspect = YECviewFactory.eINSTANCE.createYTypedSuspect();
      EList<String> _tags = suspect.getTags();
      _tags.add(ILayoutingStrategy.TAG__DATE);
      suspect.setType(this.computer.loadClass(this.uiLayout.eResource().getResourceSet(), type.getQualifiedName()));
      suspect.setTypeQualifiedName(type.getQualifiedName());
      _xblockexpression = suspect;
    }
    return _xblockexpression;
  }
  
  public YTypedSuspect createIconComboBox(final JvmType type, final OperationExtensions.OperationInfo info) {
    YTypedSuspect _xblockexpression = null;
    {
      final YTypedSuspect suspect = YECviewFactory.eINSTANCE.createYTypedSuspect();
      EList<String> _tags = suspect.getTags();
      _tags.add(ILayoutingStrategy.TAG__IMAGE_PICKER);
      suspect.setType(this.computer.loadClass(this.uiLayout.eResource().getResourceSet(), type.getQualifiedName()));
      suspect.setTypeQualifiedName(type.getQualifiedName());
      _xblockexpression = suspect;
    }
    return _xblockexpression;
  }
  
  public YTypedSuspect createEnumComboBox(final JvmType type, final OperationExtensions.OperationInfo info) {
    YTypedSuspect _xblockexpression = null;
    {
      final YTypedSuspect suspect = YECviewFactory.eINSTANCE.createYTypedSuspect();
      EList<String> _tags = suspect.getTags();
      _tags.add(ILayoutingStrategy.TAG__ENUM_COMBO);
      suspect.setType(this.computer.loadClass(this.uiLayout.eResource().getResourceSet(), type.getQualifiedName()));
      suspect.setTypeQualifiedName(type.getQualifiedName());
      boolean _isReadonly = info.isReadonly();
      if (_isReadonly) {
        EList<String> _tags_1 = suspect.getTags();
        _tags_1.add("readonly");
      }
      _xblockexpression = suspect;
    }
    return _xblockexpression;
  }
  
  public YTypedSuspect createOrganizationComboBox(final JvmType type, final OperationExtensions.OperationInfo info) {
    YTypedSuspect _xblockexpression = null;
    {
      final YTypedSuspect suspect = YECviewFactory.eINSTANCE.createYTypedSuspect();
      EList<String> _tags = suspect.getTags();
      _tags.add(ILayoutingStrategy.TAG__ORGANIZATION_COMBO);
      suspect.setType(String.class);
      suspect.setTypeQualifiedName(String.class.getName());
      boolean _isReadonly = info.isReadonly();
      if (_isReadonly) {
        EList<String> _tags_1 = suspect.getTags();
        _tags_1.add("readonly");
      }
      _xblockexpression = suspect;
    }
    return _xblockexpression;
  }
  
  public YTypedSuspect createPerspectiveComboBox(final JvmType type, final OperationExtensions.OperationInfo info) {
    YTypedSuspect _xblockexpression = null;
    {
      final YTypedSuspect suspect = YECviewFactory.eINSTANCE.createYTypedSuspect();
      EList<String> _tags = suspect.getTags();
      _tags.add(ILayoutingStrategy.TAG__PERSPECTIVE_COMBO);
      suspect.setType(String.class);
      suspect.setTypeQualifiedName(String.class.getName());
      boolean _isReadonly = info.isReadonly();
      if (_isReadonly) {
        EList<String> _tags_1 = suspect.getTags();
        _tags_1.add("readonly");
      }
      _xblockexpression = suspect;
    }
    return _xblockexpression;
  }
  
  public YTypedSuspect createThemeComboBox(final JvmType type, final OperationExtensions.OperationInfo info) {
    YTypedSuspect _xblockexpression = null;
    {
      final YTypedSuspect suspect = YECviewFactory.eINSTANCE.createYTypedSuspect();
      EList<String> _tags = suspect.getTags();
      _tags.add(ILayoutingStrategy.TAG__THEME_COMBO);
      suspect.setType(String.class);
      suspect.setTypeQualifiedName(String.class.getName());
      boolean _isReadonly = info.isReadonly();
      if (_isReadonly) {
        EList<String> _tags_1 = suspect.getTags();
        _tags_1.add("readonly");
      }
      _xblockexpression = suspect;
    }
    return _xblockexpression;
  }
  
  public YTypedSuspect createPrintServiceComboBox(final JvmType type, final OperationExtensions.OperationInfo info) {
    YTypedSuspect _xblockexpression = null;
    {
      final YTypedSuspect suspect = YECviewFactory.eINSTANCE.createYTypedSuspect();
      EList<String> _tags = suspect.getTags();
      _tags.add(ILayoutingStrategy.TAG__PRINTSERVICE_COMBO);
      suspect.setType(String.class);
      suspect.setTypeQualifiedName(String.class.getName());
      boolean _isReadonly = info.isReadonly();
      if (_isReadonly) {
        EList<String> _tags_1 = suspect.getTags();
        _tags_1.add("readonly");
      }
      _xblockexpression = suspect;
    }
    return _xblockexpression;
  }
  
  public YTypedSuspect createEnumOptionsGroup(final JvmType type, final OperationExtensions.OperationInfo info) {
    YTypedSuspect _xblockexpression = null;
    {
      final YTypedSuspect suspect = YECviewFactory.eINSTANCE.createYTypedSuspect();
      EList<String> _tags = suspect.getTags();
      _tags.add(ILayoutingStrategy.TAG__ENUM_OPTIONS);
      suspect.setType(this.computer.loadClass(this.uiLayout.eResource().getResourceSet(), type.getQualifiedName()));
      suspect.setTypeQualifiedName(type.getQualifiedName());
      StringConcatenation _builder = new StringConcatenation();
      String _generateId = this._autowireUtil.generateId(this.uiLayout);
      _builder.append(_generateId);
      _builder.append(".");
      String _name = info.getName();
      _builder.append(_name);
      suspect.setId(_builder.toString());
      boolean _isReadonly = info.isReadonly();
      if (_isReadonly) {
        EList<String> _tags_1 = suspect.getTags();
        _tags_1.add("readonly");
      }
      _xblockexpression = suspect;
    }
    return _xblockexpression;
  }
  
  public YTypedSuspect createBeanReferenceField(final JvmType type, final OperationExtensions.OperationInfo info) {
    YTypedSuspect _xblockexpression = null;
    {
      YTypedSuspect suspect = null;
      Class<?> suspectType = this.computer.loadClass(this.uiLayout.eResource().getResourceSet(), type.getQualifiedName());
      String captionProperty = BeanHelper.findCaptionProperty(suspectType);
      String captionDescription = BeanHelper.findDescriptionProperty(suspectType);
      if (((captionProperty != null) || (captionDescription != null))) {
        suspect = YECviewFactory.eINSTANCE.createYTypedSuspect();
        suspect.setType(suspectType);
        EList<String> _tags = suspect.getTags();
        _tags.add(ILayoutingStrategy.TAG__BEAN_REFERENCE);
        StringConcatenation _builder = new StringConcatenation();
        String _generateId = this._autowireUtil.generateId(this.uiLayout);
        _builder.append(_generateId);
        _builder.append(".");
        String _name = info.getName();
        _builder.append(_name);
        suspect.setId(_builder.toString());
        boolean _isReadonly = info.isReadonly();
        if (_isReadonly) {
          EList<String> _tags_1 = suspect.getTags();
          _tags_1.add("readonly");
        }
        boolean _hasAnnotation = info.hasAnnotation(FilterDepth.class);
        if (_hasAnnotation) {
          final int depth = this._autowireUtil.toFilterDepth(info.getField());
          suspect.getProperties().put(ILayoutingStrategy.PROPERTY__FILTER_DEPTH, Integer.toString(depth));
        }
        suspect.setTypeQualifiedName(type.getQualifiedName());
        suspect.getProperties().put(ILayoutingStrategy.PROPERTY__ITEM_CAPTION, captionProperty);
        suspect.getProperties().put(ILayoutingStrategy.PROPERTY__ITEM_DESCRIPTION, captionDescription);
      }
      _xblockexpression = suspect;
    }
    return _xblockexpression;
  }
  
  public YTypedSuspect createTableField(final JvmType type, final OperationExtensions.OperationInfo info) {
    return this.createCollection(type, info, ILayoutingStrategy.TAG__TABLE);
  }
  
  public YTypedSuspect createGrid(final JvmType type, final OperationExtensions.OperationInfo info) {
    return this.createCollection(type, info, ILayoutingStrategy.TAG__GRID);
  }
  
  public YTypedSuspect createCollection(final JvmType type, final OperationExtensions.OperationInfo info, final String tag) {
    YCollectionSuspect _xblockexpression = null;
    {
      final YCollectionSuspect suspect = YECviewFactory.eINSTANCE.createYCollectionSuspect();
      JvmTypeReference _returnType = info.getGetter().getReturnType();
      final JvmParameterizedTypeReference collectionType = ((JvmParameterizedTypeReference) _returnType);
      final JvmTypeReference typeInCollection = collectionType.getArguments().get(0);
      suspect.setType(this.computer.loadClass(this.uiLayout.eResource().getResourceSet(), typeInCollection.getType().getQualifiedName()));
      EList<String> _tags = suspect.getTags();
      _tags.add(tag);
      suspect.setTypeQualifiedName(typeInCollection.getType().getQualifiedName());
      JvmType _type = typeInCollection.getType();
      if ((_type instanceof JvmDeclaredType)) {
        JvmType _type_1 = typeInCollection.getType();
        final JvmDeclaredType castedType = ((JvmDeclaredType) _type_1);
        final Map<String, List<AutowireUtil.Pair>> propMap = this._autowireUtil.toFieldProperties(castedType);
        final Map<String, OperationExtensions.OperationInfo> opInfoMap = OperationExtensions.getOperationInfos(castedType);
        final LinkedHashMap<String, OperationExtensions.OperationInfo> sortedOpInfoMap = this.createSortedOpInfoMapForCollections(opInfoMap);
        final Consumer<OperationExtensions.OperationInfo> _function = (OperationExtensions.OperationInfo it) -> {
          JvmType detailType = it.getGetter().getReturnType().getType();
          YColumnInfo columnInfo = null;
          final boolean isPrimitive = (detailType instanceof JvmPrimitiveType);
          boolean _isDomainReference = this._typeHelper.isDomainReference(it);
          if (_isDomainReference) {
            Collection<JvmTypeProperties.Info> _values = JvmTypeProperties.getOperationInfos(((JvmDeclaredType) detailType)).values();
            for (final JvmTypeProperties.Info nestedInfo : _values) {
              boolean _hasAnnotation = nestedInfo.hasAnnotation(DomainKey.class);
              if (_hasAnnotation) {
                final Map<String, List<AutowireUtil.Pair>> nestPropMap = this._autowireUtil.toFieldProperties(((JvmDeclaredType) detailType));
                columnInfo = this.createYColumnInfo(nestedInfo.getType());
                String _simpleName = it.getField().getSimpleName();
                String _plus = (_simpleName + ".");
                String _attributePath = nestedInfo.getAttributePath();
                String _plus_1 = (_plus + _attributePath);
                columnInfo.setName(_plus_1);
                List<AutowireUtil.Pair> propList = nestPropMap.get(nestedInfo.getName());
                this.setYColumnInfoProperties(columnInfo, propList);
              }
            }
          } else {
            if ((((!it.isIdOrUUID()) && (!it.isVersion())) && (!it.isDirtyMark()))) {
              JvmType objectType = it.getField().getType().getType();
              if (isPrimitive) {
                final String primitiveTypeName = it.getField().getType().getType().getQualifiedName();
                JvmVoid _createJvmVoid = TypesFactory.eINSTANCE.createJvmVoid();
                final InternalEObject proxy = ((InternalEObject) _createJvmVoid);
                proxy.eSetProxyURI(URI.createURI(this.toObjectProxy(primitiveTypeName)));
                EObject _resolve = EcoreUtil.resolve(proxy, this.uiLayout.eResource());
                objectType = ((JvmType) _resolve);
              }
              columnInfo = this.createYColumnInfo(objectType);
              columnInfo.setName(it.getName());
              List<AutowireUtil.Pair> propList_1 = propMap.get(it.getField().getIdentifier());
              this.setYColumnInfoProperties(columnInfo, propList_1);
            }
          }
          if ((columnInfo != null)) {
            columnInfo.setLabelI18nKey(columnInfo.getName());
            EList<YColumnInfo> _columns = suspect.getColumns();
            _columns.add(columnInfo);
          }
        };
        sortedOpInfoMap.values().forEach(_function);
      }
      _xblockexpression = suspect;
    }
    return _xblockexpression;
  }
  
  /**
   * Creates a proxy object
   */
  public String toObjectProxy(final String primitiveTypeName) {
    if (primitiveTypeName != null) {
      switch (primitiveTypeName) {
        case "int":
          StringConcatenation _builder = new StringConcatenation();
          _builder.append("java:/Objects/java.lang.Integer#java.lang.Integer");
          return _builder.toString();
        default:
          StringConcatenation _builder_1 = new StringConcatenation();
          _builder_1.append("java:/Objects/java.lang.");
          String _firstUpper = StringExtensions.toFirstUpper(primitiveTypeName);
          _builder_1.append(_firstUpper);
          _builder_1.append("#java.lang.");
          String _firstUpper_1 = StringExtensions.toFirstUpper(primitiveTypeName);
          _builder_1.append(_firstUpper_1);
          return _builder_1.toString();
      }
    } else {
      StringConcatenation _builder_1 = new StringConcatenation();
      _builder_1.append("java:/Objects/java.lang.");
      String _firstUpper = StringExtensions.toFirstUpper(primitiveTypeName);
      _builder_1.append(_firstUpper);
      _builder_1.append("#java.lang.");
      String _firstUpper_1 = StringExtensions.toFirstUpper(primitiveTypeName);
      _builder_1.append(_firstUpper_1);
      return _builder_1.toString();
    }
  }
  
  public void createMobileSwitch(final JvmType type, final OperationExtensions.OperationInfo info) {
    final VMSwitch yField = this.vFactory.createVMSwitch();
    boolean _isReadonly = info.isReadonly();
    boolean _not = (!_isReadonly);
    yField.setInitialEnabled(_not);
    yField.setLabel(info.getName());
    this.layouter.add(yField);
    this.createBinding(yField, info, type, "value");
  }
  
  public YSuspect createRichTextField(final JvmType type, final OperationExtensions.OperationInfo info) {
    YTypedSuspect _xblockexpression = null;
    {
      final YTypedSuspect suspect = YECviewFactory.eINSTANCE.createYTypedSuspect();
      boolean _isString = this._typeHelper.isString(type);
      if (_isString) {
        EList<String> _tags = suspect.getTags();
        _tags.add(ILayoutingStrategy.TAG__RICH_TEXT__STRING);
      } else {
        boolean _isByteArray = this.isByteArray(type);
        if (_isByteArray) {
          EList<String> _tags_1 = suspect.getTags();
          _tags_1.add(ILayoutingStrategy.TAG__RICH_TEXT__BLOB);
        } else {
          String _qualifiedName = type.getQualifiedName();
          String _plus = ("RichTextFields need to be bound to String or byte[]. " + _qualifiedName);
          String _plus_1 = (_plus + 
            " is not a valid option.");
          throw new IllegalArgumentException(_plus_1);
        }
      }
      suspect.setType(this.computer.loadClass(this.uiLayout.eResource().getResourceSet(), type.getQualifiedName()));
      suspect.setTypeQualifiedName(type.getQualifiedName());
      _xblockexpression = suspect;
    }
    return _xblockexpression;
  }
  
  public YSuspect createMaskedTextField(final JvmType type, final OperationExtensions.OperationInfo info, final String mask) {
    YTypedSuspect _xblockexpression = null;
    {
      final YTypedSuspect suspect = YECviewFactory.eINSTANCE.createYTypedSuspect();
      EList<String> _tags = suspect.getTags();
      _tags.add(ILayoutingStrategy.TAG__MASKED_TEXT_FIELD);
      suspect.getProperties().put(ILayoutingStrategy.PROPERTY_MASK, mask);
      suspect.setType(this.computer.loadClass(this.uiLayout.eResource().getResourceSet(), type.getQualifiedName()));
      suspect.setTypeQualifiedName(type.getQualifiedName());
      _xblockexpression = suspect;
    }
    return _xblockexpression;
  }
  
  public YSuspect createMaskedDecimalField(final JvmType type, final OperationExtensions.OperationInfo info, final String mask) {
    YTypedSuspect _xblockexpression = null;
    {
      final YTypedSuspect suspect = YECviewFactory.eINSTANCE.createYTypedSuspect();
      EList<String> _tags = suspect.getTags();
      _tags.add(ILayoutingStrategy.TAG__MASKED_DECIMAL_FIELD);
      suspect.getProperties().put(ILayoutingStrategy.PROPERTY_MASK, mask);
      suspect.setType(this.computer.loadClass(this.uiLayout.eResource().getResourceSet(), type.getQualifiedName()));
      suspect.setTypeQualifiedName(type.getQualifiedName());
      _xblockexpression = suspect;
    }
    return _xblockexpression;
  }
  
  public YSuspect createPasswordField(final JvmType type, final OperationExtensions.OperationInfo info) {
    YTypedSuspect _xblockexpression = null;
    {
      final YTypedSuspect suspect = YECviewFactory.eINSTANCE.createYTypedSuspect();
      boolean _isString = this._typeHelper.isString(type);
      if (_isString) {
        EList<String> _tags = suspect.getTags();
        _tags.add(ILayoutingStrategy.TAG__PASSWORD);
      } else {
        String _qualifiedName = type.getQualifiedName();
        String _plus = ("PasswordField need to be bound to String. " + _qualifiedName);
        String _plus_1 = (_plus + " is not a valid option.");
        throw new IllegalArgumentException(_plus_1);
      }
      suspect.setType(this.computer.loadClass(this.uiLayout.eResource().getResourceSet(), type.getQualifiedName()));
      suspect.setTypeQualifiedName(type.getQualifiedName());
      _xblockexpression = suspect;
    }
    return _xblockexpression;
  }
  
  public YSuspect createBlopUploadComponent(final JvmType type, final OperationExtensions.OperationInfo info) {
    YTypedSuspect _xblockexpression = null;
    {
      final YTypedSuspect suspect = YECviewFactory.eINSTANCE.createYTypedSuspect();
      EList<String> _tags = suspect.getTags();
      _tags.add(ILayoutingStrategy.TAG__BLOB);
      suspect.setType(this.computer.loadClass(this.uiLayout.eResource().getResourceSet(), type.getQualifiedName()));
      suspect.setTypeQualifiedName(type.getQualifiedName());
      _xblockexpression = suspect;
    }
    return _xblockexpression;
  }
  
  public YSuspect createCustomDecimalField(final JvmType type, final OperationExtensions.OperationInfo info) {
    YTypedSuspect _xblockexpression = null;
    {
      final YTypedSuspect suspect = YECviewFactory.eINSTANCE.createYTypedSuspect();
      EList<String> _tags = suspect.getTags();
      _tags.add(ILayoutingStrategy.TAG__DECIMAL);
      suspect.setType(this.computer.loadClass(this.uiLayout.eResource().getResourceSet(), type.getQualifiedName()));
      suspect.setTypeQualifiedName(type.getQualifiedName());
      _xblockexpression = suspect;
    }
    return _xblockexpression;
  }
  
  /**
   * Create the bindings and install at the view
   */
  public void createBinding(final YEmbeddable yField, final OperationExtensions.OperationInfo info, final JvmType type, final String fieldProperty) {
    UiBindingExpression _autoWireSource = this.uiLayout.getAutoWireSource();
    final UiBindingEndpointAssignment uiModelEndpoint = ((UiBindingEndpointAssignment) _autoWireSource);
    final YValueBindingEndpoint yModelEndpoint = this.computer.createValueBindingEndpoint(uiModelEndpoint);
    final YDetailValueBindingEndpoint detailValueEndpoint = yModelEndpoint.createDetailValueEndpoint();
    detailValueEndpoint.setPropertyPath(info.getName());
    detailValueEndpoint.setType(this.computer.loadClass(this.uiLayout.eResource().getResourceSet(), this.beanType.getQualifiedName()));
    final YECViewModelValueBindingEndpoint yFieldEndpoint = BindingFactory.eINSTANCE.createYECViewModelValueBindingEndpoint();
    yFieldEndpoint.setElement(yField);
    yFieldEndpoint.setPropertyPath(fieldProperty);
    yFieldEndpoint.setTypeQualifiedName(this.beanType.getQualifiedName());
    yFieldEndpoint.setType(this.computer.loadClass(this.uiLayout.eResource().getResourceSet(), this.beanType.getQualifiedName()));
    if (((yFieldEndpoint.getType() != null) && yFieldEndpoint.getType().isAssignableFrom(EObject.class))) {
      yFieldEndpoint.setEmfNsURI(yField.eClass().getEPackage().getNsURI());
    }
    final YValueBinding yBinding = BindingFactory.eINSTANCE.createYValueBinding();
    yBinding.setTargetEndpoint(yFieldEndpoint);
    yBinding.setModelEndpoint(detailValueEndpoint);
    yBinding.setModelToTargetStrategy(YBindingUpdateStrategy.UPDATE);
    YBindingUpdateStrategy _xifexpression = null;
    boolean _isReadonly = info.isReadonly();
    if (_isReadonly) {
      _xifexpression = YBindingUpdateStrategy.NEVER;
    } else {
      _xifexpression = YBindingUpdateStrategy.UPDATE;
    }
    yBinding.setTargetToModelStrategy(_xifexpression);
    EList<YBinding> _bindings = this.yLayout.getView().getOrCreateBindingSet().getBindings();
    _bindings.add(yBinding);
    yField.setLabelI18nKey(detailValueEndpoint.getPropertyPath());
  }
  
  /**
   * Create the bindings and install at the view
   */
  public void createModelValueBinding(final YSuspect suspect, final String propertyPath, final JvmType type, final String fieldProperty, final JvmType parentType) {
    final YBeanSlot subTypeBeanSlot = this.findSubTypeBeanSlot(suspect);
    YValueBindingEndpoint endpoint = null;
    String path = "";
    if ((subTypeBeanSlot == null)) {
      UiBindingExpression _autoWireSource = this.uiLayout.getAutoWireSource();
      final UiBindingEndpointAssignment uiModelEndpoint = ((UiBindingEndpointAssignment) _autoWireSource);
      final YValueBindingEndpoint yModelEndpoint = this.computer.createValueBindingEndpoint(uiModelEndpoint);
      final YDetailValueBindingEndpoint detailValueEndpoint = yModelEndpoint.createDetailValueEndpoint();
      detailValueEndpoint.setPropertyPath(propertyPath);
      detailValueEndpoint.setType(this.computer.loadClass(this.uiLayout.eResource().getResourceSet(), 
        parentType.getQualifiedName()));
      endpoint = detailValueEndpoint;
      path = detailValueEndpoint.getPropertyPath();
    } else {
      endpoint = subTypeBeanSlot.createBindingEndpoint(propertyPath);
      path = propertyPath;
    }
    suspect.getValueBindingEndpoints().add(endpoint);
    suspect.setLabelI18nKey(path);
    suspect.setLabel(propertyPath);
  }
  
  /**
   * Creates a binding which points to the container of the property
   */
  public void createModelValueContainerBinding(final YSuspect suspect, final String propertyPath, final JvmType type, final String property) {
    String fieldProperty = property;
    boolean _contains = fieldProperty.contains(".");
    if (_contains) {
      fieldProperty = fieldProperty.substring(0, fieldProperty.lastIndexOf("."));
    } else {
      fieldProperty = null;
    }
    final YBeanSlot subTypeBeanSlot = this.findSubTypeBeanSlot(suspect);
    YValueBindingEndpoint endpoint = null;
    if ((subTypeBeanSlot == null)) {
      UiBindingExpression _autoWireSource = this.uiLayout.getAutoWireSource();
      final UiBindingEndpointAssignment uiModelEndpoint = ((UiBindingEndpointAssignment) _autoWireSource);
      final YValueBindingEndpoint yModelEndpoint = this.computer.createValueBindingEndpoint(uiModelEndpoint);
      endpoint = yModelEndpoint;
      if ((fieldProperty != null)) {
        final YDetailValueBindingEndpoint detailValueEndpoint = yModelEndpoint.createDetailValueEndpoint();
        detailValueEndpoint.setPropertyPath(propertyPath);
        detailValueEndpoint.setType(this.computer.loadClass(this.uiLayout.eResource().getResourceSet(), 
          this.beanType.getQualifiedName()));
        endpoint = detailValueEndpoint;
      }
    } else {
      endpoint = subTypeBeanSlot.createBindingEndpoint(propertyPath);
    }
    suspect.setContainerValueBindingEndpoint(endpoint);
  }
  
  /**
   * Checks if the suspect is contained in an YSubTypeSuspect. <br>
   * If so, then the detail beanslot of the YSubTypeSuspect is returned. Null otherwise.
   */
  public YBeanSlot findSubTypeBeanSlot(final YSuspect suspect) {
    if ((suspect == null)) {
      return null;
    }
    if ((suspect instanceof YSubTypeSuspect)) {
      return ((YSubTypeSuspect)suspect).getBeanSlot();
    }
    final EObject parent = suspect.eContainer();
    if ((parent instanceof YSuspect)) {
      return this.findSubTypeBeanSlot(((YSuspect)parent));
    }
    return null;
  }
  
  /**
   * Create the bindings and install at the view
   */
  public void createModelListBinding(final YSuspect suspect, final OperationExtensions.OperationInfo info, final JvmType type, final String fieldProperty) {
    final YBeanSlot subTypeBeanSlot = this.findSubTypeBeanSlot(suspect);
    YListBindingEndpoint endpoint = null;
    if ((subTypeBeanSlot == null)) {
      UiBindingExpression _autoWireSource = this.uiLayout.getAutoWireSource();
      final UiBindingEndpointAssignment uiModelEndpoint = ((UiBindingEndpointAssignment) _autoWireSource);
      endpoint = this.createListBindingEndpointWithNested(uiModelEndpoint, info.getName());
    } else {
      endpoint = subTypeBeanSlot.createListBindingEndpoint(info.getName(), subTypeBeanSlot.getValueType());
    }
    suspect.getValueBindingEndpoints().add(endpoint);
    suspect.setLabelI18nKey(info.getName());
    suspect.setLabel(info.getName());
  }
  
  /**
   * 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>
   */
  public YListBindingEndpoint createListBindingEndpointWithNested(final UiBindingEndpointAssignment epDef, final String attributePath) {
    if ((epDef == null)) {
      return null;
    }
    YListBindingEndpoint result = null;
    final BindingInfoHelper.BindingInfo info = new BindingInfoHelper.BindingInfo();
    this.bindingInfoHelper.collectBindingInfo(epDef, info);
    EObject _bindingRoot = info.getBindingRoot();
    if ((_bindingRoot instanceof UiBeanSlot)) {
      EObject _bindingRoot_1 = info.getBindingRoot();
      final UiBeanSlot uiBeanSlot = ((UiBeanSlot) _bindingRoot_1);
      final YBeanSlot yBeanSlot = this.computer.<YBeanSlot>associatedUi(uiBeanSlot);
      final YBeanSlotListBindingEndpoint ep = this.factory.createBeanSlotListBindingEndpoint();
      ep.setBeanSlot(yBeanSlot);
      ep.setAttributePath(this.toNestedCollectionPath(info, attributePath));
      result = ep;
    } else {
      EObject _bindingRoot_2 = info.getBindingRoot();
      if ((_bindingRoot_2 instanceof UiEmbeddable)) {
        final YEmbeddable yElement = this.computer.<YEmbeddable>associatedUi(info.getBindingRoot());
        final YECViewModelListBindingEndpoint ep_1 = this.factory.createECViewModelListBindingEndpoint();
        ep_1.setElement(yElement);
        ep_1.setPropertyPath(this.toNestedCollectionPath(info, attributePath));
        JvmType _typeForBinding = info.getTypeForBinding();
        boolean _tripleNotEquals = (_typeForBinding != null);
        if (_tripleNotEquals) {
          ep_1.setTypeQualifiedName(info.getTypeForBinding().getQualifiedName());
          ep_1.setType(this.computer.loadClass(epDef.eResource().getResourceSet(), ep_1.getTypeQualifiedName()));
        }
        if ((yElement != null)) {
          ep_1.setEmfNsURI(yElement.eClass().getEPackage().getNsURI());
        }
        result = ep_1;
      }
    }
    return result;
  }
  
  public String toNestedCollectionPath(final BindingInfoHelper.BindingInfo info, final String attributePath) {
    String _xblockexpression = null;
    {
      final StringBuilder b = new StringBuilder();
      boolean _isNullOrEmpty = StringExtensions.isNullOrEmpty(info.getPath().toString());
      boolean _not = (!_isNullOrEmpty);
      if (_not) {
        b.append(info.getPath().toString());
      }
      boolean _isNullOrEmpty_1 = StringExtensions.isNullOrEmpty(attributePath);
      boolean _not_1 = (!_isNullOrEmpty_1);
      if (_not_1) {
        int _length = b.length();
        boolean _greaterThan = (_length > 0);
        if (_greaterThan) {
          b.append(".");
        }
        b.append(attributePath);
      }
      final String pathResult = b.toString();
      _xblockexpression = pathResult;
    }
    return _xblockexpression;
  }
  
  /**
   * Creates y column info element
   */
  public YColumnInfo createYColumnInfo(final JvmType type) {
    YColumnInfo _xblockexpression = null;
    {
      final YColumnInfo columnInfo = YECviewFactory.eINSTANCE.createYColumnInfo();
      columnInfo.setTypeQualifiedName(type.getQualifiedName());
      columnInfo.setType(this.computer.loadClass(this.uiLayout.eResource().getResourceSet(), columnInfo.getTypeQualifiedName()));
      _xblockexpression = columnInfo;
    }
    return _xblockexpression;
  }
  
  /**
   * Sets properties into y column info
   */
  public void setYColumnInfoProperties(final YColumnInfo columnInfo, final List<AutowireUtil.Pair> propList) {
    EMap<String, String> properties = columnInfo.getProperties();
    if ((propList != null)) {
      for (final AutowireUtil.Pair prop : propList) {
        properties.put(prop.key, prop.value);
      }
    }
  }
}
