/**
 * 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.services.xtext.extensions;

import com.google.common.base.Objects;
import com.google.inject.Inject;
import java.util.Collection;
import org.eclipse.emf.common.util.EList;
import org.eclipse.osbp.dsl.common.xtext.extensions.TreeAppendableExtensions;
import org.eclipse.osbp.dsl.common.xtext.jvmmodel.AnnotationCompiler;
import org.eclipse.osbp.dsl.common.xtext.jvmmodel.CommonTypesBuilder;
import org.eclipse.osbp.dsl.semantic.common.types.LAttribute;
import org.eclipse.osbp.dsl.semantic.service.LDTOService;
import org.eclipse.osbp.dsl.semantic.service.LInjectedService;
import org.eclipse.osbp.dsl.services.xtext.extensions.AnnotationExtension;
import org.eclipse.osbp.dsl.services.xtext.extensions.MethodNamingExtensions;
import org.eclipse.osbp.dsl.services.xtext.extensions.ModelExtensions;
import org.eclipse.osbp.runtime.common.filter.IQuery;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtend2.lib.StringConcatenationClient;
import org.eclipse.xtext.common.types.JvmFormalParameter;
import org.eclipse.xtext.common.types.JvmOperation;
import org.eclipse.xtext.common.types.JvmTypeReference;
import org.eclipse.xtext.common.types.JvmVisibility;
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.util.Strings;
import org.eclipse.xtext.xbase.jvmmodel.IJvmModelAssociator;
import org.eclipse.xtext.xbase.lib.Extension;

@SuppressWarnings("all")
public class ServicesTypesBuilder extends CommonTypesBuilder {
  @Inject
  @Extension
  private ModelExtensions _modelExtensions;
  
  @Inject
  @Extension
  private MethodNamingExtensions _methodNamingExtensions;
  
  @Inject
  @Extension
  private TreeAppendableExtensions _treeAppendableExtensions;
  
  @Inject
  @Extension
  private IQualifiedNameProvider _iQualifiedNameProvider;
  
  @Inject
  @Extension
  private AnnotationExtension _annotationExtension;
  
  @Inject
  private IJvmModelAssociator associator;
  
  @Inject
  private AnnotationCompiler annotationCompiler;
  
  @Inject
  private TypesFactory typesFactory;
  
  @Inject
  private TypeReferences references;
  
  protected JvmOperation _toGetMethod(final LDTOService service) {
    final JvmOperation op = this.typesFactory.createJvmOperation();
    op.setVisibility(JvmVisibility.PUBLIC);
    op.setReturnType(this._modelExtensions.toTypeReference(service.getDto()));
    op.setSimpleName("get");
    EList<JvmFormalParameter> _parameters = op.getParameters();
    JvmFormalParameter _parameter = this.toParameter(service, "id", this.references.getTypeForName(Object.class, service));
    this.<JvmFormalParameter>operator_add(_parameters, _parameter);
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("{@inherit doc}");
    _builder.newLine();
    this.setDocumentation(op, _builder);
    boolean _basedOnEntity = this._modelExtensions.basedOnEntity(service.getDto());
    if (_basedOnEntity) {
      StringConcatenationClient _client = new StringConcatenationClient() {
        @Override
        protected void appendTo(StringConcatenationClient.TargetStringConcatenation _builder) {
          _builder.append("javax.persistence.EntityManager em = emf.createEntityManager();");
          _builder.newLine();
          _builder.append("javax.persistence.EntityTransaction txn = em.getTransaction();");
          _builder.newLine();
          _builder.newLine();
          _builder.append("// find the entity");
          _builder.newLine();
          String _qualifiedName = ServicesTypesBuilder.this._modelExtensions.toQualifiedName(ServicesTypesBuilder.this._modelExtensions.wrappedEntity(service.getDto()));
          _builder.append(_qualifiedName);
          _builder.append(" entity = null;");
          _builder.newLineIfNotEmpty();
          _builder.append("try {");
          _builder.newLine();
          _builder.append("\t");
          _builder.append("entity = em.find(");
          String _qualifiedName_1 = ServicesTypesBuilder.this._modelExtensions.toQualifiedName(ServicesTypesBuilder.this._modelExtensions.wrappedEntity(service.getDto()));
          _builder.append(_qualifiedName_1, "\t");
          _builder.append(".class, id);");
          _builder.newLineIfNotEmpty();
          _builder.append("\t");
          _builder.append("txn.commit();");
          _builder.newLine();
          _builder.append("   \t");
          _builder.append("txn = null;");
          _builder.newLine();
          _builder.append("}finally{");
          _builder.newLine();
          _builder.append("   \t");
          _builder.append("if(txn != null){");
          _builder.newLine();
          _builder.append("   \t\t");
          _builder.append("txn.rollback();");
          _builder.newLine();
          _builder.append("   \t");
          _builder.append("}");
          _builder.newLine();
          _builder.append("   \t");
          _builder.append("em.close();");
          _builder.newLine();
          _builder.append("}");
          _builder.newLine();
          _builder.newLine();
          _builder.append("// map the entity to the dto");
          _builder.newLine();
          String _simpleName = ServicesTypesBuilder.this._modelExtensions.toTypeReference(service.getDto()).getSimpleName();
          _builder.append(_simpleName);
          _builder.append(" dto = new ");
          String _simpleName_1 = ServicesTypesBuilder.this._modelExtensions.toTypeReference(service.getDto()).getSimpleName();
          _builder.append(_simpleName_1);
          _builder.append("();");
          _builder.newLineIfNotEmpty();
          _builder.append("mapper.mapToDTO(dto, entity);");
          _builder.newLine();
          _builder.append("return dto;");
          _builder.newLine();
        }
      };
      this.setBody(op, _client);
    } else {
      StringConcatenationClient _client_1 = new StringConcatenationClient() {
        @Override
        protected void appendTo(StringConcatenationClient.TargetStringConcatenation _builder) {
          _builder.append("throw new UnsupportedOperationException();");
        }
      };
      this.setBody(op, _client_1);
    }
    return this.<JvmOperation>associate(service, op);
  }
  
  public JvmOperation toFindMethod(final LDTOService service) {
    final JvmOperation op = this.typesFactory.createJvmOperation();
    op.setVisibility(JvmVisibility.PUBLIC);
    op.setReturnType(this.references.getTypeForName(Collection.class, service, this._modelExtensions.toTypeReference(service.getDto())));
    op.setSimpleName("find");
    EList<JvmFormalParameter> _parameters = op.getParameters();
    JvmFormalParameter _parameter = this.toParameter(service, "query", this.references.getTypeForName(IQuery.class, service));
    this.<JvmFormalParameter>operator_add(_parameters, _parameter);
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("{@inherit doc}");
    _builder.newLine();
    this.setDocumentation(op, _builder);
    StringConcatenationClient _client = new StringConcatenationClient() {
      @Override
      protected void appendTo(StringConcatenationClient.TargetStringConcatenation _builder) {
        _builder.append("return null;");
      }
    };
    this.setBody(op, _client);
    return this.<JvmOperation>associate(service, op);
  }
  
  public JvmOperation toFindMethodWithStartindex(final LDTOService service) {
    final JvmOperation op = this.typesFactory.createJvmOperation();
    op.setVisibility(JvmVisibility.PUBLIC);
    op.setReturnType(this.references.getTypeForName(Collection.class, service, this._modelExtensions.toTypeReference(service.getDto())));
    op.setSimpleName("find");
    EList<JvmFormalParameter> _parameters = op.getParameters();
    JvmFormalParameter _parameter = this.toParameter(service, "query", this.references.getTypeForName(IQuery.class, service));
    this.<JvmFormalParameter>operator_add(_parameters, _parameter);
    EList<JvmFormalParameter> _parameters_1 = op.getParameters();
    JvmFormalParameter _parameter_1 = this.toParameter(service, "startindex", this.references.getTypeForName(Integer.TYPE, service));
    this.<JvmFormalParameter>operator_add(_parameters_1, _parameter_1);
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("{@inherit doc}");
    _builder.newLine();
    this.setDocumentation(op, _builder);
    StringConcatenationClient _client = new StringConcatenationClient() {
      @Override
      protected void appendTo(StringConcatenationClient.TargetStringConcatenation _builder) {
        _builder.append("return null;");
      }
    };
    this.setBody(op, _client);
    return this.<JvmOperation>associate(service, op);
  }
  
  public JvmOperation toUpdateMethod(final LDTOService service) {
    final JvmOperation op = this.typesFactory.createJvmOperation();
    op.setVisibility(JvmVisibility.PUBLIC);
    op.setReturnType(this.references.getTypeForName(Void.TYPE, service));
    op.setSimpleName("update");
    EList<JvmFormalParameter> _parameters = op.getParameters();
    JvmFormalParameter _parameter = this.toParameter(service, "dto", this._modelExtensions.toTypeReference(service.getDto()));
    this.<JvmFormalParameter>operator_add(_parameters, _parameter);
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("{@inherit doc}");
    _builder.newLine();
    this.setDocumentation(op, _builder);
    boolean _basedOnEntity = this._modelExtensions.basedOnEntity(service.getDto());
    if (_basedOnEntity) {
      StringConcatenationClient _client = new StringConcatenationClient() {
        @Override
        protected void appendTo(StringConcatenationClient.TargetStringConcatenation _builder) {
          _builder.append("javax.persistence.EntityManager em = emf.createEntityManager();");
          _builder.newLine();
          _builder.append("javax.persistence.EntityTransaction txn = em.getTransaction();");
          _builder.newLine();
          _builder.newLine();
          _builder.append("try {");
          _builder.newLine();
          _builder.append("\t");
          String _qualifiedName = ServicesTypesBuilder.this._modelExtensions.toQualifiedName(ServicesTypesBuilder.this._modelExtensions.wrappedEntity(service.getDto()));
          _builder.append(_qualifiedName, "\t");
          _builder.append(" entity = em.find(");
          String _qualifiedName_1 = ServicesTypesBuilder.this._modelExtensions.toQualifiedName(ServicesTypesBuilder.this._modelExtensions.wrappedEntity(service.getDto()));
          _builder.append(_qualifiedName_1, "\t");
          _builder.append(".class, dto.");
          LAttribute _idAttribute = service.getDto().getIdAttribute();
          String _getterName = null;
          if (_idAttribute!=null) {
            _getterName=ServicesTypesBuilder.this._methodNamingExtensions.toGetterName(_idAttribute);
          }
          _builder.append(_getterName, "\t");
          _builder.append("());");
          _builder.newLineIfNotEmpty();
          _builder.append("\t");
          _builder.append("mapper.mapToEntity(dto, entity);");
          _builder.newLine();
          _builder.append("\t");
          _builder.append("em.persist(entity);");
          _builder.newLine();
          _builder.newLine();
          _builder.append("\t");
          _builder.append("txn.commit();");
          _builder.newLine();
          _builder.append("\t");
          _builder.append("txn = null;");
          _builder.newLine();
          _builder.append("}finally{");
          _builder.newLine();
          _builder.append("\t");
          _builder.append("if(txn != null){");
          _builder.newLine();
          _builder.append("\t\t");
          _builder.append("txn.rollback();");
          _builder.newLine();
          _builder.append("\t");
          _builder.append("}");
          _builder.newLine();
          _builder.append("\t");
          _builder.append("em.close();");
          _builder.newLine();
          _builder.append("}");
          _builder.newLine();
        }
      };
      this.setBody(op, _client);
    } else {
      StringConcatenationClient _client_1 = new StringConcatenationClient() {
        @Override
        protected void appendTo(StringConcatenationClient.TargetStringConcatenation _builder) {
          _builder.append("throw new UnsupportedOperationException();");
        }
      };
      this.setBody(op, _client_1);
    }
    return this.<JvmOperation>associate(service, op);
  }
  
  public JvmOperation toDeleteMethod(final LDTOService service) {
    final JvmOperation op = this.typesFactory.createJvmOperation();
    op.setVisibility(JvmVisibility.PUBLIC);
    op.setReturnType(this.references.getTypeForName(Void.TYPE, service));
    op.setSimpleName("delete");
    EList<JvmFormalParameter> _parameters = op.getParameters();
    JvmFormalParameter _parameter = this.toParameter(service, "dto", this._modelExtensions.toTypeReference(service.getDto()));
    this.<JvmFormalParameter>operator_add(_parameters, _parameter);
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("{@inherit doc}");
    _builder.newLine();
    this.setDocumentation(op, _builder);
    boolean _basedOnEntity = this._modelExtensions.basedOnEntity(service.getDto());
    if (_basedOnEntity) {
      StringConcatenationClient _client = new StringConcatenationClient() {
        @Override
        protected void appendTo(StringConcatenationClient.TargetStringConcatenation _builder) {
          _builder.append("javax.persistence.EntityManager em = emf.createEntityManager();");
          _builder.newLine();
          _builder.append("javax.persistence.EntityTransaction txn = em.getTransaction();");
          _builder.newLine();
          _builder.newLine();
          _builder.append("try {");
          _builder.newLine();
          _builder.append("\t");
          String _qualifiedName = ServicesTypesBuilder.this._modelExtensions.toQualifiedName(ServicesTypesBuilder.this._modelExtensions.wrappedEntity(service.getDto()));
          _builder.append(_qualifiedName, "\t");
          _builder.append(" entity = em.find(");
          String _qualifiedName_1 = ServicesTypesBuilder.this._modelExtensions.toQualifiedName(ServicesTypesBuilder.this._modelExtensions.wrappedEntity(service.getDto()));
          _builder.append(_qualifiedName_1, "\t");
          _builder.append(".class, dto.");
          LAttribute _idAttribute = service.getDto().getIdAttribute();
          String _getterName = null;
          if (_idAttribute!=null) {
            _getterName=ServicesTypesBuilder.this._methodNamingExtensions.toGetterName(_idAttribute);
          }
          _builder.append(_getterName, "\t");
          _builder.append("());");
          _builder.newLineIfNotEmpty();
          _builder.append("\t");
          _builder.append("em.remove(entity);");
          _builder.newLine();
          _builder.newLine();
          _builder.append("\t");
          _builder.append("txn.commit();");
          _builder.newLine();
          _builder.append("\t");
          _builder.append("txn = null;");
          _builder.newLine();
          _builder.append("}finally{");
          _builder.newLine();
          _builder.append("\t");
          _builder.append("if(txn != null){");
          _builder.newLine();
          _builder.append("\t\t");
          _builder.append("txn.rollback();");
          _builder.newLine();
          _builder.append("\t");
          _builder.append("}");
          _builder.newLine();
          _builder.append("\t");
          _builder.append("em.close();");
          _builder.newLine();
          _builder.append("}");
          _builder.newLine();
        }
      };
      this.setBody(op, _client);
    } else {
      StringConcatenationClient _client_1 = new StringConcatenationClient() {
        @Override
        protected void appendTo(StringConcatenationClient.TargetStringConcatenation _builder) {
          _builder.append("throw new UnsupportedOperationException();");
        }
      };
      this.setBody(op, _client_1);
    }
    return this.<JvmOperation>associate(service, op);
  }
  
  /**
   * shorthand for <code>toSetter(sourceElement, name, name, typeRef)</code>
   */
  public JvmOperation toBindService(final LInjectedService sourceElement, final String name, final JvmTypeReference typeRef) {
    return this.toBindService(sourceElement, name, name, typeRef);
  }
  
  /**
   * Creates a setter method for the given properties name with the standard implementation assigning the passed
   * parameter to a similarly named field.
   * 
   * Example: <code>
   * public void setFoo(String foo) {
   *   this.foo = foo;
   * }
   * </code>
   * 
   * @return a setter method for a JavaBeans property with the given name, <code>null</code> if sourceElement or name are <code>null</code>.
   */
  public JvmOperation toBindService(final LInjectedService sourceElement, final String propertyName, final String fieldName, final JvmTypeReference typeRef) {
    if (((Objects.equal(sourceElement, null) || Objects.equal(propertyName, null)) || Objects.equal(fieldName, null))) {
      return null;
    }
    final JvmOperation result = this.typesFactory.createJvmOperation();
    result.setVisibility(JvmVisibility.PROTECTED);
    result.setReturnType(this.references.getTypeForName(Void.TYPE, sourceElement));
    String _firstUpper = Strings.toFirstUpper(propertyName);
    String _plus = CommonTypesBuilder.operator_plus("bind", _firstUpper);
    result.setSimpleName(_plus);
    EList<JvmFormalParameter> _parameters = result.getParameters();
    JvmFormalParameter _parameter = this.toParameter(sourceElement, propertyName, this.cloneWithProxies(typeRef));
    this.<JvmFormalParameter>operator_add(_parameters, _parameter);
    StringConcatenationClient _client = new StringConcatenationClient() {
      @Override
      protected void appendTo(StringConcatenationClient.TargetStringConcatenation _builder) {
        _builder.append("this.");
        _builder.append(fieldName);
        _builder.append(" = ");
        _builder.append(propertyName);
        _builder.append(";");
      }
    };
    this.setBody(result, _client);
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("Binds the service {@link ");
    String _string = typeRef.getQualifiedName().toString();
    _builder.append(_string);
    _builder.append("} to this component. ");
    _builder.newLineIfNotEmpty();
    _builder.append("<br>The cardinality is ");
    String _name = sourceElement.getCardinality().getName();
    _builder.append(_name);
    _builder.newLineIfNotEmpty();
    _builder.newLine();
    _builder.append("@param ");
    _builder.append(propertyName);
    _builder.append(" the service");
    this.setDocumentation(result, _builder);
    return this.<JvmOperation>associate(sourceElement, result);
  }
  
  /**
   * shorthand for <code>toSetter(sourceElement, name, name, typeRef)</code>
   */
  public JvmOperation toUnbindService(final LInjectedService sourceElement, final String name, final JvmTypeReference typeRef) {
    return this.toUnbindService(sourceElement, name, name, typeRef);
  }
  
  /**
   * Creates a setter method for the given properties name with the standard implementation assigning the passed
   * parameter to a similarly named field.
   * 
   * Example: <code>
   * public void setFoo(String foo) {
   *   this.foo = foo;
   * }
   * </code>
   * 
   * @return a setter method for a JavaBeans property with the given name, <code>null</code> if sourceElement or name are <code>null</code>.
   */
  public JvmOperation toUnbindService(final LInjectedService sourceElement, final String propertyName, final String fieldName, final JvmTypeReference typeRef) {
    if (((Objects.equal(sourceElement, null) || Objects.equal(propertyName, null)) || Objects.equal(fieldName, null))) {
      return null;
    }
    final JvmOperation result = this.typesFactory.createJvmOperation();
    result.setVisibility(JvmVisibility.PROTECTED);
    result.setReturnType(this.references.getTypeForName(Void.TYPE, sourceElement));
    String _firstUpper = Strings.toFirstUpper(propertyName);
    String _plus = CommonTypesBuilder.operator_plus("unbind", _firstUpper);
    result.setSimpleName(_plus);
    EList<JvmFormalParameter> _parameters = result.getParameters();
    JvmFormalParameter _parameter = this.toParameter(sourceElement, propertyName, this.cloneWithProxies(typeRef));
    this.<JvmFormalParameter>operator_add(_parameters, _parameter);
    StringConcatenationClient _client = new StringConcatenationClient() {
      @Override
      protected void appendTo(StringConcatenationClient.TargetStringConcatenation _builder) {
        _builder.append("this.");
        _builder.append(fieldName);
        _builder.append(" = null;");
      }
    };
    this.setBody(result, _client);
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("Unbinds the service from this component. ");
    _builder.newLine();
    _builder.append("<br>The cardinality is ");
    String _name = sourceElement.getCardinality().getName();
    _builder.append(_name);
    _builder.newLineIfNotEmpty();
    _builder.newLine();
    _builder.append("@param ");
    _builder.append(propertyName);
    _builder.append(" the service");
    this.setDocumentation(result, _builder);
    return this.<JvmOperation>associate(sourceElement, result);
  }
  
  /**
   * shorthand for <code>toSetter(sourceElement, name, name, typeRef)</code>
   */
  public JvmOperation toAddService(final LInjectedService sourceElement, final String name, final JvmTypeReference typeRef) {
    return this.toAddService(sourceElement, name, name, typeRef);
  }
  
  /**
   * Creates a setter method for the given properties name with the standard implementation assigning the passed
   * parameter to a similarly named field.
   * 
   * Example: <code>
   * public void setFoo(String foo) {
   *   this.foo = foo;
   * }
   * </code>
   * 
   * @return a setter method for a JavaBeans property with the given name, <code>null</code> if sourceElement or name are <code>null</code>.
   */
  public JvmOperation toAddService(final LInjectedService sourceElement, final String propertyName, final String fieldName, final JvmTypeReference typeRef) {
    if (((Objects.equal(sourceElement, null) || Objects.equal(propertyName, null)) || Objects.equal(fieldName, null))) {
      return null;
    }
    final JvmOperation result = this.typesFactory.createJvmOperation();
    result.setVisibility(JvmVisibility.PROTECTED);
    result.setReturnType(this.references.getTypeForName(Void.TYPE, sourceElement));
    String _firstUpper = Strings.toFirstUpper(propertyName);
    String _plus = CommonTypesBuilder.operator_plus("add", _firstUpper);
    result.setSimpleName(_plus);
    EList<JvmFormalParameter> _parameters = result.getParameters();
    JvmFormalParameter _parameter = this.toParameter(sourceElement, propertyName, this.cloneWithProxies(typeRef));
    this.<JvmFormalParameter>operator_add(_parameters, _parameter);
    StringConcatenationClient _client = new StringConcatenationClient() {
      @Override
      protected void appendTo(StringConcatenationClient.TargetStringConcatenation _builder) {
        _builder.append("if(this.");
        _builder.append(fieldName);
        _builder.append(" == null) {");
        _builder.newLineIfNotEmpty();
        _builder.append("\t");
        _builder.append("this.");
        _builder.append(fieldName, "\t");
        _builder.append(" = new java.util.HashSet<>();");
        _builder.newLineIfNotEmpty();
        _builder.append("}");
        _builder.newLine();
        _builder.newLine();
        _builder.append("if(!this.");
        _builder.append(fieldName);
        _builder.append(".contains(");
        _builder.append(propertyName);
        _builder.append(")) {");
        _builder.newLineIfNotEmpty();
        _builder.append("\t");
        _builder.append("this.");
        _builder.append(fieldName, "\t");
        _builder.append(".add(");
        _builder.append(propertyName, "\t");
        _builder.append(");");
        _builder.newLineIfNotEmpty();
        _builder.append("}");
        _builder.newLine();
      }
    };
    this.setBody(result, _client);
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("Adds the service {@link ");
    String _string = typeRef.getQualifiedName().toString();
    _builder.append(_string);
    _builder.append("} to this component. ");
    _builder.newLineIfNotEmpty();
    _builder.append("<br>The cardinality is ");
    String _name = sourceElement.getCardinality().getName();
    _builder.append(_name);
    _builder.newLineIfNotEmpty();
    _builder.newLine();
    _builder.append("@param ");
    _builder.append(propertyName);
    _builder.append(" the service");
    this.setDocumentation(result, _builder);
    return this.<JvmOperation>associate(sourceElement, result);
  }
  
  /**
   * shorthand for <code>toSetter(sourceElement, name, name, typeRef)</code>
   */
  public JvmOperation toRemoveService(final LInjectedService sourceElement, final String name, final JvmTypeReference typeRef) {
    return this.toRemoveService(sourceElement, name, name, typeRef);
  }
  
  /**
   * Creates a setter method for the given properties name with the standard implementation assigning the passed
   * parameter to a similarly named field.
   * 
   * Example: <code>
   * public void setFoo(String foo) {
   *   this.foo = foo;
   * }
   * </code>
   * 
   * @return a setter method for a JavaBeans property with the given name, <code>null</code> if sourceElement or name are <code>null</code>.
   */
  public JvmOperation toRemoveService(final LInjectedService sourceElement, final String propertyName, final String fieldName, final JvmTypeReference typeRef) {
    if (((Objects.equal(sourceElement, null) || Objects.equal(propertyName, null)) || Objects.equal(fieldName, null))) {
      return null;
    }
    final JvmOperation result = this.typesFactory.createJvmOperation();
    result.setVisibility(JvmVisibility.PROTECTED);
    result.setReturnType(this.references.getTypeForName(Void.TYPE, sourceElement));
    String _firstUpper = Strings.toFirstUpper(propertyName);
    String _plus = CommonTypesBuilder.operator_plus("remove", _firstUpper);
    result.setSimpleName(_plus);
    EList<JvmFormalParameter> _parameters = result.getParameters();
    JvmFormalParameter _parameter = this.toParameter(sourceElement, propertyName, this.cloneWithProxies(typeRef));
    this.<JvmFormalParameter>operator_add(_parameters, _parameter);
    StringConcatenationClient _client = new StringConcatenationClient() {
      @Override
      protected void appendTo(StringConcatenationClient.TargetStringConcatenation _builder) {
        _builder.append("if(this.");
        _builder.append(fieldName);
        _builder.append("==null){");
        _builder.newLineIfNotEmpty();
        _builder.append("\t");
        _builder.append("return;");
        _builder.newLine();
        _builder.append("}");
        _builder.newLine();
        _builder.append("this.");
        _builder.append(fieldName);
        _builder.append(".remove(");
        _builder.append(propertyName);
        _builder.append(");");
      }
    };
    this.setBody(result, _client);
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("Removes the service {@link ");
    String _qualifiedName = this.cloneWithProxies(typeRef).getQualifiedName();
    _builder.append(_qualifiedName);
    _builder.append("} from this component. ");
    _builder.newLineIfNotEmpty();
    _builder.append("<br>The cardinality is ");
    String _name = sourceElement.getCardinality().getName();
    _builder.append(_name);
    _builder.newLineIfNotEmpty();
    _builder.newLine();
    _builder.append("@param ");
    _builder.append(propertyName);
    _builder.append(" the service");
    this.setDocumentation(result, _builder);
    return this.<JvmOperation>associate(sourceElement, result);
  }
  
  public JvmOperation toGetMethod(final LDTOService service) {
    return _toGetMethod(service);
  }
}
