/**
 * 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.dto.xtext.jvmmodel;

import com.google.common.collect.Iterables;
import com.google.inject.Inject;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.osbp.dsl.common.datatypes.IDto;
import org.eclipse.osbp.dsl.dto.lib.IMapper;
import org.eclipse.osbp.dsl.dto.lib.IMapperAccess;
import org.eclipse.osbp.dsl.dto.xtext.extensions.AnnotationExtension;
import org.eclipse.osbp.dsl.dto.xtext.extensions.DtoModelExtensions;
import org.eclipse.osbp.dsl.dto.xtext.extensions.DtoTypesBuilder;
import org.eclipse.osbp.dsl.dto.xtext.extensions.MethodNamingExtensions;
import org.eclipse.osbp.dsl.dto.xtext.jvmmodel.AnnotationCompiler;
import org.eclipse.osbp.dsl.semantic.common.types.LAttribute;
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.LOperation;
import org.eclipse.osbp.dsl.semantic.common.types.LReference;
import org.eclipse.osbp.dsl.semantic.common.types.LType;
import org.eclipse.osbp.dsl.semantic.common.types.LTypedPackage;
import org.eclipse.osbp.dsl.semantic.dto.LDto;
import org.eclipse.osbp.dsl.semantic.dto.LDtoAbstractAttribute;
import org.eclipse.osbp.dsl.semantic.dto.LDtoAbstractReference;
import org.eclipse.osbp.dsl.semantic.dto.LDtoFeature;
import org.eclipse.osbp.dsl.semantic.dto.LDtoMapper;
import org.eclipse.osbp.dsl.semantic.dto.LDtoOperation;
import org.eclipse.osbp.xtext.oxtype.logger.TimeLogger;
import org.eclipse.osbp.xtext.oxtype.resource.ExtendedModelInferrer;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtend2.lib.StringConcatenationClient;
import org.eclipse.xtext.common.types.JvmConstructor;
import org.eclipse.xtext.common.types.JvmDeclaredType;
import org.eclipse.xtext.common.types.JvmEnumerationLiteral;
import org.eclipse.xtext.common.types.JvmEnumerationType;
import org.eclipse.xtext.common.types.JvmField;
import org.eclipse.xtext.common.types.JvmFormalParameter;
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.JvmParameterizedTypeReference;
import org.eclipse.xtext.common.types.JvmType;
import org.eclipse.xtext.common.types.JvmTypeConstraint;
import org.eclipse.xtext.common.types.JvmTypeParameter;
import org.eclipse.xtext.common.types.JvmTypeReference;
import org.eclipse.xtext.common.types.JvmUpperBound;
import org.eclipse.xtext.common.types.TypesFactory;
import org.eclipse.xtext.common.types.util.TypeReferences;
import org.eclipse.xtext.naming.IQualifiedNameProvider;
import org.eclipse.xtext.xbase.XExpression;
import org.eclipse.xtext.xbase.jvmmodel.IJvmDeclaredTypeAcceptor;
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.Procedures.Procedure1;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * <p>Infers a JVM model from the source model.</p>
 * 
 * <p>The JVM model should contain all elements that would appear in the Java code
 * which is generated from the source model. Other models link against the JVM model rather than the source model.</p>
 */
@SuppressWarnings("all")
public class DtoGrammarJvmModelInferrer extends ExtendedModelInferrer {
  protected final Logger log = LoggerFactory.getLogger(this.getClass());
  
  @Inject
  private AnnotationCompiler annotationCompiler;
  
  @Inject
  @Extension
  private IQualifiedNameProvider _iQualifiedNameProvider;
  
  @Inject
  @Extension
  private DtoTypesBuilder _dtoTypesBuilder;
  
  @Inject
  @Extension
  private MethodNamingExtensions _methodNamingExtensions;
  
  @Inject
  @Extension
  private DtoModelExtensions _dtoModelExtensions;
  
  @Inject
  private TypeReferences references;
  
  @Inject
  private AnnotationExtension annExt;
  
  protected void _inferFullState(final JvmType type, final EObject element, final IJvmDeclaredTypeAcceptor acceptor, final boolean isPrelinkingPhase, final String selector) {
  }
  
  protected void _infer(final LDto dto, final IJvmDeclaredTypeAcceptor acceptor, final boolean isPrelinkingPhase) {
    final JvmGenericType type = this._dtoTypesBuilder.toJvmType(dto);
    this.inferDtoFullState(type, dto, acceptor, isPrelinkingPhase);
    LType _wrappedType = dto.getWrappedType();
    boolean _tripleNotEquals = (_wrappedType != null);
    if (_tripleNotEquals) {
      final JvmGenericType mapperType = this._dtoTypesBuilder.toMapperJvmType(dto);
      this.inferMapperFullState(mapperType, dto, acceptor, isPrelinkingPhase);
    }
  }
  
  protected void _inferTypesOnly(final LDto dto, final IJvmDeclaredTypeAcceptor acceptor, final boolean isPrelinkingPhase) {
    final JvmGenericType type = this._dtoTypesBuilder.toJvmType(dto);
    acceptor.<JvmGenericType>accept(type);
    LType _wrappedType = dto.getWrappedType();
    boolean _tripleNotEquals = (_wrappedType != null);
    if (_tripleNotEquals) {
      final JvmGenericType mapperType = this._dtoTypesBuilder.toMapperJvmType(dto);
      acceptor.<JvmGenericType>accept(mapperType);
    }
    this.inferTypesOnlyByDelegates(dto, acceptor, isPrelinkingPhase);
  }
  
  protected void _inferFullState(final JvmGenericType type, final LDto dto, final IJvmDeclaredTypeAcceptor acceptor, final boolean isPrelinkingPhase, final String selector) {
    boolean _equals = selector.equals("Mapper");
    if (_equals) {
      this.inferMapperFullState(type, dto, acceptor, isPrelinkingPhase);
    } else {
      this.inferDtoFullState(type, dto, acceptor, isPrelinkingPhase);
    }
  }
  
  public void inferDtoFullState(final JvmDeclaredType type, final LDto dto, final IJvmDeclaredTypeAcceptor acceptor, final boolean isPrelinkingPhase) {
    final Procedure1<JvmDeclaredType> _function = (JvmDeclaredType it) -> {
      final TimeLogger doInferLog = TimeLogger.start(it.getClass());
      it.setAbstract(dto.isAbstract());
      this.annotationCompiler.processAnnotation(dto, it);
      LAttribute idAttribute = null;
      JvmField idField = null;
      JvmField versionField = null;
      EObject _eContainer = dto.eContainer();
      this._dtoTypesBuilder.setFileHeader(it, this._dtoTypesBuilder.getDocumentation(((LTypedPackage) _eContainer)));
      this._dtoTypesBuilder.setDocumentation(it, this._dtoTypesBuilder.getDocumentation(dto));
      if (((dto.getSuperType() != null) && (!this._iQualifiedNameProvider.getFullyQualifiedName(dto.getSuperType()).toString().isEmpty()))) {
        EList<JvmTypeReference> _superTypes = it.getSuperTypes();
        JvmTypeReference _typeReference = this._dtoModelExtensions.toTypeReference(dto.getSuperType());
        this._dtoTypesBuilder.<JvmTypeReference>operator_add(_superTypes, _typeReference);
      }
      EList<JvmTypeReference> _superTypes_1 = it.getSuperTypes();
      JvmTypeReference _typeForName = this.references.getTypeForName(IDto.class, dto, null);
      this._dtoTypesBuilder.<JvmTypeReference>operator_add(_superTypes_1, _typeForName);
      EList<JvmTypeReference> _superTypes_2 = it.getSuperTypes();
      JvmTypeReference _typeForName_1 = this.references.getTypeForName(Serializable.class, dto, null);
      this._dtoTypesBuilder.<JvmTypeReference>operator_add(_superTypes_2, _typeForName_1);
      EList<JvmTypeReference> _superTypes_3 = it.getSuperTypes();
      JvmTypeReference _typeForName_2 = this.references.getTypeForName(PropertyChangeListener.class, dto, null);
      this._dtoTypesBuilder.<JvmTypeReference>operator_add(_superTypes_3, _typeForName_2);
      LDto _superType = dto.getSuperType();
      boolean _tripleEquals = (_superType == null);
      if (_tripleEquals) {
        EList<JvmMember> _members = it.getMembers();
        JvmField _propertyChangeSupportField = this._dtoTypesBuilder.toPropertyChangeSupportField(dto);
        this._dtoTypesBuilder.<JvmField>operator_add(_members, _propertyChangeSupportField);
        EList<JvmMember> _members_1 = it.getMembers();
        JvmField _diposeField = this._dtoTypesBuilder.toDiposeField(dto);
        this._dtoTypesBuilder.<JvmField>operator_add(_members_1, _diposeField);
        EList<JvmMember> _members_2 = it.getMembers();
        JvmField _dirtyField = this._dtoTypesBuilder.toDirtyField(dto);
        this._dtoTypesBuilder.<JvmField>operator_add(_members_2, _dirtyField);
      }
      EList<LDtoFeature> _features = dto.getFeatures();
      for (final LDtoFeature f : _features) {
        boolean _matched = false;
        if (f instanceof LAttribute) {
          _matched=true;
          if ((((!((LAttribute)f).isDerived()) && (this._iQualifiedNameProvider.getFullyQualifiedName(f) != null)) && (!this._iQualifiedNameProvider.getFullyQualifiedName(f).toString().isEmpty()))) {
            boolean _isIDorUUID = this._dtoModelExtensions.isIDorUUID(((LAttribute)f));
            if (_isIDorUUID) {
              idAttribute = ((LAttribute)f);
              idField = this._dtoTypesBuilder.toField(f);
              EList<JvmMember> _members_3 = it.getMembers();
              this._dtoTypesBuilder.<JvmField>operator_add(_members_3, idField);
            } else {
              boolean _isVersionAttr = ((LDtoAbstractAttribute) f).isVersionAttr();
              if (_isVersionAttr) {
                versionField = this._dtoTypesBuilder.toField(f);
                EList<JvmMember> _members_4 = it.getMembers();
                this._dtoTypesBuilder.<JvmField>operator_add(_members_4, versionField);
              } else {
                EList<JvmMember> _members_5 = it.getMembers();
                JvmField _field = this._dtoTypesBuilder.toField(f);
                this._dtoTypesBuilder.<JvmField>operator_add(_members_5, _field);
              }
            }
          }
        }
        if (!_matched) {
          if (f instanceof LReference) {
            _matched=true;
            if (((this._iQualifiedNameProvider.getFullyQualifiedName(f) != null) && (!this._iQualifiedNameProvider.getFullyQualifiedName(f).toString().isEmpty()))) {
              EList<JvmMember> _members_3 = it.getMembers();
              JvmField _field = this._dtoTypesBuilder.toField(f);
              this._dtoTypesBuilder.<JvmField>operator_add(_members_3, _field);
            }
          }
        }
      }
      EList<JvmMember> _members_3 = it.getMembers();
      final Procedure1<JvmConstructor> _function_1 = (JvmConstructor it_1) -> {
        StringConcatenationClient _client = new StringConcatenationClient() {
          @Override
          protected void appendTo(StringConcatenationClient.TargetStringConcatenation _builder) {
            _builder.append("installLazyCollections();");
          }
        };
        this._dtoTypesBuilder.setBody(it_1, _client);
      };
      JvmConstructor _constructor = this._dtoTypesBuilder.toConstructor(dto, _function_1);
      this._dtoTypesBuilder.<JvmConstructor>operator_add(_members_3, _constructor);
      EList<JvmMember> _members_4 = it.getMembers();
      JvmOperation _installLazyCollections = this._dtoTypesBuilder.toInstallLazyCollections(dto);
      this._dtoTypesBuilder.<JvmOperation>operator_add(_members_4, _installLazyCollections);
      LDto _superType_1 = dto.getSuperType();
      boolean _tripleEquals_1 = (_superType_1 == null);
      if (_tripleEquals_1) {
        EList<JvmMember> _members_5 = it.getMembers();
        JvmOperation _isDisposed = this._dtoTypesBuilder.toIsDisposed(dto);
        this._dtoTypesBuilder.<JvmOperation>operator_add(_members_5, _isDisposed);
        EList<JvmMember> _members_6 = it.getMembers();
        JvmOperation _addPropertyChangeListener = this._dtoTypesBuilder.toAddPropertyChangeListener(dto);
        this._dtoTypesBuilder.<JvmOperation>operator_add(_members_6, _addPropertyChangeListener);
        EList<JvmMember> _members_7 = it.getMembers();
        JvmOperation _addPropertyChangeListenerWithProperty = this._dtoTypesBuilder.toAddPropertyChangeListenerWithProperty(dto);
        this._dtoTypesBuilder.<JvmOperation>operator_add(_members_7, _addPropertyChangeListenerWithProperty);
        EList<JvmMember> _members_8 = it.getMembers();
        JvmOperation _removePropertyChangeListener = this._dtoTypesBuilder.toRemovePropertyChangeListener(dto);
        this._dtoTypesBuilder.<JvmOperation>operator_add(_members_8, _removePropertyChangeListener);
        EList<JvmMember> _members_9 = it.getMembers();
        JvmOperation _removePropertyChangeListenerWithProperty = this._dtoTypesBuilder.toRemovePropertyChangeListenerWithProperty(dto);
        this._dtoTypesBuilder.<JvmOperation>operator_add(_members_9, _removePropertyChangeListenerWithProperty);
        EList<JvmMember> _members_10 = it.getMembers();
        JvmOperation _firePropertyChange = this._dtoTypesBuilder.toFirePropertyChange(dto, (versionField != null));
        this._dtoTypesBuilder.<JvmOperation>operator_add(_members_10, _firePropertyChange);
        EList<JvmMember> _members_11 = it.getMembers();
        JvmOperation _isDirty = this._dtoTypesBuilder.toIsDirty(dto);
        this._dtoTypesBuilder.<JvmOperation>operator_add(_members_11, _isDirty);
        EList<JvmMember> _members_12 = it.getMembers();
        JvmOperation _setDirty = this._dtoTypesBuilder.toSetDirty(dto);
        this._dtoTypesBuilder.<JvmOperation>operator_add(_members_12, _setDirty);
      }
      EList<JvmMember> _members_13 = it.getMembers();
      JvmOperation _checkDisposed = this._dtoTypesBuilder.toCheckDisposed(dto);
      this._dtoTypesBuilder.<JvmOperation>operator_add(_members_13, _checkDisposed);
      EList<JvmMember> _members_14 = it.getMembers();
      JvmOperation _dispose = this._dtoTypesBuilder.toDispose(dto);
      this._dtoTypesBuilder.<JvmOperation>operator_add(_members_14, _dispose);
      EList<LDtoFeature> _features_1 = dto.getFeatures();
      for (final LDtoFeature f_1 : _features_1) {
        boolean _matched_1 = false;
        if (f_1 instanceof LAttribute) {
          _matched_1=true;
          EList<JvmMember> _members_15 = it.getMembers();
          JvmOperation _getter = this._dtoTypesBuilder.toGetter(f_1);
          this._dtoTypesBuilder.<JvmOperation>operator_add(_members_15, _getter);
          boolean _isDerived = ((LAttribute)f_1).isDerived();
          boolean _not = (!_isDerived);
          if (_not) {
            boolean _isToMany = this._dtoModelExtensions.isToMany(f_1);
            if (_isToMany) {
              EList<JvmMember> _members_16 = it.getMembers();
              JvmOperation _internalCollectionGetter = this._dtoTypesBuilder.toInternalCollectionGetter(f_1, this._dtoModelExtensions.toName(f_1));
              this._dtoTypesBuilder.<JvmOperation>operator_add(_members_16, _internalCollectionGetter);
              EList<JvmMember> _members_17 = it.getMembers();
              JvmOperation _adder = this._dtoTypesBuilder.toAdder(f_1, this._dtoModelExtensions.toName(f_1));
              this._dtoTypesBuilder.<JvmOperation>operator_add(_members_17, _adder);
              EList<JvmMember> _members_18 = it.getMembers();
              JvmOperation _remover = this._dtoTypesBuilder.toRemover(f_1, this._dtoModelExtensions.toName(f_1));
              this._dtoTypesBuilder.<JvmOperation>operator_add(_members_18, _remover);
              EList<JvmMember> _members_19 = it.getMembers();
              JvmOperation _internalAdder = this._dtoTypesBuilder.toInternalAdder(f_1);
              this._dtoTypesBuilder.<JvmOperation>operator_add(_members_19, _internalAdder);
              EList<JvmMember> _members_20 = it.getMembers();
              JvmOperation _internalRemover = this._dtoTypesBuilder.toInternalRemover(f_1);
              this._dtoTypesBuilder.<JvmOperation>operator_add(_members_20, _internalRemover);
              EList<JvmMember> _members_21 = it.getMembers();
              JvmOperation _setter = this._dtoTypesBuilder.toSetter(f_1);
              this._dtoTypesBuilder.<JvmOperation>operator_add(_members_21, _setter);
            } else {
              boolean _isVersionAttr = ((LDtoAbstractAttribute) f_1).isVersionAttr();
              if (_isVersionAttr) {
                EList<JvmMember> _members_22 = it.getMembers();
                JvmOperation _versionSetter = this._dtoTypesBuilder.toVersionSetter(((LDtoAbstractAttribute) f_1));
                this._dtoTypesBuilder.<JvmOperation>operator_add(_members_22, _versionSetter);
              } else {
                EList<JvmMember> _members_23 = it.getMembers();
                JvmOperation _setter_1 = this._dtoTypesBuilder.toSetter(f_1);
                this._dtoTypesBuilder.<JvmOperation>operator_add(_members_23, _setter_1);
              }
            }
          }
        }
        if (!_matched_1) {
          if (f_1 instanceof LReference) {
            _matched_1=true;
            EList<JvmMember> _members_15 = it.getMembers();
            JvmOperation _getter = this._dtoTypesBuilder.toGetter(f_1);
            this._dtoTypesBuilder.<JvmOperation>operator_add(_members_15, _getter);
            boolean _isToMany = this._dtoModelExtensions.isToMany(f_1);
            if (_isToMany) {
              EList<JvmMember> _members_16 = it.getMembers();
              JvmOperation _internalCollectionGetter = this._dtoTypesBuilder.toInternalCollectionGetter(f_1, this._dtoModelExtensions.toName(f_1));
              this._dtoTypesBuilder.<JvmOperation>operator_add(_members_16, _internalCollectionGetter);
              EList<JvmMember> _members_17 = it.getMembers();
              JvmOperation _adder = this._dtoTypesBuilder.toAdder(f_1, this._dtoModelExtensions.toName(f_1));
              this._dtoTypesBuilder.<JvmOperation>operator_add(_members_17, _adder);
              EList<JvmMember> _members_18 = it.getMembers();
              JvmOperation _remover = this._dtoTypesBuilder.toRemover(f_1, this._dtoModelExtensions.toName(f_1));
              this._dtoTypesBuilder.<JvmOperation>operator_add(_members_18, _remover);
              EList<JvmMember> _members_19 = it.getMembers();
              JvmOperation _internalAdder = this._dtoTypesBuilder.toInternalAdder(f_1);
              this._dtoTypesBuilder.<JvmOperation>operator_add(_members_19, _internalAdder);
              EList<JvmMember> _members_20 = it.getMembers();
              JvmOperation _internalRemover = this._dtoTypesBuilder.toInternalRemover(f_1);
              this._dtoTypesBuilder.<JvmOperation>operator_add(_members_20, _internalRemover);
              EList<JvmMember> _members_21 = it.getMembers();
              JvmOperation _setter = this._dtoTypesBuilder.toSetter(f_1);
              this._dtoTypesBuilder.<JvmOperation>operator_add(_members_21, _setter);
            } else {
              EList<JvmMember> _members_22 = it.getMembers();
              JvmOperation _setter_1 = this._dtoTypesBuilder.toSetter(f_1);
              this._dtoTypesBuilder.<JvmOperation>operator_add(_members_22, _setter_1);
              if ((f_1.isCascading() || (this._dtoModelExtensions.opposite(f_1) != null))) {
                EList<JvmMember> _members_23 = it.getMembers();
                JvmOperation _internalSetter = this._dtoTypesBuilder.toInternalSetter(f_1);
                this._dtoTypesBuilder.<JvmOperation>operator_add(_members_23, _internalSetter);
              }
            }
          }
        }
      }
      List<LDtoOperation> _operations = dto.getOperations();
      for (final LDtoOperation op : _operations) {
        EList<JvmMember> _members_15 = it.getMembers();
        final Procedure1<JvmOperation> _function_2 = (JvmOperation it_1) -> {
          this._dtoTypesBuilder.setDocumentation(it_1, this._dtoTypesBuilder.getDocumentation(op));
          EList<JvmFormalParameter> _params = op.getParams();
          for (final JvmFormalParameter p : _params) {
            EList<JvmFormalParameter> _parameters = it_1.getParameters();
            JvmFormalParameter _parameter = this._dtoTypesBuilder.toParameter(p, p.getName(), p.getParameterType());
            this._dtoTypesBuilder.<JvmFormalParameter>operator_add(_parameters, _parameter);
          }
          this._dtoTypesBuilder.setBody(it_1, op.getBody());
        };
        JvmOperation _method = this._dtoTypesBuilder.toMethod(op, this._dtoModelExtensions.toName(op), op.getType(), _function_2);
        this._dtoTypesBuilder.<JvmOperation>operator_add(_members_15, _method);
      }
      if ((idAttribute != null)) {
        EList<JvmMember> _members_16 = it.getMembers();
        JvmOperation _equalVersionsMethod = this._dtoTypesBuilder.toEqualVersionsMethod(idAttribute, it, false, idField, versionField);
        this._dtoTypesBuilder.<JvmOperation>operator_add(_members_16, _equalVersionsMethod);
        boolean _isHistorizedOrTimedependent = dto.isHistorizedOrTimedependent();
        if (_isHistorizedOrTimedependent) {
          EList<JvmMember> _members_17 = it.getMembers();
          JvmOperation _newIdVersion = this._dtoTypesBuilder.toNewIdVersion(dto, idField.getSimpleName());
          this._dtoTypesBuilder.<JvmOperation>operator_add(_members_17, _newIdVersion);
        }
      }
      final JvmParameterizedTypeReference typeRef = TypesFactory.eINSTANCE.createJvmParameterizedTypeReference();
      typeRef.setType(it);
      EList<JvmMember> _members_18 = it.getMembers();
      final Procedure1<JvmOperation> _function_3 = (JvmOperation it_1) -> {
        EList<JvmFormalParameter> _parameters = it_1.getParameters();
        JvmFormalParameter _parameter = this._dtoTypesBuilder.toParameter(dto, "event", this._dtoTypesBuilder.newTypeRef(it_1, PropertyChangeEvent.class.getName(), null));
        this._dtoTypesBuilder.<JvmFormalParameter>operator_add(_parameters, _parameter);
        StringConcatenationClient _client = new StringConcatenationClient() {
          @Override
          protected void appendTo(StringConcatenationClient.TargetStringConcatenation _builder) {
            _builder.append("Object source = event.getSource();");
            _builder.newLine();
            _builder.newLine();
            _builder.append("// forward the event from embeddable beans to all listeners. So the parent of the embeddable");
            _builder.newLine();
            _builder.append("// bean will become notified and its dirty state can be handled properly");
            _builder.newLine();
            {
              final Function1<LDtoFeature, Boolean> _function = (LDtoFeature it_2) -> {
                return Boolean.valueOf((!(it_2 instanceof LOperation)));
              };
              final Function1<LDtoFeature, Boolean> _function_1 = (LDtoFeature it_2) -> {
                return Boolean.valueOf(DtoGrammarJvmModelInferrer.this._dtoModelExtensions.isBean(DtoGrammarJvmModelInferrer.this._dtoModelExtensions.toRawType(it_2)));
              };
              Iterable<LDtoFeature> _filter = IterableExtensions.<LDtoFeature>filter(IterableExtensions.<LDtoFeature>filter(dto.getFeatures(), _function), _function_1);
              for(final LDtoFeature ref : _filter) {
                _builder.newLine();
                _builder.newLine();
                _builder.append("\t");
                _builder.append("if(source == ");
                String _name = DtoGrammarJvmModelInferrer.this._dtoModelExtensions.toName(ref);
                _builder.append(_name, "\t");
                _builder.append("){");
                _builder.newLineIfNotEmpty();
                _builder.append("\t\t");
                _builder.append("firePropertyChange(\"");
                String _name_1 = DtoGrammarJvmModelInferrer.this._dtoModelExtensions.toName(ref);
                _builder.append(_name_1, "\t\t");
                _builder.append("\" + \"_\" + event.getPropertyName(), event.getOldValue(), event.getNewValue());");
                _builder.newLineIfNotEmpty();
                _builder.append("\t");
                _builder.append("} else ");
                _builder.newLine();
              }
            }
            _builder.append("{ ");
            _builder.newLine();
            {
              LDto _superType = dto.getSuperType();
              boolean _tripleNotEquals = (_superType != null);
              if (_tripleNotEquals) {
                _builder.append("\t");
                _builder.append("super.propertyChange(event);");
                _builder.newLine();
              } else {
                _builder.append("\t");
                _builder.append("// no super class available to forward event");
                _builder.newLine();
              }
            }
            _builder.append("}");
            _builder.newLine();
          }
        };
        this._dtoTypesBuilder.setBody(it_1, _client);
      };
      JvmOperation _method_1 = this._dtoTypesBuilder.toMethod(dto, "propertyChange", this.references.getTypeForName(Void.TYPE, dto), _function_3);
      this._dtoTypesBuilder.<JvmOperation>operator_add(_members_18, _method_1);
      String _name = dto.getName();
      String _plus = ("Inferring dto " + _name);
      doInferLog.stop(this.log, _plus);
    };
    acceptor.<JvmDeclaredType>accept(type).initializeLater(_function);
  }
  
  public void inferMapperFullState(final JvmGenericType type, final LDto dto, final IJvmDeclaredTypeAcceptor acceptor, final boolean isPrelinkingPhase) {
    final Procedure1<JvmGenericType> _function = (JvmGenericType it) -> {
      final TimeLogger doInferLog = TimeLogger.start(it.getClass());
      EObject _eContainer = dto.eContainer();
      this._dtoTypesBuilder.setFileHeader(it, this._dtoTypesBuilder.getDocumentation(((LTypedPackage) _eContainer)));
      StringConcatenation _builder = new StringConcatenation();
      _builder.append("This class maps the dto {@link ");
      String _name = this._dtoModelExtensions.toName(dto);
      _builder.append(_name);
      _builder.append("} to and from the entity {@link ");
      String _name_1 = this._dtoModelExtensions.toName(dto.getWrappedType());
      _builder.append(_name_1);
      _builder.append("}.");
      _builder.newLineIfNotEmpty();
      this._dtoTypesBuilder.setDocumentation(it, _builder);
      EList<JvmMember> _members = it.getMembers();
      final Procedure1<JvmConstructor> _function_1 = (JvmConstructor it_1) -> {
      };
      JvmConstructor _constructor = this._dtoTypesBuilder.toConstructor(dto, _function_1);
      this._dtoTypesBuilder.<JvmConstructor>operator_add(_members, _constructor);
      LType _wrappedType = dto.getWrappedType();
      boolean _tripleNotEquals = (_wrappedType != null);
      if (_tripleNotEquals) {
        final JvmTypeParameter dtoParam = TypesFactory.eINSTANCE.createJvmTypeParameter();
        dtoParam.setName("DTO");
        final JvmUpperBound dtoUpper = TypesFactory.eINSTANCE.createJvmUpperBound();
        dtoUpper.setTypeReference(this._dtoTypesBuilder.findDtoTypeReference(dto));
        EList<JvmTypeConstraint> _constraints = dtoParam.getConstraints();
        this._dtoTypesBuilder.<JvmUpperBound>operator_add(_constraints, dtoUpper);
        EList<JvmTypeParameter> _typeParameters = it.getTypeParameters();
        this._dtoTypesBuilder.<JvmTypeParameter>operator_add(_typeParameters, dtoParam);
        final JvmTypeParameter entityParam = TypesFactory.eINSTANCE.createJvmTypeParameter();
        entityParam.setName("ENTITY");
        final JvmUpperBound entityUpper = TypesFactory.eINSTANCE.createJvmUpperBound();
        LType _wrappedType_1 = dto.getWrappedType();
        JvmTypeReference _typeReference = null;
        if (_wrappedType_1!=null) {
          _typeReference=this._dtoModelExtensions.toTypeReference(_wrappedType_1);
        }
        entityUpper.setTypeReference(_typeReference);
        EList<JvmTypeConstraint> _constraints_1 = entityParam.getConstraints();
        this._dtoTypesBuilder.<JvmUpperBound>operator_add(_constraints_1, entityUpper);
        EList<JvmTypeParameter> _typeParameters_1 = it.getTypeParameters();
        this._dtoTypesBuilder.<JvmTypeParameter>operator_add(_typeParameters_1, entityParam);
        final JvmParameterizedTypeReference entityType = TypesFactory.eINSTANCE.createJvmParameterizedTypeReference();
        entityType.setType(entityParam);
        final JvmParameterizedTypeReference dtoType = TypesFactory.eINSTANCE.createJvmParameterizedTypeReference();
        dtoType.setType(dtoParam);
        LDto _superType = dto.getSuperType();
        boolean _tripleNotEquals_1 = (_superType != null);
        if (_tripleNotEquals_1) {
          EList<JvmTypeReference> _superTypes = it.getSuperTypes();
          JvmParameterizedTypeReference _findSuperDtoMapperType = this._dtoTypesBuilder.findSuperDtoMapperType(dto, dtoType, entityType);
          this._dtoTypesBuilder.<JvmParameterizedTypeReference>operator_add(_superTypes, _findSuperDtoMapperType);
        } else {
          EList<JvmTypeReference> _superTypes_1 = it.getSuperTypes();
          JvmTypeReference _typeForName = this.references.getTypeForName(IMapper.class, dto, dtoType, entityType);
          this._dtoTypesBuilder.<JvmTypeReference>operator_add(_superTypes_1, _typeForName);
          EList<JvmMember> _members_1 = it.getMembers();
          JvmField _field = this._dtoTypesBuilder.toField(dto, "mapperAccess", this.references.getTypeForName(IMapperAccess.class, dto, null));
          this._dtoTypesBuilder.<JvmField>operator_add(_members_1, _field);
          EList<JvmMember> _members_2 = it.getMembers();
          JvmOperation _getToDtoMapperAccess = this._dtoTypesBuilder.toGetToDtoMapperAccess(dto);
          this._dtoTypesBuilder.<JvmOperation>operator_add(_members_2, _getToDtoMapperAccess);
          EList<JvmMember> _members_3 = it.getMembers();
          JvmOperation _getToEntityMapperAccess = this._dtoTypesBuilder.toGetToEntityMapperAccess(dto);
          this._dtoTypesBuilder.<JvmOperation>operator_add(_members_3, _getToEntityMapperAccess);
          EList<JvmMember> _members_4 = it.getMembers();
          JvmOperation _mapperBindMethod = this._dtoTypesBuilder.toMapperBindMethod(dto);
          this._dtoTypesBuilder.<JvmOperation>operator_add(_members_4, _mapperBindMethod);
          EList<JvmMember> _members_5 = it.getMembers();
          JvmOperation _mapperUnbindMethod = this._dtoTypesBuilder.toMapperUnbindMethod(dto);
          this._dtoTypesBuilder.<JvmOperation>operator_add(_members_5, _mapperUnbindMethod);
        }
        EList<JvmMember> _members_6 = it.getMembers();
        final Procedure1<JvmOperation> _function_2 = (JvmOperation it_1) -> {
          StringConcatenation _builder_1 = new StringConcatenation();
          _builder_1.append("Creates a new instance of the entity");
          this._dtoTypesBuilder.setDocumentation(it_1, _builder_1);
          StringConcatenationClient _client = new StringConcatenationClient() {
            @Override
            protected void appendTo(StringConcatenationClient.TargetStringConcatenation _builder) {
              {
                boolean _isAbstract = DtoGrammarJvmModelInferrer.this._dtoModelExtensions.isAbstract(dto.getWrappedType());
                if (_isAbstract) {
                  _builder.append("throw new UnsupportedOperationException(\"Subclass needs to provide dto.\");");
                } else {
                  _builder.append("return new ");
                  String _name = DtoGrammarJvmModelInferrer.this._dtoModelExtensions.toName(dto.getWrappedType());
                  _builder.append(_name);
                  _builder.append("();");
                }
              }
              _builder.newLineIfNotEmpty();
            }
          };
          this._dtoTypesBuilder.setBody(it_1, _client);
        };
        JvmOperation _method = this._dtoTypesBuilder.toMethod(dto, "createEntity", this._dtoModelExtensions.toTypeReference(dto.getWrappedType()), _function_2);
        this._dtoTypesBuilder.<JvmOperation>operator_add(_members_6, _method);
        EList<JvmMember> _members_7 = it.getMembers();
        final Procedure1<JvmOperation> _function_3 = (JvmOperation it_1) -> {
          StringConcatenation _builder_1 = new StringConcatenation();
          _builder_1.append("Creates a new instance of the dto");
          this._dtoTypesBuilder.setDocumentation(it_1, _builder_1);
          StringConcatenationClient _client = new StringConcatenationClient() {
            @Override
            protected void appendTo(StringConcatenationClient.TargetStringConcatenation _builder) {
              {
                boolean _isAbstract = dto.isAbstract();
                if (_isAbstract) {
                  _builder.append("throw new UnsupportedOperationException(\"Subclass needs to provide dto.\");");
                } else {
                  _builder.append("return new ");
                  String _name = DtoGrammarJvmModelInferrer.this._dtoModelExtensions.toName(dto);
                  _builder.append(_name);
                  _builder.append("();");
                }
              }
              _builder.newLineIfNotEmpty();
            }
          };
          this._dtoTypesBuilder.setBody(it_1, _client);
        };
        JvmOperation _method_1 = this._dtoTypesBuilder.toMethod(dto, "createDto", this._dtoTypesBuilder.findDtoTypeReference(dto), _function_3);
        this._dtoTypesBuilder.<JvmOperation>operator_add(_members_7, _method_1);
        EList<JvmMember> _members_8 = it.getMembers();
        JvmOperation _mapToDto = this._dtoTypesBuilder.toMapToDto(dto);
        this._dtoTypesBuilder.<JvmOperation>operator_add(_members_8, _mapToDto);
        EList<JvmMember> _members_9 = it.getMembers();
        JvmOperation _mapToEntity = this._dtoTypesBuilder.toMapToEntity(dto);
        this._dtoTypesBuilder.<JvmOperation>operator_add(_members_9, _mapToEntity);
        EList<LDtoFeature> _features = dto.getFeatures();
        for (final LDtoFeature f : _features) {
          boolean _matched = false;
          if ((f instanceof LDtoAbstractAttribute)) {
            _matched=true;
            final LDtoAbstractAttribute att = ((LDtoAbstractAttribute) f);
            boolean _or = false;
            boolean _inherited = this._dtoModelExtensions.inherited(att);
            if (_inherited) {
              _or = true;
            } else {
              LDtoMapper _mapper = att.getMapper();
              XExpression _toDTO = null;
              if (_mapper!=null) {
                _toDTO=_mapper.getToDTO();
              }
              boolean _tripleNotEquals_2 = (_toDTO != null);
              _or = _tripleNotEquals_2;
            }
            if (_or) {
              EList<JvmMember> _members_10 = it.getMembers();
              JvmOperation _mapToDtoProperty = this._dtoTypesBuilder.toMapToDtoProperty(att);
              this._dtoTypesBuilder.<JvmOperation>operator_add(_members_10, _mapToDtoProperty);
            }
            boolean _or_1 = false;
            boolean _inherited_1 = this._dtoModelExtensions.inherited(att);
            if (_inherited_1) {
              _or_1 = true;
            } else {
              LDtoMapper _mapper_1 = att.getMapper();
              XExpression _fromDTO = null;
              if (_mapper_1!=null) {
                _fromDTO=_mapper_1.getFromDTO();
              }
              boolean _tripleNotEquals_3 = (_fromDTO != null);
              _or_1 = _tripleNotEquals_3;
            }
            if (_or_1) {
              EList<JvmMember> _members_11 = it.getMembers();
              JvmOperation _mapToEntityProperty = this._dtoTypesBuilder.toMapToEntityProperty(att);
              this._dtoTypesBuilder.<JvmOperation>operator_add(_members_11, _mapToEntityProperty);
            }
          }
          if (!_matched) {
            if ((f instanceof LDtoAbstractReference)) {
              _matched=true;
              final LDtoAbstractReference att_1 = ((LDtoAbstractReference) f);
              boolean _or_2 = false;
              boolean _inherited_2 = this._dtoModelExtensions.inherited(att_1);
              if (_inherited_2) {
                _or_2 = true;
              } else {
                LDtoMapper _mapper_2 = att_1.getMapper();
                XExpression _toDTO_1 = null;
                if (_mapper_2!=null) {
                  _toDTO_1=_mapper_2.getToDTO();
                }
                boolean _tripleNotEquals_4 = (_toDTO_1 != null);
                _or_2 = _tripleNotEquals_4;
              }
              if (_or_2) {
                EList<JvmMember> _members_12 = it.getMembers();
                JvmOperation _mapToDtoProperty_1 = this._dtoTypesBuilder.toMapToDtoProperty(att_1);
                this._dtoTypesBuilder.<JvmOperation>operator_add(_members_12, _mapToDtoProperty_1);
              }
              boolean _or_3 = false;
              boolean _inherited_3 = this._dtoModelExtensions.inherited(att_1);
              if (_inherited_3) {
                _or_3 = true;
              } else {
                LDtoMapper _mapper_3 = att_1.getMapper();
                XExpression _fromDTO_1 = null;
                if (_mapper_3!=null) {
                  _fromDTO_1=_mapper_3.getFromDTO();
                }
                boolean _tripleNotEquals_5 = (_fromDTO_1 != null);
                _or_3 = _tripleNotEquals_5;
              }
              if (_or_3) {
                EList<JvmMember> _members_13 = it.getMembers();
                JvmOperation _mapToEntityProperty_1 = this._dtoTypesBuilder.toMapToEntityProperty(att_1);
                this._dtoTypesBuilder.<JvmOperation>operator_add(_members_13, _mapToEntityProperty_1);
              }
            }
          }
        }
        final LAttribute idAtt = this.findIdProperty(dto);
        EList<JvmMember> _members_14 = it.getMembers();
        final Procedure1<JvmOperation> _function_4 = (JvmOperation it_1) -> {
          EList<JvmFormalParameter> _parameters = it_1.getParameters();
          JvmFormalParameter _parameter = this._dtoTypesBuilder.toParameter(dto, "in", this.references.getTypeForName(Object.class, dto, null));
          this._dtoTypesBuilder.<JvmFormalParameter>operator_add(_parameters, _parameter);
          if ((idAtt != null)) {
            StringConcatenationClient _client = new StringConcatenationClient() {
              @Override
              protected void appendTo(StringConcatenationClient.TargetStringConcatenation _builder) {
                _builder.append("return org.eclipse.osbp.runtime.common.hash.HashUtil.createObjectWithIdHash(");
                String _name = DtoGrammarJvmModelInferrer.this._dtoModelExtensions.toName(dto);
                _builder.append(_name);
                _builder.append(".class, in);");
                _builder.newLineIfNotEmpty();
              }
            };
            this._dtoTypesBuilder.setBody(it_1, _client);
          } else {
            StringConcatenationClient _client_1 = new StringConcatenationClient() {
              @Override
              protected void appendTo(StringConcatenationClient.TargetStringConcatenation _builder) {
                _builder.append("throw new UnsupportedOperationException(\"No id attribute available\");");
                _builder.newLine();
              }
            };
            this._dtoTypesBuilder.setBody(it_1, _client_1);
          }
        };
        JvmOperation _method_2 = this._dtoTypesBuilder.toMethod(dto, "createDtoHash", this.references.getTypeForName(String.class, dto, null), _function_4);
        this._dtoTypesBuilder.<JvmOperation>operator_add(_members_14, _method_2);
        EList<JvmMember> _members_15 = it.getMembers();
        final Procedure1<JvmOperation> _function_5 = (JvmOperation it_1) -> {
          EList<JvmFormalParameter> _parameters = it_1.getParameters();
          JvmFormalParameter _parameter = this._dtoTypesBuilder.toParameter(dto, "in", this.references.getTypeForName(Object.class, dto, null));
          this._dtoTypesBuilder.<JvmFormalParameter>operator_add(_parameters, _parameter);
          if ((idAtt != null)) {
            StringConcatenationClient _client = new StringConcatenationClient() {
              @Override
              protected void appendTo(StringConcatenationClient.TargetStringConcatenation _builder) {
                _builder.append("return org.eclipse.osbp.runtime.common.hash.HashUtil.createObjectWithIdHash(");
                String _name = DtoGrammarJvmModelInferrer.this._dtoModelExtensions.toName(dto.getWrappedType());
                _builder.append(_name);
                _builder.append(".class, in);");
                _builder.newLineIfNotEmpty();
              }
            };
            this._dtoTypesBuilder.setBody(it_1, _client);
          } else {
            StringConcatenationClient _client_1 = new StringConcatenationClient() {
              @Override
              protected void appendTo(StringConcatenationClient.TargetStringConcatenation _builder) {
                _builder.append("throw new UnsupportedOperationException(\"No id attribute available\");");
                _builder.newLine();
              }
            };
            this._dtoTypesBuilder.setBody(it_1, _client_1);
          }
        };
        JvmOperation _method_3 = this._dtoTypesBuilder.toMethod(dto, "createEntityHash", this.references.getTypeForName(String.class, dto, null), _function_5);
        this._dtoTypesBuilder.<JvmOperation>operator_add(_members_15, _method_3);
      }
      String _name_2 = dto.getName();
      String _plus = ("Inferring mapper " + _name_2);
      doInferLog.stop(this.log, _plus);
    };
    acceptor.<JvmGenericType>accept(type).initializeLater(_function);
  }
  
  public LAttribute findIdProperty(final LDto dto) {
    final Function1<LAttribute, LAttribute> _function = (LAttribute it) -> {
      return ((LAttribute) it);
    };
    Iterable<LAttribute> _map = IterableExtensions.<LAttribute, LAttribute>map(Iterables.<LAttribute>filter(dto.getAllFeatures(), LAttribute.class), _function);
    for (final LAttribute att : _map) {
      boolean _isIDorUUID = this._dtoModelExtensions.isIDorUUID(att);
      if (_isIDorUUID) {
        return att;
      }
    }
    return null;
  }
  
  protected void _infer(final LEnum enumX, final IJvmDeclaredTypeAcceptor acceptor, final boolean isPrelinkingPhase) {
    final JvmEnumerationType type = this._dtoTypesBuilder.toEnumerationType(enumX, this._iQualifiedNameProvider.getFullyQualifiedName(enumX).toString(), null);
    this.inferFullState(type, enumX, acceptor, isPrelinkingPhase, "");
  }
  
  protected void _inferTypesOnly(final LEnum enumX, final IJvmDeclaredTypeAcceptor acceptor, final boolean isPrelinkingPhase) {
    final JvmEnumerationType type = this._dtoTypesBuilder.toEnumerationType(enumX, this._iQualifiedNameProvider.getFullyQualifiedName(enumX).toString(), null);
    acceptor.<JvmEnumerationType>accept(type);
    this.inferTypesOnlyByDelegates(enumX, acceptor, isPrelinkingPhase);
  }
  
  protected void _inferFullState(final JvmDeclaredType type, final LEnum enumX, final IJvmDeclaredTypeAcceptor acceptor, final boolean isPrelinkingPhase, final String selector) {
    final Procedure1<JvmDeclaredType> _function = (JvmDeclaredType it) -> {
      final TimeLogger doInferLog = TimeLogger.start(it.getClass());
      EObject _eContainer = enumX.eContainer();
      this._dtoTypesBuilder.setFileHeader(it, this._dtoTypesBuilder.getDocumentation(((LTypedPackage) _eContainer)));
      this._dtoTypesBuilder.setDocumentation(it, this._dtoTypesBuilder.getDocumentation(enumX));
      EList<LEnumLiteral> _literals = enumX.getLiterals();
      for (final LEnumLiteral f : _literals) {
        {
          this._dtoTypesBuilder.setDocumentation(it, this._dtoTypesBuilder.getDocumentation(f));
          EList<JvmMember> _members = it.getMembers();
          JvmEnumerationLiteral _enumerationLiteral = this._dtoTypesBuilder.toEnumerationLiteral(f, f.getName());
          this._dtoTypesBuilder.<JvmEnumerationLiteral>operator_add(_members, _enumerationLiteral);
        }
      }
      String _name = enumX.getName();
      String _plus = ("Inferring enum " + _name);
      doInferLog.stop(this.log, _plus);
    };
    acceptor.<JvmDeclaredType>accept(type).initializeLater(_function);
  }
  
  public void inferFullState(final JvmType type, final EObject dto, final IJvmDeclaredTypeAcceptor acceptor, final boolean isPrelinkingPhase, final String selector) {
    if (type instanceof JvmGenericType
         && dto instanceof LDto) {
      _inferFullState((JvmGenericType)type, (LDto)dto, acceptor, isPrelinkingPhase, selector);
      return;
    } else if (type instanceof JvmDeclaredType
         && dto instanceof LEnum) {
      _inferFullState((JvmDeclaredType)type, (LEnum)dto, acceptor, isPrelinkingPhase, selector);
      return;
    } else if (type != null
         && dto != null) {
      _inferFullState(type, dto, acceptor, isPrelinkingPhase, selector);
      return;
    } else {
      throw new IllegalArgumentException("Unhandled parameter types: " +
        Arrays.<Object>asList(type, dto, acceptor, isPrelinkingPhase, selector).toString());
    }
  }
  
  public void infer(final EObject enumX, final IJvmDeclaredTypeAcceptor acceptor, final boolean isPrelinkingPhase) {
    if (enumX instanceof LEnum) {
      _infer((LEnum)enumX, acceptor, isPrelinkingPhase);
      return;
    } else if (enumX instanceof LDto) {
      _infer((LDto)enumX, acceptor, isPrelinkingPhase);
      return;
    } else if (enumX != null) {
      _infer(enumX, acceptor, isPrelinkingPhase);
      return;
    } else {
      throw new IllegalArgumentException("Unhandled parameter types: " +
        Arrays.<Object>asList(enumX, acceptor, isPrelinkingPhase).toString());
    }
  }
  
  public void inferTypesOnly(final EObject enumX, final IJvmDeclaredTypeAcceptor acceptor, final boolean isPrelinkingPhase) {
    if (enumX instanceof LEnum) {
      _inferTypesOnly((LEnum)enumX, acceptor, isPrelinkingPhase);
      return;
    } else if (enumX instanceof LDto) {
      _inferTypesOnly((LDto)enumX, acceptor, isPrelinkingPhase);
      return;
    } else if (enumX != null) {
      _inferTypesOnly(enumX, acceptor, isPrelinkingPhase);
      return;
    } else {
      throw new IllegalArgumentException("Unhandled parameter types: " +
        Arrays.<Object>asList(enumX, acceptor, isPrelinkingPhase).toString());
    }
  }
}
