/**
 * Copyright (c) 2011, 2015 - Lunifera GmbH (Gross Enzersdorf, Austria), Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 * 
 * SPDX-License-Identifier: EPL-2.0
 * 
 * Contributors:
 *         Florian Pirchner - Initial implementation
 */
package org.eclipse.osbp.dsl.entity.xtext.jvmmodel;

import com.google.common.base.Objects;
import com.google.inject.Inject;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import javax.persistence.AssociationOverride;
import javax.persistence.AssociationOverrides;
import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Basic;
import javax.persistence.Cacheable;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.DiscriminatorValue;
import javax.persistence.ElementCollection;
import javax.persistence.Embeddable;
import javax.persistence.Embedded;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Index;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinColumns;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.MappedSuperclass;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
import javax.persistence.Version;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.osbp.dsl.entity.xtext.extensions.AnnotationExtension;
import org.eclipse.osbp.dsl.entity.xtext.extensions.ModelExtensions;
import org.eclipse.osbp.dsl.entity.xtext.extensions.NamingExtensions;
import org.eclipse.osbp.dsl.entity.xtext.util.PersistenceNamingUtils;
import org.eclipse.osbp.dsl.semantic.common.types.LAnnotationDef;
import org.eclipse.osbp.dsl.semantic.common.types.LAnnotationTarget;
import org.eclipse.osbp.dsl.semantic.common.types.LAttribute;
import org.eclipse.osbp.dsl.semantic.common.types.LAttributeMatchingConstraint;
import org.eclipse.osbp.dsl.semantic.common.types.LDataType;
import org.eclipse.osbp.dsl.semantic.common.types.LDatatypeConstraint;
import org.eclipse.osbp.dsl.semantic.common.types.LDateType;
import org.eclipse.osbp.dsl.semantic.common.types.LEnum;
import org.eclipse.osbp.dsl.semantic.common.types.LEnumLiteral;
import org.eclipse.osbp.dsl.semantic.common.types.LFeature;
import org.eclipse.osbp.dsl.semantic.common.types.LReference;
import org.eclipse.osbp.dsl.semantic.common.types.LResultFilter;
import org.eclipse.osbp.dsl.semantic.common.types.LResultFilters;
import org.eclipse.osbp.dsl.semantic.common.types.LScalarType;
import org.eclipse.osbp.dsl.semantic.common.types.LStateClass;
import org.eclipse.osbp.dsl.semantic.common.types.LType;
import org.eclipse.osbp.dsl.semantic.entity.LBean;
import org.eclipse.osbp.dsl.semantic.entity.LBeanAttribute;
import org.eclipse.osbp.dsl.semantic.entity.LBeanFeature;
import org.eclipse.osbp.dsl.semantic.entity.LBeanReference;
import org.eclipse.osbp.dsl.semantic.entity.LDiscriminatorType;
import org.eclipse.osbp.dsl.semantic.entity.LEntity;
import org.eclipse.osbp.dsl.semantic.entity.LEntityAttribute;
import org.eclipse.osbp.dsl.semantic.entity.LEntityFeature;
import org.eclipse.osbp.dsl.semantic.entity.LEntityInheritanceStrategy;
import org.eclipse.osbp.dsl.semantic.entity.LEntityReference;
import org.eclipse.osbp.dsl.semantic.entity.LIndex;
import org.eclipse.osbp.dsl.semantic.entity.LOperation;
import org.eclipse.osbp.dsl.semantic.entity.LTablePerClassStrategy;
import org.eclipse.osbp.dsl.semantic.entity.LTablePerSubclassStrategy;
import org.eclipse.osbp.jpa.services.history.HistorizedQueryRedirector;
import org.eclipse.osbp.jpa.services.history.HistorizedReferenceQueryRedirector;
import org.eclipse.osbp.jpa.services.listener.EntityInfoListener;
import org.eclipse.osbp.runtime.common.annotations.AsGrid;
import org.eclipse.osbp.runtime.common.annotations.AsKanbanOrdering;
import org.eclipse.osbp.runtime.common.annotations.AsKanbanState;
import org.eclipse.osbp.runtime.common.annotations.AsTable;
import org.eclipse.osbp.runtime.common.annotations.BeanOnTab;
import org.eclipse.osbp.runtime.common.annotations.Dispose;
import org.eclipse.osbp.runtime.common.annotations.DomainDescription;
import org.eclipse.osbp.runtime.common.annotations.DomainKey;
import org.eclipse.osbp.runtime.common.annotations.ExtraStyle;
import org.eclipse.osbp.runtime.common.annotations.Filter;
import org.eclipse.osbp.runtime.common.annotations.Hidden;
import org.eclipse.osbp.runtime.common.annotations.HistReference;
import org.eclipse.osbp.runtime.common.annotations.HistorizedObject;
import org.eclipse.osbp.runtime.common.annotations.OnKanbanCard;
import org.eclipse.osbp.runtime.common.annotations.Range;
import org.eclipse.osbp.runtime.common.annotations.ReadOnly;
import org.eclipse.osbp.runtime.common.annotations.SideKick;
import org.eclipse.osbp.runtime.common.annotations.StateClass;
import org.eclipse.osbp.runtime.common.annotations.TargetEnumConstraint;
import org.eclipse.osbp.runtime.common.annotations.TargetEnumConstraints;
import org.eclipse.osbp.runtime.common.annotations.TimedependentObject;
import org.eclipse.osbp.runtime.common.annotations.UIGroup;
import org.eclipse.osbp.runtime.common.annotations.UniqueEntry;
import org.eclipse.persistence.annotations.ConversionValue;
import org.eclipse.persistence.annotations.Convert;
import org.eclipse.persistence.annotations.ObjectTypeConverter;
import org.eclipse.persistence.annotations.QueryRedirectors;
import org.eclipse.xtext.common.types.JvmAnnotationReference;
import org.eclipse.xtext.common.types.JvmAnnotationTarget;
import org.eclipse.xtext.common.types.JvmEnumerationType;
import org.eclipse.xtext.common.types.JvmFeature;
import org.eclipse.xtext.common.types.JvmField;
import org.eclipse.xtext.common.types.JvmGenericType;
import org.eclipse.xtext.common.types.JvmMember;
import org.eclipse.xtext.common.types.JvmOperation;
import org.eclipse.xtext.common.types.JvmTypeReference;
import org.eclipse.xtext.common.types.util.TypeReferences;
import org.eclipse.xtext.xbase.annotations.xAnnotations.XAnnotation;
import org.eclipse.xtext.xbase.jvmmodel.JvmTypesBuilder;
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
import org.eclipse.xtext.xbase.lib.Conversions;
import org.eclipse.xtext.xbase.lib.Extension;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.InputOutput;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.ListExtensions;
import org.eclipse.xtext.xbase.lib.StringExtensions;

/**
 * This class is responsible to generate the Annotations defined in the entity model
 */
@SuppressWarnings("all")
public class AnnotationCompiler extends org.eclipse.osbp.dsl.common.xtext.jvmmodel.AnnotationCompiler {
  @Inject
  @Extension
  private ModelExtensions _modelExtensions;
  
  @Inject
  @Extension
  private JvmTypesBuilder _jvmTypesBuilder;
  
  @Inject
  @Extension
  private AnnotationExtension _annotationExtension;
  
  @Inject
  @Extension
  private NamingExtensions _namingExtensions;
  
  @Inject
  private TypeReferences references;
  
  protected void _internalProcessAnnotation(final LBean bean, final JvmGenericType jvmType) {
    final Function1<LAnnotationDef, Boolean> _function = (LAnnotationDef it) -> {
      boolean _isExclude = it.isExclude();
      return Boolean.valueOf((!_isExclude));
    };
    final Function1<LAnnotationDef, XAnnotation> _function_1 = (LAnnotationDef it) -> {
      return it.getAnnotation();
    };
    this._jvmTypesBuilder.addAnnotations(jvmType, IterableExtensions.<LAnnotationDef, XAnnotation>map(IterableExtensions.<LAnnotationDef>filter(bean.getResolvedAnnotations(), _function), _function_1));
    this._annotationExtension.addAnno(bean, jvmType, this._jvmTypesBuilder.toAnnotation(bean, Embeddable.class));
  }
  
  protected void _internalProcessAnnotation(final LOperation member, final JvmField jvmOperation) {
    final Function1<LAnnotationDef, Boolean> _function = (LAnnotationDef it) -> {
      boolean _isExclude = it.isExclude();
      return Boolean.valueOf((!_isExclude));
    };
    final Function1<LAnnotationDef, XAnnotation> _function_1 = (LAnnotationDef it) -> {
      return it.getAnnotation();
    };
    this._jvmTypesBuilder.addAnnotations(jvmOperation, IterableExtensions.<LAnnotationDef, XAnnotation>map(IterableExtensions.<LAnnotationDef>filter(member.getResolvedAnnotations(), _function), _function_1));
  }
  
  protected void _internalProcessAnnotation(final LEntity entity, final JvmGenericType jvmType) {
    final Function1<LAnnotationDef, Boolean> _function = (LAnnotationDef it) -> {
      boolean _isExclude = it.isExclude();
      return Boolean.valueOf((!_isExclude));
    };
    final Function1<LAnnotationDef, XAnnotation> _function_1 = (LAnnotationDef it) -> {
      return it.getAnnotation();
    };
    this._jvmTypesBuilder.addAnnotations(jvmType, IterableExtensions.<LAnnotationDef, XAnnotation>map(IterableExtensions.<LAnnotationDef>filter(entity.getResolvedAnnotations(), _function), _function_1));
    boolean _isHistorized = entity.isHistorized();
    if (_isHistorized) {
      this._annotationExtension.addAnno(entity, jvmType, this._jvmTypesBuilder.toAnnotation(entity, HistorizedObject.class));
    } else {
      boolean _isTimedependent = entity.isTimedependent();
      if (_isTimedependent) {
        this._annotationExtension.addAnno(entity, jvmType, this._jvmTypesBuilder.toAnnotation(entity, TimedependentObject.class));
      }
    }
    if ((entity.isHistorized() || entity.isTimedependent())) {
      final JvmAnnotationReference redirectAnno = this._jvmTypesBuilder.toAnnotation(entity, QueryRedirectors.class);
      final JvmTypeReference insertType = this.references.getTypeForName(HistorizedQueryRedirector.class, entity);
      this._annotationExtension.addAnnAttr(redirectAnno, entity, "insert", insertType);
      final JvmTypeReference updateType = this.references.getTypeForName(HistorizedQueryRedirector.class, entity);
      this._annotationExtension.addAnnAttr(redirectAnno, entity, "update", updateType);
      final JvmTypeReference readObjectType = this.references.getTypeForName(HistorizedReferenceQueryRedirector.class, entity);
      this._annotationExtension.addAnnAttr(redirectAnno, entity, "readObject", readObjectType);
      this._annotationExtension.addAnno(entity, jvmType, redirectAnno);
    }
    boolean _isMappedSuperclass = entity.isMappedSuperclass();
    if (_isMappedSuperclass) {
      this._annotationExtension.addAnno(entity, jvmType, this._jvmTypesBuilder.toAnnotation(entity, MappedSuperclass.class));
      final JvmAnnotationReference listenerAnn = this._jvmTypesBuilder.toAnnotation(entity, EntityListeners.class);
      final JvmTypeReference listenerType = this.references.getTypeForName(EntityInfoListener.class, entity);
      this._annotationExtension.addAnnAttr(listenerAnn, entity, "value", listenerType);
      this._annotationExtension.addAnno(entity, jvmType, listenerAnn);
    } else {
      this._annotationExtension.addAnno(entity, jvmType, this._jvmTypesBuilder.toAnnotation(entity, Entity.class));
      if (((!this._modelExtensions.isStrategyFromSuperPresent(entity)) || this._modelExtensions.isStrategyPerSubclass(entity))) {
        final JvmAnnotationReference tableAnn = this._jvmTypesBuilder.toAnnotation(entity, Table.class);
        this._annotationExtension.addAnno(entity, jvmType, tableAnn);
        final String schemaName = this._namingExtensions.toSchemaName(entity);
        boolean _isNullOrEmpty = StringExtensions.isNullOrEmpty(schemaName);
        boolean _not = (!_isNullOrEmpty);
        if (_not) {
          this._annotationExtension.addAnnAttr(tableAnn, entity, "schema", schemaName);
        }
        this._annotationExtension.addAnnAttr(tableAnn, entity, "name", this._namingExtensions.toTableName(entity));
        final List<JvmAnnotationReference> collectedIndizes = CollectionLiterals.<JvmAnnotationReference>newArrayList();
        EList<LIndex> _indexes = entity.getIndexes();
        for (final LIndex index : _indexes) {
          {
            final JvmAnnotationReference indexAnn = this._jvmTypesBuilder.toAnnotation(entity, Index.class);
            this._annotationExtension.addAnno(entity, jvmType, indexAnn);
            String _name = entity.getName();
            String _name_1 = index.getName();
            String _plus = (_name + _name_1);
            this._annotationExtension.addAnnAttr(indexAnn, entity, "name", PersistenceNamingUtils.camelCaseToUpperCase(_plus));
            boolean _isUnique = index.isUnique();
            if (_isUnique) {
              this._annotationExtension.addAnnAttr(indexAnn, entity, "unique", Boolean.valueOf(true));
            }
            StringBuilder propList = new StringBuilder();
            final Function1<LEntityFeature, String> _function_2 = (LEntityFeature it) -> {
              return it.getName();
            };
            List<String> _map = ListExtensions.<LEntityFeature, String>map(index.getFeatures(), _function_2);
            for (final String name : _map) {
              boolean _notEquals = (!Objects.equal(propList, null));
              if (_notEquals) {
                int _length = propList.length();
                boolean _greaterThan = (_length > 0);
                if (_greaterThan) {
                  propList.append(", ");
                }
                propList.append(PersistenceNamingUtils.camelCaseToUpperCase(name));
              }
            }
            this._annotationExtension.addAnnAttr(indexAnn, entity, "columnList", propList.toString());
            collectedIndizes.add(indexAnn);
          }
        }
        int _size = collectedIndizes.size();
        boolean _greaterThan = (_size > 0);
        if (_greaterThan) {
          final JvmAnnotationReference[] result = collectedIndizes.<JvmAnnotationReference>toArray(
            new JvmAnnotationReference[collectedIndizes.size()]);
          this._annotationExtension.addAnnAttr(tableAnn, entity, "indexes", result);
        }
      }
      final LEntityInheritanceStrategy strategy = this._modelExtensions.toInheritanceStrategy(entity);
      this.processInheritance(strategy, entity, jvmType);
      boolean _isCacheable = entity.isCacheable();
      if (_isCacheable) {
        this._annotationExtension.addAnno(entity, jvmType, this._jvmTypesBuilder.toAnnotation(entity, Cacheable.class));
      }
    }
  }
  
  protected void _processInheritance(final LTablePerClassStrategy strategy, final LEntity entity, final JvmGenericType jvmType) {
    final LEntity superType = entity.getSuperType();
    if (((!entity.getSubTypes().isEmpty()) && (Objects.equal(superType, null) || this._modelExtensions.checkIsMappedSuperclass(superType)))) {
      final JvmAnnotationReference annRef = this._jvmTypesBuilder.toAnnotation(entity, Inheritance.class);
      this._annotationExtension.addAnnAttr(annRef, entity, "strategy", InheritanceType.SINGLE_TABLE);
      this._annotationExtension.addAnno(entity, jvmType, annRef);
      final JvmAnnotationReference discrColumn = this._jvmTypesBuilder.toAnnotation(entity, DiscriminatorColumn.class);
      this._annotationExtension.addAnnAttr(discrColumn, entity, "name", strategy.getDiscriminatorColumn());
      this._annotationExtension.addAnnAttr(discrColumn, entity, "discriminatorType", this.toDiscriminatorType(strategy.getDiscriminatorType()));
      this._annotationExtension.addAnno(entity, jvmType, discrColumn);
    }
    if (((!entity.getSubTypes().isEmpty()) || (!this._modelExtensions.checkIsMappedSuperclass(superType)))) {
      final JvmAnnotationReference discrValue = this._jvmTypesBuilder.toAnnotation(entity, DiscriminatorValue.class);
      this._annotationExtension.addAnnAttr(discrValue, entity, "value", strategy.getDiscriminatorValue());
      this._annotationExtension.addAnno(entity, jvmType, discrValue);
    }
  }
  
  protected void _processInheritance(final LTablePerSubclassStrategy strategy, final LEntity entity, final JvmGenericType jvmType) {
    final LEntity superType = entity.getSuperType();
    if (((!entity.getSubTypes().isEmpty()) && (Objects.equal(superType, null) || this._modelExtensions.checkIsMappedSuperclass(superType)))) {
      final JvmAnnotationReference annRef = this._jvmTypesBuilder.toAnnotation(entity, Inheritance.class);
      this._annotationExtension.addAnnAttr(annRef, entity, "strategy", InheritanceType.JOINED);
      this._annotationExtension.addAnno(entity, jvmType, annRef);
      final JvmAnnotationReference discrColumn = this._jvmTypesBuilder.toAnnotation(entity, DiscriminatorColumn.class);
      this._annotationExtension.addAnnAttr(discrColumn, entity, "name", strategy.getDiscriminatorColumn());
      this._annotationExtension.addAnnAttr(discrColumn, entity, "discriminatorType", this.toDiscriminatorType(strategy.getDiscriminatorType()));
      this._annotationExtension.addAnno(entity, jvmType, discrColumn);
    }
    if (((!entity.getSubTypes().isEmpty()) || (!this._modelExtensions.checkIsMappedSuperclass(superType)))) {
      final JvmAnnotationReference discrValue = this._jvmTypesBuilder.toAnnotation(entity, DiscriminatorValue.class);
      this._annotationExtension.addAnnAttr(discrValue, entity, "value", strategy.getDiscriminatorValue());
      this._annotationExtension.addAnno(entity, jvmType, discrValue);
    }
  }
  
  public DiscriminatorType toDiscriminatorType(final LDiscriminatorType type) {
    Object _switchResult = null;
    if (type != null) {
      switch (type) {
        case STRING:
          return DiscriminatorType.STRING;
        case CHAR:
          return DiscriminatorType.CHAR;
        case INTEGER:
          return DiscriminatorType.INTEGER;
        default:
          _switchResult = null;
          break;
      }
    } else {
      _switchResult = null;
    }
    return ((DiscriminatorType)_switchResult);
  }
  
  protected void _internalProcessAnnotation(final LEntityReference prop, final JvmField jvmField) {
    final Function1<LAnnotationDef, Boolean> _function = (LAnnotationDef it) -> {
      boolean _isExclude = it.isExclude();
      return Boolean.valueOf((!_isExclude));
    };
    final Function1<LAnnotationDef, XAnnotation> _function_1 = (LAnnotationDef it) -> {
      return it.getAnnotation();
    };
    this._jvmTypesBuilder.addAnnotations(jvmField, IterableExtensions.<LAnnotationDef, XAnnotation>map(IterableExtensions.<LAnnotationDef>filter(prop.getResolvedAnnotations(), _function), _function_1));
    boolean _isToMany = this._modelExtensions.isToMany(prop);
    if (_isToMany) {
      boolean _isToMany_1 = this._modelExtensions.isToMany(prop.getOpposite());
      if (_isToMany_1) {
        this.addManyToManyAnno(prop, jvmField);
      } else {
        this.addOneToManyAnno(prop, jvmField);
      }
    } else {
      final LFeature opposite = this._modelExtensions.getResolvedOpposite(prop);
      if (((!Objects.equal(opposite, null)) && (!this._modelExtensions.isToMany(opposite)))) {
        this.addOneToOneAnno(prop, jvmField);
      } else {
        this.addManyToOneAnno(prop, jvmField);
      }
    }
    LResultFilters _resultFilters = prop.getResultFilters();
    boolean _notEquals = (!Objects.equal(_resultFilters, null));
    if (_notEquals) {
      this.addConstraintsAnno(prop.getResultFilters(), jvmField);
    }
    this.toPropertiesAnnotation(prop, this.mergeKeyAndValues(prop), jvmField);
    this.toConstraintAnnotations(prop, jvmField);
  }
  
  protected void _internalProcessAnnotation(final LStateClass stateClass, final JvmField jvmField) {
    final Function1<LAnnotationDef, Boolean> _function = (LAnnotationDef it) -> {
      boolean _isExclude = it.isExclude();
      return Boolean.valueOf((!_isExclude));
    };
    final Function1<LAnnotationDef, XAnnotation> _function_1 = (LAnnotationDef it) -> {
      return it.getAnnotation();
    };
    this._jvmTypesBuilder.addAnnotations(jvmField, IterableExtensions.<LAnnotationDef, XAnnotation>map(IterableExtensions.<LAnnotationDef>filter(stateClass.getResolvedAnnotations(), _function), _function_1));
    boolean _isColumnAnnoCreated = this._annotationExtension.isColumnAnnoCreated(jvmField, stateClass);
    boolean _not = (!_isColumnAnnoCreated);
    if (_not) {
      final JvmAnnotationReference ann = this._jvmTypesBuilder.toAnnotation(stateClass, Column.class);
      this._annotationExtension.addAnnAttr(ann, stateClass, "name", this._namingExtensions.toColumnName(stateClass));
      boolean _isRequired = this._modelExtensions.getBounds(stateClass).isRequired();
      if (_isRequired) {
        this._annotationExtension.addAnnAttr(ann, stateClass, "nullable", Boolean.valueOf(false));
      }
      this._annotationExtension.addAnno(stateClass, jvmField, ann);
    }
    EList<JvmAnnotationReference> _annotations = jvmField.getAnnotations();
    JvmAnnotationReference _annotation = this._jvmTypesBuilder.toAnnotation(stateClass, StateClass.class);
    this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations, _annotation);
    EList<JvmAnnotationReference> _annotations_1 = jvmField.getAnnotations();
    JvmAnnotationReference _annotation_1 = this._jvmTypesBuilder.toAnnotation(stateClass, ReadOnly.class);
    this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations_1, _annotation_1);
  }
  
  protected void _internalProcessAnnotation(final LEntityAttribute prop, final JvmField jvmField) {
    final Function1<LAnnotationDef, Boolean> _function = (LAnnotationDef it) -> {
      boolean _isExclude = it.isExclude();
      return Boolean.valueOf((!_isExclude));
    };
    final Function1<LAnnotationDef, XAnnotation> _function_1 = (LAnnotationDef it) -> {
      return it.getAnnotation();
    };
    this._jvmTypesBuilder.addAnnotations(jvmField, IterableExtensions.<LAnnotationDef, XAnnotation>map(IterableExtensions.<LAnnotationDef>filter(prop.getResolvedAnnotations(), _function), _function_1));
    boolean _isTransient = prop.isTransient();
    if (_isTransient) {
      this._annotationExtension.addAnno(prop, jvmField, this._jvmTypesBuilder.toAnnotation(prop, Transient.class));
      boolean _isAttributeHidden = prop.isAttributeHidden();
      if (_isAttributeHidden) {
        EList<JvmAnnotationReference> _annotations = jvmField.getAnnotations();
        JvmAnnotationReference _annotation = this._jvmTypesBuilder.toAnnotation(prop, Hidden.class);
        this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations, _annotation);
      } else {
        boolean _isAttributeReadOnly = prop.isAttributeReadOnly();
        if (_isAttributeReadOnly) {
          EList<JvmAnnotationReference> _annotations_1 = jvmField.getAnnotations();
          JvmAnnotationReference _annotation_1 = this._jvmTypesBuilder.toAnnotation(prop, ReadOnly.class);
          this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations_1, _annotation_1);
        }
      }
      String _extraStyle = prop.getExtraStyle();
      boolean _tripleNotEquals = (_extraStyle != null);
      if (_tripleNotEquals) {
        final JvmAnnotationReference styleAnnotation = this._jvmTypesBuilder.toAnnotation(prop, ExtraStyle.class);
        this._annotationExtension.addAnnAttr(styleAnnotation, prop, "name", prop.getExtraStyle());
        EList<JvmAnnotationReference> _annotations_2 = jvmField.getAnnotations();
        this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations_2, styleAnnotation);
      }
    } else {
      boolean _isId = prop.isId();
      if (_isId) {
        boolean _isHistorizedOrTimedependentWithParent = prop.getEntity().isHistorizedOrTimedependentWithParent();
        if (_isHistorizedOrTimedependentWithParent) {
          EList<JvmAnnotationReference> _annotations_3 = jvmField.getAnnotations();
          JvmAnnotationReference _annotation_2 = this._jvmTypesBuilder.toAnnotation(prop, EmbeddedId.class);
          this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations_3, _annotation_2);
        } else {
          EList<JvmAnnotationReference> _annotations_4 = jvmField.getAnnotations();
          JvmAnnotationReference _annotation_3 = this._jvmTypesBuilder.toAnnotation(prop, Id.class);
          this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations_4, _annotation_3);
          JvmAnnotationReference genValueAnn = this._jvmTypesBuilder.toAnnotation(prop, GeneratedValue.class);
          this._annotationExtension.addAnnAttr(genValueAnn, prop, "strategy", GenerationType.IDENTITY);
          EList<JvmAnnotationReference> _annotations_5 = jvmField.getAnnotations();
          this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations_5, genValueAnn);
        }
      } else {
        boolean _isUuid = prop.isUuid();
        if (_isUuid) {
          EList<JvmAnnotationReference> _annotations_6 = jvmField.getAnnotations();
          JvmAnnotationReference _annotation_4 = this._jvmTypesBuilder.toAnnotation(prop, Id.class);
          this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations_6, _annotation_4);
        }
      }
      boolean _isVersion = prop.isVersion();
      if (_isVersion) {
        EList<JvmAnnotationReference> _annotations_7 = jvmField.getAnnotations();
        JvmAnnotationReference _annotation_5 = this._jvmTypesBuilder.toAnnotation(prop, Version.class);
        this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations_7, _annotation_5);
      }
      boolean _isAttributeHidden_1 = prop.isAttributeHidden();
      if (_isAttributeHidden_1) {
        EList<JvmAnnotationReference> _annotations_8 = jvmField.getAnnotations();
        JvmAnnotationReference _annotation_6 = this._jvmTypesBuilder.toAnnotation(prop, Hidden.class);
        this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations_8, _annotation_6);
      } else {
        boolean _isAttributeReadOnly_1 = prop.isAttributeReadOnly();
        if (_isAttributeReadOnly_1) {
          EList<JvmAnnotationReference> _annotations_9 = jvmField.getAnnotations();
          JvmAnnotationReference _annotation_7 = this._jvmTypesBuilder.toAnnotation(prop, ReadOnly.class);
          this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations_9, _annotation_7);
        }
      }
      String _extraStyle_1 = prop.getExtraStyle();
      boolean _tripleNotEquals_1 = (_extraStyle_1 != null);
      if (_tripleNotEquals_1) {
        final JvmAnnotationReference styleAnnotation_1 = this._jvmTypesBuilder.toAnnotation(prop, ExtraStyle.class);
        this._annotationExtension.addAnnAttr(styleAnnotation_1, prop, "name", prop.getExtraStyle());
        EList<JvmAnnotationReference> _annotations_10 = jvmField.getAnnotations();
        this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations_10, styleAnnotation_1);
      }
      boolean _isToMany = this._modelExtensions.isToMany(prop);
      if (_isToMany) {
        final JvmAnnotationReference ann = this._jvmTypesBuilder.toAnnotation(prop, ElementCollection.class);
        this._annotationExtension.addAnno(prop, jvmField, ann);
      } else {
        LScalarType _type = prop.getType();
        if ((_type instanceof LBean)) {
          this._annotationExtension.addAnno(prop, jvmField, this._jvmTypesBuilder.toAnnotation(prop, Embedded.class));
          LScalarType _type_1 = prop.getType();
          boolean _isBeanOnTab = ((LBean) _type_1).isBeanOnTab();
          if (_isBeanOnTab) {
            this._annotationExtension.addAnno(prop, jvmField, this._jvmTypesBuilder.toAnnotation(prop, BeanOnTab.class));
          }
          this.toAttributesOverride(jvmField, prop);
        }
        boolean _isDomainKey = prop.isDomainKey();
        if (_isDomainKey) {
          this._annotationExtension.addAnno(prop, jvmField, this._jvmTypesBuilder.toAnnotation(prop, DomainKey.class));
        }
        boolean _isDomainDescription = prop.isDomainDescription();
        if (_isDomainDescription) {
          this._annotationExtension.addAnno(prop, jvmField, this._jvmTypesBuilder.toAnnotation(prop, DomainDescription.class));
        }
      }
      boolean _isColumnAnnoCreated = this._annotationExtension.isColumnAnnoCreated(jvmField, prop);
      boolean _not = (!_isColumnAnnoCreated);
      if (_not) {
        final JvmAnnotationReference ann_1 = this._jvmTypesBuilder.toAnnotation(prop, Column.class);
        this._annotationExtension.addAnnAttr(ann_1, prop, "name", this._namingExtensions.toColumnName(prop));
        boolean _isRequired = this._modelExtensions.getBounds(prop).isRequired();
        if (_isRequired) {
          this._annotationExtension.addAnnAttr(ann_1, prop, "nullable", Boolean.valueOf(false));
        }
        this._annotationExtension.addAnno(prop, jvmField, ann_1);
      }
      LScalarType _type_2 = prop.getType();
      if ((_type_2 instanceof LEnum)) {
        LScalarType _type_3 = prop.getType();
        final LEnum enumType = ((LEnum) _type_3);
        final ArrayList<JvmAnnotationReference> valueAnnotations = CollectionLiterals.<JvmAnnotationReference>newArrayList();
        boolean _needsConverter = this.needsConverter(enumType, prop, valueAnnotations);
        if (_needsConverter) {
          final JvmAnnotationReference converter = this._jvmTypesBuilder.toAnnotation(prop, ObjectTypeConverter.class);
          String _name = prop.getName();
          String _plus = (_name + "Converter");
          this._annotationExtension.addAnnAttr(converter, prop, "name", _plus);
          this._annotationExtension.addAnnAttr(converter, prop, "objectType", this.references.getTypeForName(this._modelExtensions.toQualifiedName(prop.getType()), prop));
          this._annotationExtension.addAnnAttr(converter, prop, "dataType", this.references.getTypeForName(String.class, prop));
          this._annotationExtension.addAnnAttr(converter, prop, "conversionValues", valueAnnotations.<JvmAnnotationReference>toArray(new JvmAnnotationReference[((Object[])Conversions.unwrapArray(valueAnnotations, Object.class)).length]));
          this._annotationExtension.addAnno(prop, jvmField, converter);
          String _name_1 = prop.getName();
          String _plus_1 = (_name_1 + "Converter");
          final JvmAnnotationReference converterRef = this._jvmTypesBuilder.toAnnotation(prop, Convert.class, _plus_1);
          this._annotationExtension.addAnno(prop, jvmField, converterRef);
        }
      }
      LScalarType _type_4 = prop.getType();
      if ((_type_4 instanceof LDataType)) {
        LScalarType _type_5 = prop.getType();
        final LDataType datatype = ((LDataType) _type_5);
        boolean _isDate = datatype.isDate();
        if (_isDate) {
          final JvmAnnotationReference temp = this._jvmTypesBuilder.toAnnotation(prop, Temporal.class);
          LDateType _dateType = datatype.getDateType();
          if (_dateType != null) {
            switch (_dateType) {
              case DATE:
                this._annotationExtension.addAnnAttr(temp, prop, "value", TemporalType.DATE);
                break;
              case TIME:
                this._annotationExtension.addAnnAttr(temp, prop, "value", TemporalType.TIME);
                break;
              case TIMESTAMP:
                this._annotationExtension.addAnnAttr(temp, prop, "value", TemporalType.TIMESTAMP);
                break;
              default:
                break;
            }
          } else {
          }
          this._annotationExtension.addAnno(prop, jvmField, temp);
        } else {
          boolean _isAsBlob = datatype.isAsBlob();
          if (_isAsBlob) {
            this._annotationExtension.addAnno(prop, jvmField, this._jvmTypesBuilder.toAnnotation(prop, Lob.class));
            final JvmAnnotationReference basic = this._jvmTypesBuilder.toAnnotation(prop, Basic.class);
            this._annotationExtension.addAnnAttr(basic, prop, "fetch", FetchType.LAZY);
            this._annotationExtension.addAnno(prop, jvmField, basic);
          }
        }
        boolean _isFiltering = prop.isFiltering();
        if (_isFiltering) {
          this._annotationExtension.addAnno(prop, jvmField, this._jvmTypesBuilder.toAnnotation(prop, Filter.class));
        }
        boolean _isRangeFiltering = prop.isRangeFiltering();
        if (_isRangeFiltering) {
          this._annotationExtension.addAnno(prop, jvmField, this._jvmTypesBuilder.toAnnotation(prop, Range.class));
        }
        boolean _isUniqueEntry = prop.isUniqueEntry();
        if (_isUniqueEntry) {
          this._annotationExtension.addAnno(prop, jvmField, this._jvmTypesBuilder.toAnnotation(prop, UniqueEntry.class));
        }
      }
      boolean _isOnKanbanCard = prop.isOnKanbanCard();
      if (_isOnKanbanCard) {
        this._annotationExtension.addAnno(prop, jvmField, this._jvmTypesBuilder.toAnnotation(prop, OnKanbanCard.class));
      }
      boolean _isAsKanbanOrdering = prop.isAsKanbanOrdering();
      if (_isAsKanbanOrdering) {
        this._annotationExtension.addAnno(prop, jvmField, this._jvmTypesBuilder.toAnnotation(prop, AsKanbanOrdering.class));
      }
      boolean _isAsKanbanState = prop.isAsKanbanState();
      if (_isAsKanbanState) {
        this._annotationExtension.addAnno(prop, jvmField, this._jvmTypesBuilder.toAnnotation(prop, AsKanbanState.class));
      }
      boolean _isIsGrouped = prop.isIsGrouped();
      if (_isIsGrouped) {
        final JvmAnnotationReference groupAnnotation = this._jvmTypesBuilder.toAnnotation(prop, UIGroup.class);
        this._annotationExtension.addAnnAttr(groupAnnotation, prop, "name", prop.getGroupName());
        this._annotationExtension.addAnno(prop, jvmField, groupAnnotation);
      }
    }
    this.toPropertiesAnnotation(prop, this.mergeKeyAndValues(prop), jvmField);
    this.toConstraintAnnotations(prop, jvmField);
  }
  
  public boolean needsConverter(final LEnum lEnum, final LEntityAttribute prop, final List<JvmAnnotationReference> valueAnnotations) {
    boolean needsConverter = false;
    EList<LEnumLiteral> _literals = lEnum.getLiterals();
    for (final LEnumLiteral literal : _literals) {
      String _stringValue = literal.getStringValue();
      boolean _tripleNotEquals = (_stringValue != null);
      if (_tripleNotEquals) {
        needsConverter = true;
        final JvmAnnotationReference anno = this._jvmTypesBuilder.toAnnotation(prop, ConversionValue.class);
        this._annotationExtension.addAnnAttr(anno, prop, "objectValue", literal.getName());
        this._annotationExtension.addAnnAttr(anno, prop, "dataValue", literal.getStringValue());
        valueAnnotations.add(anno);
      }
    }
    return needsConverter;
  }
  
  protected void toAttributesOverride(final JvmField jvmField, final LEntityAttribute prop) {
    final List<JvmAnnotationReference> collectedAttributes = CollectionLiterals.<JvmAnnotationReference>newArrayList();
    final List<JvmAnnotationReference> collectedAssocations = CollectionLiterals.<JvmAnnotationReference>newArrayList();
    LScalarType _type = prop.getType();
    final Function1<LBeanFeature, Boolean> _function = (LBeanFeature it) -> {
      boolean _isToMany = this._modelExtensions.isToMany(it);
      return Boolean.valueOf((!_isToMany));
    };
    Iterable<LBeanFeature> _filter = IterableExtensions.<LBeanFeature>filter(((LBean) _type).getAllFeatures(), _function);
    for (final LBeanFeature f : _filter) {
      if ((f instanceof LBeanAttribute)) {
        final JvmAnnotationReference overrideAttributeAnno = this._jvmTypesBuilder.toAnnotation(prop, AttributeOverride.class);
        this._annotationExtension.addAnnAttr(overrideAttributeAnno, f, "name", this._modelExtensions.toName(f));
        {
          final JvmAnnotationReference colAnno = this._jvmTypesBuilder.toAnnotation(prop, Column.class);
          String _name = this._modelExtensions.toName(prop);
          String _plus = (_name + "_");
          String _name_1 = this._modelExtensions.toName(f);
          this._annotationExtension.addAnnAttr(colAnno, f, "name", (_plus + _name_1).toUpperCase());
          this._annotationExtension.addAnnAttr(overrideAttributeAnno, f, "column", colAnno);
        }
        collectedAttributes.add(overrideAttributeAnno);
      } else {
        if ((f instanceof LBeanReference)) {
          final LType type = ((LBeanReference)f).getType();
          boolean _matched = false;
          if (type instanceof LEntity) {
            _matched=true;
            final JvmAnnotationReference overrideAssociationAnno = this._jvmTypesBuilder.toAnnotation(prop, AssociationOverride.class);
            this._annotationExtension.addAnnAttr(overrideAssociationAnno, f, "name", this._modelExtensions.toName(f));
            {
              final JvmAnnotationReference colAnno = this._jvmTypesBuilder.toAnnotation(prop, JoinColumn.class);
              String _name = this._modelExtensions.toName(prop);
              String _plus = (_name + "_");
              String _name_1 = this._modelExtensions.toName(f);
              this._annotationExtension.addAnnAttr(colAnno, f, "name", (_plus + _name_1).toUpperCase());
              this._annotationExtension.addAnnAttr(overrideAssociationAnno, f, "joinColumns", colAnno);
            }
            collectedAssocations.add(overrideAssociationAnno);
          }
          if (!_matched) {
            if (type instanceof LBean) {
              _matched=true;
              String _name = this._modelExtensions.toName(prop);
              String _plus = (_name + "_");
              String _name_1 = this._modelExtensions.toName(f);
              this.collectNestedAttributeOverride(((LBean)type), collectedAttributes, this._modelExtensions.toName(f), 
                (_plus + _name_1).toUpperCase());
            }
          }
        }
      }
    }
    boolean _isEmpty = collectedAttributes.isEmpty();
    boolean _not = (!_isEmpty);
    if (_not) {
      final JvmAnnotationReference overrideAttributesAnno = this._jvmTypesBuilder.toAnnotation(prop, AttributeOverrides.class);
      final JvmAnnotationReference[] result = collectedAttributes.<JvmAnnotationReference>toArray(new JvmAnnotationReference[collectedAttributes.size()]);
      this._annotationExtension.addAnnAttr(overrideAttributesAnno, prop, "value", result);
      this._annotationExtension.addAnno(prop, jvmField, overrideAttributesAnno);
    }
    boolean _isEmpty_1 = collectedAssocations.isEmpty();
    boolean _not_1 = (!_isEmpty_1);
    if (_not_1) {
      final JvmAnnotationReference overrideAssociationsAnno = this._jvmTypesBuilder.toAnnotation(prop, AssociationOverrides.class);
      final JvmAnnotationReference[] result_1 = collectedAssocations.<JvmAnnotationReference>toArray(
        new JvmAnnotationReference[collectedAssocations.size()]);
      this._annotationExtension.addAnnAttr(overrideAssociationsAnno, prop, "value", result_1);
      this._annotationExtension.addAnno(prop, jvmField, overrideAssociationsAnno);
    }
  }
  
  /**
   * Collects all nested embedded fields to be overridden
   */
  protected void collectNestedAttributeOverride(final LBean bean, final List<JvmAnnotationReference> collectedReferences, final String propertyPath, final String persistencePath) {
    boolean _equals = Objects.equal(bean, null);
    if (_equals) {
      return;
    }
    final Function1<LBeanFeature, Boolean> _function = (LBeanFeature it) -> {
      boolean _isToMany = this._modelExtensions.isToMany(it);
      return Boolean.valueOf((!_isToMany));
    };
    Iterable<LBeanFeature> _filter = IterableExtensions.<LBeanFeature>filter(bean.getAllFeatures(), _function);
    for (final LBeanFeature f : _filter) {
      if ((f instanceof LBeanAttribute)) {
        final JvmAnnotationReference overrideAttributeAnno = this._jvmTypesBuilder.toAnnotation(bean, AttributeOverride.class);
        String _name = this._modelExtensions.toName(f);
        String _plus = ((propertyPath + ".") + _name);
        this._annotationExtension.addAnnAttr(overrideAttributeAnno, f, "name", _plus);
        {
          final JvmAnnotationReference colAnno = this._jvmTypesBuilder.toAnnotation(bean, Column.class);
          String _name_1 = this._modelExtensions.toName(f);
          this._annotationExtension.addAnnAttr(colAnno, f, "name", ((persistencePath + "_") + _name_1).toUpperCase());
          this._annotationExtension.addAnnAttr(overrideAttributeAnno, f, "column", colAnno);
        }
        collectedReferences.add(overrideAttributeAnno);
      } else {
        if ((f instanceof LBeanReference)) {
          LFeature _opposite = ((LBeanReference)f).getOpposite();
          LType _type = null;
          if (_opposite!=null) {
            _type=this._modelExtensions.type(_opposite);
          }
          final LType oppositeType = _type;
          final LType type = ((LBeanReference)f).getType();
          boolean _matched = false;
          if (type instanceof LEntity) {
            _matched=true;
          }
          if (!_matched) {
            if (type instanceof LBean) {
              _matched=true;
              boolean _notEquals = (!Objects.equal(oppositeType, bean));
              if (_notEquals) {
                String _name_1 = this._modelExtensions.toName(f);
                String _plus_1 = ((propertyPath + ".") + _name_1);
                String _upperCase = this._modelExtensions.toName(f).toUpperCase();
                String _plus_2 = ((persistencePath + "_") + _upperCase);
                this.collectNestedAttributeOverride(((LBean)type), collectedReferences, _plus_1, _plus_2);
              }
            }
          }
        }
      }
    }
  }
  
  protected void _internalProcessAnnotation(final LBeanAttribute prop, final JvmField jvmField) {
    final Function1<LAnnotationDef, Boolean> _function = (LAnnotationDef it) -> {
      boolean _isExclude = it.isExclude();
      return Boolean.valueOf((!_isExclude));
    };
    final Function1<LAnnotationDef, XAnnotation> _function_1 = (LAnnotationDef it) -> {
      return it.getAnnotation();
    };
    this._jvmTypesBuilder.addAnnotations(jvmField, IterableExtensions.<LAnnotationDef, XAnnotation>map(IterableExtensions.<LAnnotationDef>filter(prop.getResolvedAnnotations(), _function), _function_1));
    boolean _isTransient = prop.isTransient();
    if (_isTransient) {
      EList<JvmAnnotationReference> _annotations = jvmField.getAnnotations();
      JvmAnnotationReference _annotation = this._jvmTypesBuilder.toAnnotation(prop, Transient.class);
      this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations, _annotation);
    }
    boolean basicAdded = false;
    LScalarType _type = prop.getType();
    if ((_type instanceof LDataType)) {
      LScalarType _type_1 = prop.getType();
      final LDataType datatype = ((LDataType) _type_1);
      boolean _isDate = datatype.isDate();
      if (_isDate) {
        this._annotationExtension.addAnno(prop, jvmField, this._jvmTypesBuilder.toAnnotation(prop, Basic.class));
        basicAdded = true;
        final JvmAnnotationReference temp = this._jvmTypesBuilder.toAnnotation(prop, Temporal.class);
        LDateType _dateType = datatype.getDateType();
        if (_dateType != null) {
          switch (_dateType) {
            case DATE:
              this._annotationExtension.addAnnAttr(temp, prop, "value", TemporalType.DATE);
              break;
            case TIME:
              this._annotationExtension.addAnnAttr(temp, prop, "value", TemporalType.TIME);
              break;
            case TIMESTAMP:
              this._annotationExtension.addAnnAttr(temp, prop, "value", TemporalType.TIMESTAMP);
              break;
            default:
              break;
          }
        }
        this._annotationExtension.addAnno(prop, jvmField, temp);
      } else {
        boolean _isAsBlob = datatype.isAsBlob();
        if (_isAsBlob) {
          this._annotationExtension.addAnno(prop, jvmField, this._jvmTypesBuilder.toAnnotation(prop, Lob.class));
          final JvmAnnotationReference basic = this._jvmTypesBuilder.toAnnotation(prop, Basic.class);
          this._annotationExtension.addAnnAttr(basic, prop, "fetch", FetchType.LAZY);
          this._annotationExtension.addAnno(prop, jvmField, basic);
          basicAdded = true;
        }
      }
      boolean _isFiltering = prop.isFiltering();
      if (_isFiltering) {
        this._jvmTypesBuilder.toAnnotation(prop, Filter.class);
      }
      boolean _isRangeFiltering = prop.isRangeFiltering();
      if (_isRangeFiltering) {
        this._jvmTypesBuilder.toAnnotation(prop, Range.class);
      }
    }
    if ((!basicAdded)) {
      this._annotationExtension.addAnno(prop, jvmField, this._jvmTypesBuilder.toAnnotation(prop, Basic.class));
      basicAdded = true;
    }
    boolean _isToMany = this._modelExtensions.isToMany(prop);
    if (_isToMany) {
      final JvmAnnotationReference ann = this._jvmTypesBuilder.toAnnotation(prop, ElementCollection.class);
      this._annotationExtension.addAnno(prop, jvmField, ann);
    }
    this.toPropertiesAnnotation(prop, this.mergeKeyAndValues(prop), jvmField);
    this.toConstraintAnnotations(prop, jvmField);
  }
  
  protected void _toConstraintAnnotations(final LBeanAttribute prop, final JvmField jvmField) {
    boolean _isValidAllowed = this.isValidAllowed(prop.getType());
    if (_isValidAllowed) {
      this.toValidAnnotation(prop, jvmField);
    }
    EList<LDatatypeConstraint> _constraints = prop.getConstraints();
    for (final LDatatypeConstraint c : _constraints) {
      this.toConstraintAnnotation(c, jvmField);
    }
    boolean _isEmpty = prop.getConstraints().isEmpty();
    if (_isEmpty) {
      super.toDatatypeBasedConstraintAnnotations(prop, jvmField);
    }
  }
  
  protected void _toConstraintAnnotations(final LBeanReference prop, final JvmField jvmField) {
    if (((prop.getType() instanceof LBean) && (!this._modelExtensions.getBounds(prop).isToMany()))) {
      this.toValidAnnotation(prop, jvmField);
    }
    EList<LDatatypeConstraint> _constraints = prop.getConstraints();
    for (final LDatatypeConstraint c : _constraints) {
      this.toConstraintAnnotation(c, jvmField);
    }
  }
  
  protected void _toConstraintAnnotations(final LEntityAttribute prop, final JvmField jvmField) {
    boolean _isValidAllowed = this.isValidAllowed(prop.getType());
    if (_isValidAllowed) {
      this.toValidAnnotation(prop, jvmField);
    }
    EList<LDatatypeConstraint> _constraints = prop.getConstraints();
    for (final LDatatypeConstraint c : _constraints) {
      this.toConstraintAnnotation(c, jvmField);
    }
    boolean _isEmpty = prop.getConstraints().isEmpty();
    if (_isEmpty) {
      super.toDatatypeBasedConstraintAnnotations(prop, jvmField);
    }
  }
  
  protected void _toConstraintAnnotations(final LEntityReference prop, final JvmField jvmField) {
    if ((prop.isCascading() && (!this._modelExtensions.getBounds(prop).isToMany()))) {
      this.toValidAnnotation(prop, jvmField);
    }
    EList<LDatatypeConstraint> _constraints = prop.getConstraints();
    for (final LDatatypeConstraint c : _constraints) {
      this.toConstraintAnnotation(c, jvmField);
    }
  }
  
  protected void _internalProcessAnnotation(final LBeanReference prop, final JvmField jvmField) {
    final Function1<LAnnotationDef, Boolean> _function = (LAnnotationDef it) -> {
      boolean _isExclude = it.isExclude();
      return Boolean.valueOf((!_isExclude));
    };
    final Function1<LAnnotationDef, XAnnotation> _function_1 = (LAnnotationDef it) -> {
      return it.getAnnotation();
    };
    this._jvmTypesBuilder.addAnnotations(jvmField, IterableExtensions.<LAnnotationDef, XAnnotation>map(IterableExtensions.<LAnnotationDef>filter(prop.getResolvedAnnotations(), _function), _function_1));
    LType _type = prop.getType();
    if ((_type instanceof LEntity)) {
      boolean _isToMany = this._modelExtensions.isToMany(prop);
      if (_isToMany) {
        boolean _isToMany_1 = this._modelExtensions.isToMany(prop.getOpposite());
        if (_isToMany_1) {
          this.addManyToManyAnno(prop, jvmField);
        } else {
          this.addOneToManyAnno(prop, jvmField);
        }
      } else {
        final LFeature opposite = this._modelExtensions.getResolvedOpposite(prop);
        if (((!Objects.equal(opposite, null)) && (!this._modelExtensions.isToMany(opposite)))) {
          this.addOneToOneAnno(prop, jvmField);
        } else {
          this.addManyToOneAnno(prop, jvmField);
        }
      }
      LResultFilters _resultFilters = prop.getResultFilters();
      boolean _tripleNotEquals = (_resultFilters != null);
      if (_tripleNotEquals) {
        this.addConstraintsAnno(prop.getResultFilters(), jvmField);
      }
    } else {
      EList<JvmAnnotationReference> _annotations = jvmField.getAnnotations();
      JvmAnnotationReference _annotation = this._jvmTypesBuilder.toAnnotation(prop, Basic.class);
      this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations, _annotation);
      this._annotationExtension.addAnno(prop, jvmField, this._jvmTypesBuilder.toAnnotation(prop, Embedded.class));
      boolean _isToMany_2 = this._modelExtensions.isToMany(prop);
      if (_isToMany_2) {
        this._annotationExtension.addAnno(prop, jvmField, this._jvmTypesBuilder.toAnnotation(prop, ElementCollection.class));
      }
    }
    this.toPropertiesAnnotation(prop, this.mergeKeyAndValues(prop), jvmField);
    this.toConstraintAnnotations(prop, jvmField);
  }
  
  private boolean addOneToManyAnno(final LReference prop, final JvmAnnotationTarget jvmAnnTarget) {
    boolean _xblockexpression = false;
    {
      final JvmAnnotationReference col = this._jvmTypesBuilder.toAnnotation(prop, JoinColumn.class);
      this._annotationExtension.addAnnAttr(col, prop, "name", this._namingExtensions.toColumnName(prop));
      boolean _isRequired = this._modelExtensions.getBounds(prop).isRequired();
      if (_isRequired) {
        this._annotationExtension.addAnnAttr(col, prop, "nullable", Boolean.valueOf(false));
      }
      this._annotationExtension.addAnno(prop, jvmAnnTarget, col);
      final JvmAnnotationReference ann = this._jvmTypesBuilder.toAnnotation(prop, OneToMany.class);
      LFeature _opposite = this._modelExtensions.opposite(prop);
      boolean _tripleNotEquals = (_opposite != null);
      if (_tripleNotEquals) {
        String _name = this._modelExtensions.opposite(prop).getName();
        boolean _tripleEquals = (_name == null);
        if (_tripleEquals) {
          this._annotationExtension.addAnnAttr(ann, prop, "mappedBy", "");
        } else {
          this._annotationExtension.addAnnAttr(ann, prop, "mappedBy", this._modelExtensions.opposite(prop).getName());
        }
      }
      final ArrayList<CascadeType> cascaded = CollectionLiterals.<CascadeType>newArrayList();
      boolean _isCascadeRemove = prop.isCascadeRemove();
      if (_isCascadeRemove) {
        cascaded.add(CascadeType.REMOVE);
        boolean _isCascadeMergePersist = prop.isCascadeMergePersist();
        if (_isCascadeMergePersist) {
          cascaded.add(CascadeType.MERGE);
          cascaded.add(CascadeType.PERSIST);
        }
        boolean _isCascadeRefresh = prop.isCascadeRefresh();
        if (_isCascadeRefresh) {
          cascaded.add(CascadeType.REFRESH);
        }
        this._annotationExtension.addAnnAttr(ann, prop, "cascade", cascaded.<Enum>toArray(new Enum[((Object[])Conversions.unwrapArray(cascaded, Object.class)).length]));
        this._annotationExtension.addAnnAttr(ann, prop, "orphanRemoval", Boolean.valueOf(true));
        this._annotationExtension.addAnnAttr(ann, prop, "fetch", FetchType.EAGER);
      } else {
        boolean _isCascadeMergePersist_1 = prop.isCascadeMergePersist();
        if (_isCascadeMergePersist_1) {
          cascaded.add(CascadeType.MERGE);
          cascaded.add(CascadeType.PERSIST);
          boolean _isCascadeRefresh_1 = prop.isCascadeRefresh();
          if (_isCascadeRefresh_1) {
            cascaded.add(CascadeType.REFRESH);
          }
          this._annotationExtension.addAnnAttr(ann, prop, "cascade", cascaded.<Enum>toArray(new Enum[((Object[])Conversions.unwrapArray(cascaded, Object.class)).length]));
          this._annotationExtension.addAnnAttr(ann, prop, "orphanRemoval", Boolean.valueOf(false));
          this._annotationExtension.addAnnAttr(ann, prop, "fetch", FetchType.LAZY);
        } else {
          boolean _isCascadeRefresh_2 = prop.isCascadeRefresh();
          if (_isCascadeRefresh_2) {
            cascaded.add(CascadeType.REFRESH);
            this._annotationExtension.addAnnAttr(ann, prop, "cascade", cascaded.<Enum>toArray(new Enum[((Object[])Conversions.unwrapArray(cascaded, Object.class)).length]));
            this._annotationExtension.addAnnAttr(ann, prop, "orphanRemoval", Boolean.valueOf(false));
            this._annotationExtension.addAnnAttr(ann, prop, "fetch", FetchType.LAZY);
          }
        }
      }
      this._annotationExtension.addAnno(prop, jvmAnnTarget, ann);
      boolean _isIsGrouped = prop.isIsGrouped();
      if (_isIsGrouped) {
        final JvmAnnotationReference groupAnnotation = this._jvmTypesBuilder.toAnnotation(prop, UIGroup.class);
        this._annotationExtension.addAnnAttr(groupAnnotation, prop, "name", prop.getGroupName());
        this._annotationExtension.addAnno(prop, jvmAnnTarget, groupAnnotation);
      }
      boolean _isAsGrid = prop.isAsGrid();
      if (_isAsGrid) {
        this._annotationExtension.addAnno(prop, jvmAnnTarget, this._jvmTypesBuilder.toAnnotation(prop, AsGrid.class));
      }
      boolean _xifexpression = false;
      boolean _isAsTable = prop.isAsTable();
      if (_isAsTable) {
        _xifexpression = this._annotationExtension.addAnno(prop, jvmAnnTarget, this._jvmTypesBuilder.toAnnotation(prop, AsTable.class));
      }
      _xblockexpression = _xifexpression;
    }
    return _xblockexpression;
  }
  
  private Object addManyToManyAnno(final LReference prop, final JvmAnnotationTarget jvmAnnTarget) {
    return null;
  }
  
  private boolean addManyToOneAnno(final LReference prop, final JvmAnnotationTarget jvmAnnTarget) {
    boolean _xblockexpression = false;
    {
      boolean _isHistorized = prop.isHistorized();
      if (_isHistorized) {
        this._annotationExtension.addAnno(prop, jvmAnnTarget, this._jvmTypesBuilder.toAnnotation(prop, HistReference.class));
      }
      final JvmAnnotationReference manyToOne = this._jvmTypesBuilder.toAnnotation(prop, ManyToOne.class);
      boolean _isRequired = this._modelExtensions.getBounds(prop).isRequired();
      if (_isRequired) {
        boolean _isRequired_1 = this._modelExtensions.getBounds(prop).isRequired();
        boolean _not = (!_isRequired_1);
        this._annotationExtension.addAnnAttr(manyToOne, prop, "optional", Boolean.valueOf(_not));
      }
      this._annotationExtension.addAnnAttr(manyToOne, prop, "fetch", FetchType.LAZY);
      final LFeature opposite = this._modelExtensions.getResolvedOpposite(prop);
      this._annotationExtension.addAnno(prop, jvmAnnTarget, manyToOne);
      boolean shouldCreateHistorized = false;
      final LType targetType = this._modelExtensions.type(prop);
      if ((targetType instanceof LEntity)) {
        boolean _isHistorizedOrTimedependentWithParent = ((LEntity)targetType).isHistorizedOrTimedependentWithParent();
        if (_isHistorizedOrTimedependentWithParent) {
          shouldCreateHistorized = true;
        }
      }
      if ((!shouldCreateHistorized)) {
        final JvmAnnotationReference joinColumn = this._jvmTypesBuilder.toAnnotation(prop, JoinColumn.class);
        this._annotationExtension.addAnnAttr(joinColumn, prop, "name", this._namingExtensions.toColumnName(prop));
        boolean _isRequired_2 = this._modelExtensions.getBounds(prop).isRequired();
        if (_isRequired_2) {
          this._annotationExtension.addAnnAttr(joinColumn, prop, "nullable", Boolean.valueOf(false));
        }
        this._annotationExtension.addAnno(prop, jvmAnnTarget, joinColumn);
      } else {
        final JvmAnnotationReference joinColumns = this._jvmTypesBuilder.toAnnotation(prop, JoinColumns.class);
        this._annotationExtension.addAnno(prop, jvmAnnTarget, joinColumns);
        final ArrayList<JvmAnnotationReference> columns = CollectionLiterals.<JvmAnnotationReference>newArrayList();
        final JvmAnnotationReference idJoinColumn = this._jvmTypesBuilder.toAnnotation(prop, JoinColumn.class);
        String _columnName = this._namingExtensions.toColumnName(prop);
        String _plus = (_columnName + "_ID");
        this._annotationExtension.addAnnAttr(idJoinColumn, prop, "name", _plus);
        this._annotationExtension.addAnnAttr(idJoinColumn, prop, "referencedColumnName", "ID");
        boolean _isRequired_3 = this._modelExtensions.getBounds(prop).isRequired();
        if (_isRequired_3) {
          this._annotationExtension.addAnnAttr(idJoinColumn, prop, "nullable", Boolean.valueOf(false));
        }
        columns.add(idJoinColumn);
        final JvmAnnotationReference validFromJoinColumn = this._jvmTypesBuilder.toAnnotation(prop, JoinColumn.class);
        String _columnName_1 = this._namingExtensions.toColumnName(prop);
        String _plus_1 = (_columnName_1 + "_VALIDFROM");
        this._annotationExtension.addAnnAttr(validFromJoinColumn, prop, "name", _plus_1);
        this._annotationExtension.addAnnAttr(validFromJoinColumn, prop, "referencedColumnName", "VALIDFROM");
        boolean _isRequired_4 = this._modelExtensions.getBounds(prop).isRequired();
        if (_isRequired_4) {
          this._annotationExtension.addAnnAttr(validFromJoinColumn, prop, "nullable", Boolean.valueOf(false));
        }
        columns.add(validFromJoinColumn);
        this._annotationExtension.addAnnAttr(joinColumns, prop, "value", 
          columns.<JvmAnnotationReference>toArray(new JvmAnnotationReference[((Object[])Conversions.unwrapArray(columns, Object.class)).length]));
      }
      boolean _isSideKick = prop.isSideKick();
      if (_isSideKick) {
        this._annotationExtension.addAnno(prop, jvmAnnTarget, this._jvmTypesBuilder.toAnnotation(prop, SideKick.class));
      }
      boolean _isReferenceHidden = prop.isReferenceHidden();
      if (_isReferenceHidden) {
        this._annotationExtension.addAnno(prop, jvmAnnTarget, this._jvmTypesBuilder.toAnnotation(prop, Hidden.class));
      }
      boolean _xifexpression = false;
      boolean _isReferenceReadOnly = prop.isReferenceReadOnly();
      if (_isReferenceReadOnly) {
        _xifexpression = this._annotationExtension.addAnno(prop, jvmAnnTarget, this._jvmTypesBuilder.toAnnotation(prop, ReadOnly.class));
      }
      _xblockexpression = _xifexpression;
    }
    return _xblockexpression;
  }
  
  private boolean addOneToOneAnno(final LReference prop, final JvmAnnotationTarget jvmAnnTarget) {
    boolean _xblockexpression = false;
    {
      final JvmAnnotationReference oneToOne = this._jvmTypesBuilder.toAnnotation(prop, OneToOne.class);
      boolean _isRequired = this._modelExtensions.getBounds(prop).isRequired();
      if (_isRequired) {
        boolean _isRequired_1 = this._modelExtensions.getBounds(prop).isRequired();
        boolean _not = (!_isRequired_1);
        this._annotationExtension.addAnnAttr(oneToOne, prop, "optional", Boolean.valueOf(_not));
      }
      final LFeature opposite = this._modelExtensions.getResolvedOpposite(prop);
      if (((!Objects.equal(opposite, null)) && (prop.isCascadeMergePersist() || prop.isCascadeRemove()))) {
        String _xifexpression = null;
        String _name = opposite.getName();
        boolean _notEquals = (!Objects.equal(_name, null));
        if (_notEquals) {
          _xifexpression = opposite.getName();
        } else {
          _xifexpression = "";
        }
        this._annotationExtension.addAnnAttr(oneToOne, prop, "mappedBy", _xifexpression);
      }
      final ArrayList<CascadeType> cascaded = CollectionLiterals.<CascadeType>newArrayList();
      boolean _isCascadeRemove = prop.isCascadeRemove();
      if (_isCascadeRemove) {
        cascaded.add(CascadeType.REMOVE);
        boolean _isCascadeMergePersist = prop.isCascadeMergePersist();
        if (_isCascadeMergePersist) {
          cascaded.add(CascadeType.MERGE);
          cascaded.add(CascadeType.PERSIST);
        }
        this._annotationExtension.addAnnAttr(oneToOne, prop, "cascade", cascaded.<Enum>toArray(new Enum[((Object[])Conversions.unwrapArray(cascaded, Object.class)).length]));
        this._annotationExtension.addAnnAttr(oneToOne, prop, "orphanRemoval", Boolean.valueOf(true));
        this._annotationExtension.addAnnAttr(oneToOne, prop, "fetch", FetchType.EAGER);
      } else {
        boolean _isCascadeMergePersist_1 = prop.isCascadeMergePersist();
        if (_isCascadeMergePersist_1) {
          cascaded.add(CascadeType.MERGE);
          cascaded.add(CascadeType.PERSIST);
          this._annotationExtension.addAnnAttr(oneToOne, prop, "cascade", cascaded.<Enum>toArray(new Enum[((Object[])Conversions.unwrapArray(cascaded, Object.class)).length]));
          this._annotationExtension.addAnnAttr(oneToOne, prop, "orphanRemoval", Boolean.valueOf(false));
          this._annotationExtension.addAnnAttr(oneToOne, prop, "fetch", FetchType.LAZY);
        }
      }
      this._annotationExtension.addAnno(prop, jvmAnnTarget, oneToOne);
      if ((((opposite != null) && (opposite instanceof LEntityReference)) && ((LEntityReference) opposite).isCascading())) {
        final JvmAnnotationReference joinColumn = this._jvmTypesBuilder.toAnnotation(prop, JoinColumn.class);
        this._annotationExtension.addAnnAttr(joinColumn, prop, "name", this._namingExtensions.toColumnName(prop));
        boolean _isRequired_2 = this._modelExtensions.getBounds(prop).isRequired();
        if (_isRequired_2) {
          this._annotationExtension.addAnnAttr(joinColumn, prop, "nullable", Boolean.valueOf(false));
        }
        this._annotationExtension.addAnno(prop, jvmAnnTarget, joinColumn);
      }
      boolean _isSideKick = prop.isSideKick();
      if (_isSideKick) {
        this._annotationExtension.addAnno(prop, jvmAnnTarget, this._jvmTypesBuilder.toAnnotation(prop, SideKick.class));
      }
      boolean _isReferenceHidden = prop.isReferenceHidden();
      if (_isReferenceHidden) {
        this._annotationExtension.addAnno(prop, jvmAnnTarget, this._jvmTypesBuilder.toAnnotation(prop, Hidden.class));
      }
      boolean _xifexpression_1 = false;
      boolean _isReferenceReadOnly = prop.isReferenceReadOnly();
      if (_isReferenceReadOnly) {
        _xifexpression_1 = this._annotationExtension.addAnno(prop, jvmAnnTarget, this._jvmTypesBuilder.toAnnotation(prop, ReadOnly.class));
      }
      _xblockexpression = _xifexpression_1;
    }
    return _xblockexpression;
  }
  
  public void addConstraintsAnno(final LResultFilters constraints, final JvmField jvmField) {
    final Function1<LResultFilter, Boolean> _function = (LResultFilter it) -> {
      return Boolean.valueOf((it instanceof LAttributeMatchingConstraint));
    };
    boolean _isEmpty = IterableExtensions.isEmpty(IterableExtensions.<LResultFilter>filter(constraints.getResultFilters(), _function));
    boolean _not = (!_isEmpty);
    if (_not) {
      final ArrayList<JvmAnnotationReference> innerAnnotations = CollectionLiterals.<JvmAnnotationReference>newArrayList();
      final Function1<LResultFilter, Boolean> _function_1 = (LResultFilter it) -> {
        return Boolean.valueOf((it instanceof LAttributeMatchingConstraint));
      };
      final Function1<LResultFilter, LAttributeMatchingConstraint> _function_2 = (LResultFilter it) -> {
        return ((LAttributeMatchingConstraint) it);
      };
      final Consumer<LAttributeMatchingConstraint> _function_3 = (LAttributeMatchingConstraint it) -> {
        final JvmAnnotationReference innerAnno = this._jvmTypesBuilder.toAnnotation(constraints, TargetEnumConstraint.class);
        this._annotationExtension.addAnnAttr(innerAnno, it, "targetProperty", it.getAttribute().getName());
        this._annotationExtension.addAnnAttr(innerAnno, it, "enumClass", this._modelExtensions.toTypeReference(it.getAttribute()));
        this._annotationExtension.addAnnAttr(innerAnno, it, "enumLiteral", it.getMatchingLiteral().getName());
        innerAnnotations.add(innerAnno);
      };
      IterableExtensions.<LResultFilter, LAttributeMatchingConstraint>map(IterableExtensions.<LResultFilter>filter(constraints.getResultFilters(), _function_1), _function_2).forEach(_function_3);
      final JvmAnnotationReference mainAnno = this._jvmTypesBuilder.toAnnotation(constraints, TargetEnumConstraints.class);
      this._annotationExtension.addAnnAttr(mainAnno, constraints, "constraints", 
        innerAnnotations.<JvmAnnotationReference>toArray(new JvmAnnotationReference[((Object[])Conversions.unwrapArray(innerAnnotations, Object.class)).length]));
      EList<JvmAnnotationReference> _annotations = jvmField.getAnnotations();
      this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations, mainAnno);
    }
  }
  
  protected boolean _addDisposeFieldAnnotation(final LEntity entity, final JvmField field) {
    boolean _xblockexpression = false;
    {
      final JvmAnnotationReference anno = this._jvmTypesBuilder.toAnnotation(entity, Transient.class);
      this._annotationExtension.addAnno(entity, field, anno);
      _xblockexpression = this._annotationExtension.addAnno(entity, field, this._jvmTypesBuilder.toAnnotation(entity, Dispose.class));
    }
    return _xblockexpression;
  }
  
  protected boolean _addDisposeFieldAnnotation(final LBean entity, final JvmField field) {
    boolean _xblockexpression = false;
    {
      final JvmAnnotationReference anno = this._jvmTypesBuilder.toAnnotation(entity, Transient.class);
      this._annotationExtension.addAnno(entity, field, anno);
      _xblockexpression = this._annotationExtension.addAnno(entity, field, this._jvmTypesBuilder.toAnnotation(entity, Dispose.class));
    }
    return _xblockexpression;
  }
  
  protected boolean _addDisposeFieldAnnotation(final LEntity entity, final JvmOperation op) {
    return this._annotationExtension.addAnno(entity, op, this._jvmTypesBuilder.toAnnotation(entity, Dispose.class));
  }
  
  protected boolean _addDisposeFieldAnnotation(final LBean entity, final JvmOperation op) {
    return this._annotationExtension.addAnno(entity, op, this._jvmTypesBuilder.toAnnotation(entity, Dispose.class));
  }
  
  protected boolean _isValidAllowed(final LBean type) {
    return true;
  }
  
  /**
   * @noreference This method is called by the framework
   * @nooverride
   */
  public void setContext(final Resource resource) {
    InputOutput.println();
  }
  
  protected void internalProcessAnnotation(final LAnnotationTarget stateClass, final JvmMember jvmField) {
    if (stateClass instanceof LEnum
         && jvmField instanceof JvmEnumerationType) {
      _internalProcessAnnotation((LEnum)stateClass, (JvmEnumerationType)jvmField);
      return;
    } else if (stateClass instanceof LStateClass
         && jvmField instanceof JvmEnumerationType) {
      _internalProcessAnnotation((LStateClass)stateClass, (JvmEnumerationType)jvmField);
      return;
    } else if (stateClass instanceof LStateClass
         && jvmField instanceof JvmField) {
      _internalProcessAnnotation((LStateClass)stateClass, (JvmField)jvmField);
      return;
    } else if (stateClass instanceof LBean
         && jvmField instanceof JvmGenericType) {
      _internalProcessAnnotation((LBean)stateClass, (JvmGenericType)jvmField);
      return;
    } else if (stateClass instanceof LBeanAttribute
         && jvmField instanceof JvmField) {
      _internalProcessAnnotation((LBeanAttribute)stateClass, (JvmField)jvmField);
      return;
    } else if (stateClass instanceof LBeanReference
         && jvmField instanceof JvmField) {
      _internalProcessAnnotation((LBeanReference)stateClass, (JvmField)jvmField);
      return;
    } else if (stateClass instanceof LEntity
         && jvmField instanceof JvmGenericType) {
      _internalProcessAnnotation((LEntity)stateClass, (JvmGenericType)jvmField);
      return;
    } else if (stateClass instanceof LEntityAttribute
         && jvmField instanceof JvmField) {
      _internalProcessAnnotation((LEntityAttribute)stateClass, (JvmField)jvmField);
      return;
    } else if (stateClass instanceof LEntityReference
         && jvmField instanceof JvmField) {
      _internalProcessAnnotation((LEntityReference)stateClass, (JvmField)jvmField);
      return;
    } else if (stateClass instanceof LOperation
         && jvmField instanceof JvmField) {
      _internalProcessAnnotation((LOperation)stateClass, (JvmField)jvmField);
      return;
    } else if (stateClass instanceof LAttribute
         && jvmField instanceof JvmField) {
      _internalProcessAnnotation((LAttribute)stateClass, (JvmField)jvmField);
      return;
    } else if (stateClass instanceof LReference
         && jvmField instanceof JvmField) {
      _internalProcessAnnotation((LReference)stateClass, (JvmField)jvmField);
      return;
    } else if (stateClass instanceof org.eclipse.osbp.dsl.semantic.common.types.LOperation
         && jvmField instanceof JvmOperation) {
      _internalProcessAnnotation((org.eclipse.osbp.dsl.semantic.common.types.LOperation)stateClass, (JvmOperation)jvmField);
      return;
    } else if (stateClass instanceof LType
         && jvmField instanceof JvmGenericType) {
      _internalProcessAnnotation((LType)stateClass, (JvmGenericType)jvmField);
      return;
    } else {
      throw new IllegalArgumentException("Unhandled parameter types: " +
        Arrays.<Object>asList(stateClass, jvmField).toString());
    }
  }
  
  protected void processInheritance(final LEntityInheritanceStrategy strategy, final LEntity entity, final JvmGenericType jvmType) {
    if (strategy instanceof LTablePerClassStrategy) {
      _processInheritance((LTablePerClassStrategy)strategy, entity, jvmType);
      return;
    } else if (strategy instanceof LTablePerSubclassStrategy) {
      _processInheritance((LTablePerSubclassStrategy)strategy, entity, jvmType);
      return;
    } else {
      throw new IllegalArgumentException("Unhandled parameter types: " +
        Arrays.<Object>asList(strategy, entity, jvmType).toString());
    }
  }
  
  public void toConstraintAnnotations(final LFeature prop, final JvmField jvmField) {
    if (prop instanceof LBeanAttribute) {
      _toConstraintAnnotations((LBeanAttribute)prop, jvmField);
      return;
    } else if (prop instanceof LBeanReference) {
      _toConstraintAnnotations((LBeanReference)prop, jvmField);
      return;
    } else if (prop instanceof LEntityAttribute) {
      _toConstraintAnnotations((LEntityAttribute)prop, jvmField);
      return;
    } else if (prop instanceof LEntityReference) {
      _toConstraintAnnotations((LEntityReference)prop, jvmField);
      return;
    } else {
      throw new IllegalArgumentException("Unhandled parameter types: " +
        Arrays.<Object>asList(prop, jvmField).toString());
    }
  }
  
  public boolean addDisposeFieldAnnotation(final EObject entity, final JvmFeature op) {
    if (entity instanceof LBean
         && op instanceof JvmOperation) {
      return _addDisposeFieldAnnotation((LBean)entity, (JvmOperation)op);
    } else if (entity instanceof LEntity
         && op instanceof JvmOperation) {
      return _addDisposeFieldAnnotation((LEntity)entity, (JvmOperation)op);
    } else if (entity instanceof LBean
         && op instanceof JvmField) {
      return _addDisposeFieldAnnotation((LBean)entity, (JvmField)op);
    } else if (entity instanceof LEntity
         && op instanceof JvmField) {
      return _addDisposeFieldAnnotation((LEntity)entity, (JvmField)op);
    } else {
      throw new IllegalArgumentException("Unhandled parameter types: " +
        Arrays.<Object>asList(entity, op).toString());
    }
  }
  
  public boolean isValidAllowed(final LScalarType type) {
    if (type instanceof LDataType) {
      return _isValidAllowed((LDataType)type);
    } else if (type instanceof LBean) {
      return _isValidAllowed((LBean)type);
    } else if (type != null) {
      return _isValidAllowed(type);
    } else if (type == null) {
      return _isValidAllowed((Void)null);
    } else {
      throw new IllegalArgumentException("Unhandled parameter types: " +
        Arrays.<Object>asList(type).toString());
    }
  }
}
