/*
 *                                                                            
 *  Copyright (c) 2011 - 2019 - Loetz GmbH & Co KG, 69115 Heidelberg, Germany 
 *                                                                            
 *  All rights reserved. This program and the accompanying materials           
 *  are made available under the terms of the Eclipse Public License v1.0       
 *  which accompanies this distribution, and is available at                  
 *  http://www.eclipse.org/legal/epl-v10.html                                 
 *                                                                            
 *  Initial contribution:                                                      
 *     Loetz GmbH & Co. KG                              
 * 
 */
package org.eclipse.osbp.ide.core.ui.builder;

import org.eclipse.osbp.dsl.semantic.common.types.LTypedPackage;
import org.eclipse.osbp.dsl.semantic.dto.LDto;
import org.eclipse.osbp.dsl.semantic.dto.LDtoAttribute;
import org.eclipse.osbp.dsl.semantic.dto.util.NamingConventionsUtil;
import org.eclipse.osbp.dsl.semantic.service.LDTOService;
import org.eclipse.osbp.dsl.semantic.service.LServiceOperation;
import org.eclipse.osbp.dsl.semantic.service.OSBPServiceFactory;
import org.eclipse.osbp.ide.core.ui.builder.OSBPModelEnhancingBuilder.ServiceEnhancer.ServiceEnhancerContext;
import org.eclipse.xtext.common.types.JvmArrayType;
import org.eclipse.xtext.common.types.JvmFormalParameter;
import org.eclipse.xtext.common.types.JvmGenericArrayTypeReference;
import org.eclipse.xtext.common.types.JvmGenericType;
import org.eclipse.xtext.common.types.JvmOperation;
import org.eclipse.xtext.common.types.JvmParameterizedTypeReference;
import org.eclipse.xtext.common.types.JvmTypeParameter;
import org.eclipse.xtext.common.types.JvmTypeReference;
import org.eclipse.xtext.common.types.JvmVisibility;
import org.eclipse.xtext.common.types.JvmWildcardTypeReference;
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.XAssignment;
import org.eclipse.xtext.xbase.XBinaryOperation;
import org.eclipse.xtext.xbase.XBlockExpression;
import org.eclipse.xtext.xbase.XCastedExpression;
import org.eclipse.xtext.xbase.XFeatureCall;
import org.eclipse.xtext.xbase.XMemberFeatureCall;
import org.eclipse.xtext.xbase.XNumberLiteral;
import org.eclipse.xtext.xbase.XReturnExpression;
import org.eclipse.xtext.xbase.XSetLiteral;
import org.eclipse.xtext.xbase.XStringLiteral;
import org.eclipse.xtext.xbase.XVariableDeclaration;
import org.eclipse.xtext.xbase.XbaseFactory;

/**
 * ServiceEnhancerHelper creates methods in the service model to handle stateClasses.
 */
public class ServiceEnhancerHelper { 
	
	private static final String NUMBER_OF = "numberOfStates";

	private static final String NEXT = "nextState";

	private static final String PREVIOUS = "previousState";

	private static final String ABSTRACT_DTO_SERVICE = "AbstractDTOService";

	private static final String JAVA_LANG = "java.lang";

	private static final String JAVA_LANG_LONG = "java.lang.Long";

	private static final String ORG_ECLIPSE_OSBP_RUNTIME_COMMON_FILTER_IJPQL = "org.eclipse.osbp.runtime.common.filter.IJPQL";

	private static final String JAVA_LANG_OBJECT = "java.lang.Object";

	private static final String JAVA_LANG_STRING = "java.lang.String";

	private static final String ORG_ECLIPSE_OSBP_JPA_SERVICES_JPQL = "org.eclipse.osbp.jpa.services.JPQL";

	/** The Constant ORG_ECLIPSE_OSBP_DSL_DTO_LIB_SERVICES_IMPL. */
	private static final String ORG_ECLIPSE_OSBP_DSL_DTO_LIB_SERVICES_IMPL = "org.eclipse.osbp.dsl.dto.lib.services.impl";

	/** The Constant JAVA_UTIL. */
	private static final String JAVA_UTIL = "java.util";

	/** The Constant ORG_ECLIPSE_XTEXT_XBASE_LIB. */
	private static final String ORG_ECLIPSE_XTEXT_XBASE_LIB = "org.eclipse.xtext.xbase.lib";

	/** The dto name provider. */
	private IQualifiedNameProvider dtoNameProvider;
	
	/** The context. */
	private ServiceEnhancerContext context;
	
	/** The type refs. */
	private TypeReferences typeRefs;

	/**
	 * Instantiates a new service enhancer helper.
	 *
	 * @param dtoNameProvider the dto name provider
	 * @param context the context
	 * @param typeRefs the type refs
	 */
	public ServiceEnhancerHelper(IQualifiedNameProvider dtoNameProvider, ServiceEnhancerContext context, TypeReferences typeRefs) {
		this.dtoNameProvider = dtoNameProvider;
		this.context = context;
		this.typeRefs = typeRefs;
	}

	/**
	 * finds old operation.
	 *
	 * @param lService the l service
	 * @param opName the op name
	 */
	private LServiceOperation findOperation(LDTOService lService, String opName) {
		for(LServiceOperation op : lService.getOperations()) {
			if(opName.equals(op.getName())) {
				return op;
			}
		}
		return null;
	}

	/**
	 * Creates the state class methods.
	 *
	 * @param lService the l service
	 * @param lDto the l dto
	 * @param attribute the attribute
	 */
	public void createStateClassMethods(LDTOService lService, LDto lDto, LDtoAttribute attribute) {
		if(!lService.getOperations().contains(findOperation(lService, NEXT))) {
			lService.getOperations().add(createChangeStateClassMethod(lDto, attribute, NEXT));
		}
		if(!lService.getOperations().contains(findOperation(lService, PREVIOUS))) {
			lService.getOperations().add(createChangeStateClassMethod(lDto, attribute, PREVIOUS));
		}
		if(!lService.getOperations().contains(findOperation(lService, NUMBER_OF))) {
			lService.getOperations().add(createCountStateClassMethod(lService, lDto, attribute, NUMBER_OF));
		}
	}

	/**
	 * Creates the state class methods.
	 *
	 * @param lService the l service
	 * @param lDto the l dto
	 * @param attribute the attribute
	 * @param operationName the method name
	 * @return the l service operation
	 */
	private LServiceOperation createCountStateClassMethod(LDTOService lService, LDto lDto, LDtoAttribute attribute, String operationName) {
		String stateClassPackage = dtoNameProvider.getFullyQualifiedName(attribute.getType()).skipLast(1).toString();
		String stateClassName = dtoNameProvider.getFullyQualifiedName(attribute.getType()).getLastSegment();
		LServiceOperation operation = OSBPServiceFactory.eINSTANCE.createLServiceOperation();
		operation.setName(operationName);

		JvmFormalParameter para = TypesFactory.eINSTANCE.createJvmFormalParameter();
		para.setName(NamingConventionsUtil.toFirstLower(stateClassName));
		para.setParameterType(typeRefs.getTypeForName(JAVA_LANG_OBJECT, context.serviceResource));
		operation.getParams().add(para);

		XBlockExpression xBlock = XbaseFactory.eINSTANCE.createXBlockExpression();
		
		XVariableDeclaration query = createQueryVariable(lDto, attribute, stateClassPackage, stateClassName);
		xBlock.getExpressions().add(query);
		XVariableDeclaration result = createResultVariable(lService, lDto, query);
		xBlock.getExpressions().add(result);
		xBlock.getExpressions().add(createCountReturnStatement(result));
		
		operation.setBody(xBlock);
		operation.setType(typeRefs.getTypeForName(JAVA_LANG_LONG, context.serviceResource));
		return operation;
	}

	/**
	 * Creates the change state class method.
	 *
	 * @param lService the l service
	 * @param lDto the l dto
	 * @param attribute the attribute
	 * @param operationName the method name
	 * @return the l service operation
	 */
	private LServiceOperation createChangeStateClassMethod(LDto lDto, LDtoAttribute attribute, String operationName) {
		String stateClassPackage = dtoNameProvider.getFullyQualifiedName(attribute.getType()).skipLast(1).toString();
		String stateClassName = dtoNameProvider.getFullyQualifiedName(attribute.getType()).getLastSegment();
		String dtoPackage = dtoNameProvider.getFullyQualifiedName(lDto).skipLast(1).toString();
		String dtoName = lDto.getName();
		LServiceOperation operation = OSBPServiceFactory.eINSTANCE.createLServiceOperation();
		operation.setName(operationName);
		JvmFormalParameter para = TypesFactory.eINSTANCE.createJvmFormalParameter();
		para.setName(NamingConventionsUtil.toFirstLower(lDto.getName()));
		para.setParameterType(typeRefs.getTypeForName(JAVA_LANG_OBJECT, context.serviceResource));
		operation.getParams().add(para);
		XBlockExpression xBlock = XbaseFactory.eINSTANCE.createXBlockExpression();
		
		XVariableDeclaration values = createValuesVariable(stateClassPackage, stateClassName);
		xBlock.getExpressions().add(values);
		XVariableDeclaration ordinal = createOrdinalVariable(attribute, dtoPackage, dtoName, stateClassPackage, stateClassName);
		xBlock.getExpressions().add(ordinal);
		if(NEXT.equals(operationName)) {
			xBlock.getExpressions().add(createOrdinalAssignment(ordinal, "operator_plus"));
		}
		if(PREVIOUS.equals(operationName)) {
			xBlock.getExpressions().add(createOrdinalAssignment(ordinal, "operator_minus"));
		}
		xBlock.getExpressions().add(createStateAssignment(attribute, dtoPackage, dtoName,
				stateClassPackage, stateClassName, values, ordinal));
		xBlock.getExpressions().add(createUpdate(dtoPackage, dtoName));
		
		operation.setBody(xBlock);
		operation.setType(typeRefs.getTypeForName(Void.TYPE, context.serviceResource));
		return operation;
	}

	/**
	 * Creates the query variable.
	 *
	 * @param dto the dto
	 * @param attribute the attribute
	 * @param stateClassPackage the state class package
	 * @param stateClassName the state class name
	 * @return the x variable declaration
	 */
	private XVariableDeclaration createQueryVariable(LDto dto, LDtoAttribute attribute,	String stateClassPackage, String stateClassName) {
		// val query
		XVariableDeclaration varDecl = XbaseFactory.eINSTANCE.createXVariableDeclaration();
		varDecl.setName("query");
		varDecl.setWriteable(true);
		
		// right
		XFeatureCall right = XbaseFactory.eINSTANCE.createXFeatureCall();
		
		// feature(right)
		JvmOperation oper = TypesFactory.eINSTANCE.createJvmOperation();
		JvmGenericType dtoServiceType = TypesFactory.eINSTANCE.createJvmGenericType();
		dtoServiceType.setPackageName(ORG_ECLIPSE_OSBP_DSL_DTO_LIB_SERVICES_IMPL);
		dtoServiceType.setSimpleName(ABSTRACT_DTO_SERVICE);
		oper.setDeclaringType(dtoServiceType);
		oper.setSimpleName("createJPQL");
		oper.setReturnType(typeRefs.getTypeForName(ORG_ECLIPSE_OSBP_JPA_SERVICES_JPQL, context.serviceResource));
		
		// parameters(feature(right))
		JvmFormalParameter para1 = TypesFactory.eINSTANCE.createJvmFormalParameter();
		para1.setParameterType(typeRefs.getTypeForName(JAVA_LANG_STRING, context.serviceResource));
		oper.getParameters().add(para1);
		JvmFormalParameter para2 = TypesFactory.eINSTANCE.createJvmFormalParameter();
		JvmParameterizedTypeReference ptr = TypesFactory.eINSTANCE.createJvmParameterizedTypeReference();
		JvmGenericType gt = TypesFactory.eINSTANCE.createJvmGenericType();
		gt.setPackageName(JAVA_UTIL);
		gt.setSimpleName("Map");
		ptr.setType(gt);
		ptr.getArguments().add(typeRefs.getTypeForName(JAVA_LANG_STRING, context.serviceResource));
		ptr.getArguments().add(typeRefs.getTypeForName(JAVA_LANG_OBJECT, context.serviceResource));
		para2.setParameterType(ptr);
		oper.getParameters().add(para2);
		right.setFeature(oper);
		// feature(right) end
		
		// featureCallArguments(right)
		// first element
		XStringLiteral queryString = XbaseFactory.eINSTANCE.createXStringLiteral();
		queryString.setValue(String.format("select count(t) from %s t where t.%s = :%s", dto.getWrappedType().getName(), attribute.getName(), "StateClass"+stateClassName));
		right.getFeatureCallArguments().add(queryString);
		// second element
		XSetLiteral set = XbaseFactory.eINSTANCE.createXSetLiteral();
		// binary operation(second element)
		XBinaryOperation binOp = XbaseFactory.eINSTANCE.createXBinaryOperation();
		// left operand(binary operation(second element))
		XStringLiteral left2 = XbaseFactory.eINSTANCE.createXStringLiteral();
		left2.setValue("StateClass"+stateClassName);
		binOp.setLeftOperand(left2);
		// right operand(binary operation(second element))
		XFeatureCall right2 = XbaseFactory.eINSTANCE.createXFeatureCall();
		// feature(right operand(binary operation(second element)))
		JvmFormalParameter para5 = TypesFactory.eINSTANCE.createJvmFormalParameter();
		para5.setName(NamingConventionsUtil.toFirstLower(stateClassName));
		para5.setParameterType(typeRefs.getTypeForName(JAVA_LANG_OBJECT, context.serviceResource));
		right2.setFeature(para5);
		binOp.setRightOperand(right2);
		// right operand end
		
		// feature(binary operation(second element)))
		JvmOperation mapOperation = TypesFactory.eINSTANCE.createJvmOperation();
		JvmGenericType mapType = TypesFactory.eINSTANCE.createJvmGenericType();
		mapType.setPackageName(ORG_ECLIPSE_XTEXT_XBASE_LIB);
		mapType.setSimpleName("ObjectExtensions");
		mapOperation.setDeclaringType(mapType);
		mapOperation.setSimpleName("operator_mappedTo");
		mapOperation.setDeprecated(false);
		mapOperation.setVisibility(JvmVisibility.PUBLIC);
		mapOperation.setStatic(true);
		// parameter1(feature(binary operation(second element))))
		JvmFormalParameter para3 = TypesFactory.eINSTANCE.createJvmFormalParameter();
		para3.setParameterType(createObjectType("A"));
		mapOperation.getParameters().add(para3);
		// parameter2(feature(binary operation(second element))))
		JvmFormalParameter para4 = TypesFactory.eINSTANCE.createJvmFormalParameter();
		para4.setParameterType(createObjectType("B"));
		mapOperation.getParameters().add(para4);
		// return type(feature(binary operation(second element))))
		JvmParameterizedTypeReference retType = TypesFactory.eINSTANCE.createJvmParameterizedTypeReference();
		// arguments(return type(feature(binary operation(second element)))))
		retType.getArguments().add(createObjectType("A"));
		retType.getArguments().add(createObjectType("B"));
		// type(return type(feature(binary operation(second element)))))
		JvmGenericType gt1 = TypesFactory.eINSTANCE.createJvmGenericType();
		gt1.setPackageName(ORG_ECLIPSE_XTEXT_XBASE_LIB);
		gt1.setSimpleName("Pair");
		// type parameters(type(return type(feature(binary operation(second element))))))
		JvmTypeParameter tp1 = TypesFactory.eINSTANCE.createJvmTypeParameter();
		tp1.setName("K");
		gt1.getTypeParameters().add(tp1);
		JvmTypeParameter tp2 = TypesFactory.eINSTANCE.createJvmTypeParameter();
		tp2.setName("V");
		gt1.getTypeParameters().add(tp2);
		retType.setType(gt1);
		// return type end 
		mapOperation.setReturnType(retType);
		binOp.setFeature(mapOperation);
		// binary operation end
		set.getElements().add(binOp);
		right.getFeatureCallArguments().add(set);
		right.setExplicitOperationCall(true);
		varDecl.setRight(right);
		return varDecl;
	}

	/**
	 * Creates the result variable.
	 *
	 * @param lService the l service
	 * @param dto the dto
	 * @param query the query
	 * @return the x variable declaration
	 */
	private XVariableDeclaration createResultVariable(LDTOService lService, LDto dto, XVariableDeclaration query) {
		// val result
		XVariableDeclaration varDecl = XbaseFactory.eINSTANCE.createXVariableDeclaration();
		varDecl.setName("result");
		varDecl.setWriteable(true);

		// right
		XMemberFeatureCall right = XbaseFactory.eINSTANCE.createXMemberFeatureCall();
		
		// feature(right)
		JvmOperation oper = TypesFactory.eINSTANCE.createJvmOperation();
		JvmGenericType dtoServiceType = TypesFactory.eINSTANCE.createJvmGenericType();
		dtoServiceType.setPackageName(ORG_ECLIPSE_OSBP_DSL_DTO_LIB_SERVICES_IMPL);
		dtoServiceType.setSimpleName(ABSTRACT_DTO_SERVICE);
		oper.setDeclaringType(dtoServiceType);
		oper.setSimpleName("findValues");
		// return type(feature(right))
		// arguments(return type(feature(right)))
		JvmParameterizedTypeReference retType = TypesFactory.eINSTANCE.createJvmParameterizedTypeReference();
		JvmWildcardTypeReference wildCard = TypesFactory.eINSTANCE.createJvmWildcardTypeReference();
		retType.getArguments().add(wildCard);
		JvmGenericType gt = TypesFactory.eINSTANCE.createJvmGenericType();
		gt.setPackageName(JAVA_UTIL);
		gt.setSimpleName("List");
		retType.setType(gt);
		oper.setReturnType(retType);
		oper.setVisibility(JvmVisibility.PUBLIC);
		
		// parameters(feature(right))
		JvmFormalParameter para1 = TypesFactory.eINSTANCE.createJvmFormalParameter();
		para1.setParameterType(typeRefs.getTypeForName(ORG_ECLIPSE_OSBP_RUNTIME_COMMON_FILTER_IJPQL, context.serviceResource));
		oper.getParameters().add(para1);
		right.setFeature(oper);
		// feature(right) end
		
		// member call arguments(right)
		XFeatureCall fCallArg = XbaseFactory.eINSTANCE.createXFeatureCall();
		fCallArg.setFeature(query);
		right.getMemberCallArguments().add(fCallArg);
		
		// member call target(right)
		XFeatureCall fCall = XbaseFactory.eINSTANCE.createXFeatureCall();
		JvmGenericType thiz = TypesFactory.eINSTANCE.createJvmGenericType();
		thiz.setPackageName(getServicePackageName(dto));
		thiz.setSimpleName(lService.getName());
		thiz.setVisibility(JvmVisibility.PUBLIC);
		
		fCall.setFeature(thiz);
		right.setMemberCallTarget(fCall);
		
		right.setExplicitOperationCall(true);
		varDecl.setRight(right);
		return varDecl;
	}

	/**
	 * Creates the count return statement.
	 *
	 * @param result the result
	 * @return the x return expression
	 */
	private XReturnExpression createCountReturnStatement(XVariableDeclaration result) {
		XReturnExpression xReturn = XbaseFactory.eINSTANCE.createXReturnExpression();
		XCastedExpression xCasted = XbaseFactory.eINSTANCE.createXCastedExpression();

		XMemberFeatureCall target = XbaseFactory.eINSTANCE.createXMemberFeatureCall();
		JvmOperation oper = TypesFactory.eINSTANCE.createJvmOperation();
		JvmGenericType gt = TypesFactory.eINSTANCE.createJvmGenericType();
		gt.setPackageName(JAVA_UTIL);
		gt.setSimpleName("List");
		oper.setDeclaringType(gt);
		oper.setSimpleName("get");
		oper.setReturnType(createObjectType("E"));
		oper.setVisibility(JvmVisibility.PUBLIC);
		oper.setAbstract(true);

		JvmFormalParameter para = TypesFactory.eINSTANCE.createJvmFormalParameter();
		para.setParameterType(typeRefs.getTypeForName(Integer.TYPE, context.serviceResource));
		oper.getParameters().add(para);
		target.setFeature(oper);
		target.setExplicitOperationCall(true);
		
		XNumberLiteral index = XbaseFactory.eINSTANCE.createXNumberLiteral();
		index.setValue("00");
		target.getMemberCallArguments().add(index);
		
		XFeatureCall fCall = XbaseFactory.eINSTANCE.createXFeatureCall();
		fCall.setFeature(result);
		target.setMemberCallTarget(fCall);
		
		xCasted.setTarget(target);
		xCasted.setType(typeRefs.getTypeForName(JAVA_LANG_LONG, context.serviceResource));
		xReturn.setExpression(xCasted);
		return xReturn;
	}
	
	/**
	 * Creates the values variable.
	 *
	 * @param stateClassPackage the state class package
	 * @param stateClassName the state class name
	 * @return the x variable declaration
	 * var values = Idee.values
	 */
	private XVariableDeclaration createValuesVariable(String stateClassPackage, String stateClassName) {
		XVariableDeclaration varDecl = XbaseFactory.eINSTANCE.createXVariableDeclaration();
		varDecl.setName("values");
		varDecl.setWriteable(true);
		XMemberFeatureCall right = XbaseFactory.eINSTANCE.createXMemberFeatureCall();
		JvmOperation oper = TypesFactory.eINSTANCE.createJvmOperation();
		JvmGenericType stateClassType = TypesFactory.eINSTANCE.createJvmGenericType();
		stateClassType.setPackageName(stateClassPackage);
		stateClassType.setSimpleName(stateClassName);
		oper.setDeclaringType(stateClassType);
		oper.setSimpleName("values");
		JvmTypeReference stateClassTypeRef = typeRefs.getTypeForName(stateClassPackage+"."+stateClassName, context.serviceResource);
		JvmGenericArrayTypeReference arrayType = typeRefs.createArrayType(stateClassTypeRef);
		oper.setReturnType(arrayType);
		right.setFeature(oper);
		XFeatureCall fCall = XbaseFactory.eINSTANCE.createXFeatureCall();
		JvmGenericType fCallType = TypesFactory.eINSTANCE.createJvmGenericType();
		fCallType.setSimpleName(stateClassName);
		fCallType.setPackageName(stateClassPackage);
		fCall.setFeature(fCallType);
		fCall.setTypeLiteral(true);
		right.setMemberCallTarget(fCall);
		varDecl.setRight(right);
		return varDecl;
	}

	/**
	 * Creates the ordinal variable.
	 *
	 * @param attribute the attribute
	 * @param dtoPackage the dto package
	 * @param dtoName the dto name
	 * @param stateClassPackage the state class package
	 * @param stateClassName the state class name
	 * @return the x variable declaration
	 * var ordinal = testEntityDto.idee.ordinal
	 */
	private XVariableDeclaration createOrdinalVariable(LDtoAttribute attribute, String dtoPackage, String dtoName, String stateClassPackage, String stateClassName) {
		XVariableDeclaration varDecl = XbaseFactory.eINSTANCE.createXVariableDeclaration();
		varDecl.setName("ordinal");
		varDecl.setWriteable(true);
		XMemberFeatureCall right = XbaseFactory.eINSTANCE.createXMemberFeatureCall();
		right.setFeature(createOrdinalOperation());
		right.setNullSafe(true);
		XMemberFeatureCall mfCall = XbaseFactory.eINSTANCE.createXMemberFeatureCall();
		JvmOperation oper2 = TypesFactory.eINSTANCE.createJvmOperation();
		oper2.setSimpleName(attribute.getName());
		oper2.setReturnType(typeRefs.getTypeForName(stateClassPackage+"."+stateClassName, context.serviceResource));
		oper2.setVisibility(JvmVisibility.PUBLIC);
		mfCall.setFeature(oper2);

		XCastedExpression casted = XbaseFactory.eINSTANCE.createXCastedExpression();
		XFeatureCall fCall = XbaseFactory.eINSTANCE.createXFeatureCall();
		JvmFormalParameter para = TypesFactory.eINSTANCE.createJvmFormalParameter();
		para.setName(NamingConventionsUtil.toFirstLower(dtoName));
		para.setParameterType(typeRefs.getTypeForName(dtoPackage+"."+dtoName, context.serviceResource));
		fCall.setFeature(para);
		casted.setTarget(fCall);
		casted.setType(typeRefs.getTypeForName(dtoPackage+"."+dtoName, context.serviceResource));
		
		mfCall.setMemberCallTarget(casted);

		right.setMemberCallTarget(mfCall);
		varDecl.setRight(right);
		return varDecl;
	}

	/**
	 * Creates the ordinal assignment.
	 *
	 * @param ordinal the ordinal
	 * @param operator the operator
	 * @return the x assignment
	 * ordinal = ordinal + 01
	 */
	private XAssignment createOrdinalAssignment(XVariableDeclaration ordinal, String operator) {
		XAssignment xAssign = XbaseFactory.eINSTANCE.createXAssignment();
		
		xAssign.setFeature(ordinal);

		XBinaryOperation binOp = XbaseFactory.eINSTANCE.createXBinaryOperation();

		XFeatureCall left = XbaseFactory.eINSTANCE.createXFeatureCall();
		left.setFeature(ordinal);
		binOp.setLeftOperand(left);
		
		XNumberLiteral right = XbaseFactory.eINSTANCE.createXNumberLiteral();
		right.setValue("01");
		binOp.setRightOperand(right);

		JvmOperation plusOperation = TypesFactory.eINSTANCE.createJvmOperation();
		JvmGenericType plusType = TypesFactory.eINSTANCE.createJvmGenericType();
		plusType.setPackageName(ORG_ECLIPSE_XTEXT_XBASE_LIB);
		plusType.setSimpleName("IntegerExtensions");
		plusOperation.setDeclaringType(plusType);
		plusOperation.setSimpleName(operator);
		plusOperation.setDeprecated(false);
		plusOperation.setVisibility(JvmVisibility.PUBLIC);
		plusOperation.setStatic(true);

		JvmFormalParameter para1 = TypesFactory.eINSTANCE.createJvmFormalParameter();
		para1.setParameterType(typeRefs.getTypeForName(Integer.TYPE, context.serviceResource));
		plusOperation.getParameters().add(para1);
		JvmFormalParameter para2 = TypesFactory.eINSTANCE.createJvmFormalParameter();
		para2.setParameterType(typeRefs.getTypeForName(Integer.TYPE, context.serviceResource));
		plusOperation.getParameters().add(para2);

		plusOperation.setReturnType(typeRefs.getTypeForName(Integer.TYPE, context.serviceResource));
		binOp.setFeature(plusOperation);

		xAssign.setValue(binOp);
		return xAssign;
	}

	/**
	 * Creates the state assignment.
	 *
	 * @param attribute the attribute
	 * @param dtoPackage the dto package
	 * @param dtoName the dto name
	 * @param stateClassPackage the state class package
	 * @param stateClassName the state class name
	 * @param values the values
	 * @param ordinal the ordinal
	 * @return the x assignment
	 * testEntityDto.idee = values.get( ordinal )
	 */
	private XAssignment createStateAssignment(LDtoAttribute attribute, String dtoPackage, String dtoName, String stateClassPackage, String stateClassName,
			XVariableDeclaration values, XVariableDeclaration ordinal) {
		XAssignment xAssign = XbaseFactory.eINSTANCE.createXAssignment();
		JvmOperation setterOperation = TypesFactory.eINSTANCE.createJvmOperation();
		JvmGenericType dtoType = TypesFactory.eINSTANCE.createJvmGenericType();
		dtoType.setPackageName(dtoPackage);
		dtoType.setSimpleName(dtoName);
		setterOperation.setDeclaringType(dtoType);
		setterOperation.setSimpleName("set" + NamingConventionsUtil.toFirstUpper(attribute.getName()));
		setterOperation.setReturnType(typeRefs.getTypeForName(Void.TYPE, context.serviceResource));
		setterOperation.setVisibility(JvmVisibility.PUBLIC);
		JvmFormalParameter para3 = TypesFactory.eINSTANCE.createJvmFormalParameter();
		para3.setName(attribute.getName());
		JvmParameterizedTypeReference tr = TypesFactory.eINSTANCE.createJvmParameterizedTypeReference();
		tr.setType(typeRefs.getTypeForName(stateClassPackage+"."+stateClassName, context.serviceResource).getType());
		para3.setParameterType(tr);
		setterOperation.getParameters().add(para3);
		xAssign.setFeature(setterOperation);

		XCastedExpression casted = XbaseFactory.eINSTANCE.createXCastedExpression();
		XFeatureCall fCall = XbaseFactory.eINSTANCE.createXFeatureCall();
		JvmFormalParameter para = TypesFactory.eINSTANCE.createJvmFormalParameter();
		para.setName(NamingConventionsUtil.toFirstLower(dtoName));
		para.setParameterType(typeRefs.getTypeForName(dtoPackage+"."+dtoName, context.serviceResource));
		fCall.setFeature(para);
		casted.setTarget(fCall);
		casted.setType(typeRefs.getTypeForName(dtoPackage+"."+dtoName, context.serviceResource));
		
		xAssign.setAssignable(casted);
		
		XMemberFeatureCall mfCall = XbaseFactory.eINSTANCE.createXMemberFeatureCall();
		JvmOperation getterOperation = TypesFactory.eINSTANCE.createJvmOperation();
		JvmGenericType getType = TypesFactory.eINSTANCE.createJvmGenericType();
		getType.setPackageName(ORG_ECLIPSE_XTEXT_XBASE_LIB);
		getType.setSimpleName("ArrayExtensions");
		getterOperation.setDeclaringType(getType);
		getterOperation.setSimpleName("get");
		getterOperation.setDeprecated(false);
		getterOperation.setVisibility(JvmVisibility.PUBLIC);
		getterOperation.setStatic(true);

		JvmArrayType arrayType = TypesFactory.eINSTANCE.createJvmArrayType();
		JvmTypeParameter tp = TypesFactory.eINSTANCE.createJvmTypeParameter();
		tp.setName("T");
		tp.setArrayType(arrayType);

		getterOperation.getTypeParameters().add(tp);

		JvmFormalParameter para1 = TypesFactory.eINSTANCE.createJvmFormalParameter();
		JvmParameterizedTypeReference ptr = TypesFactory.eINSTANCE.createJvmParameterizedTypeReference();
		JvmGenericType gt = TypesFactory.eINSTANCE.createJvmGenericType();
		gt.setSimpleName("T");
		ptr.setType(gt);
		JvmGenericArrayTypeReference arrayTypeRef = typeRefs.createArrayType(ptr);
		para1.setParameterType(arrayTypeRef);
		getterOperation.getParameters().add(para1);
		JvmFormalParameter para2 = TypesFactory.eINSTANCE.createJvmFormalParameter();
		para2.setParameterType(typeRefs.getTypeForName(Integer.TYPE, context.serviceResource));
		getterOperation.getParameters().add(para2);
		getterOperation.setReturnType(typeRefs.getTypeForName(stateClassPackage+"."+stateClassName, context.serviceResource));
		mfCall.setFeature(getterOperation);
		mfCall.setExplicitOperationCall(true);

		XFeatureCall callTarget = XbaseFactory.eINSTANCE.createXFeatureCall();
		callTarget.setFeature(values);
		mfCall.setMemberCallTarget(callTarget);

		XFeatureCall callArgument = XbaseFactory.eINSTANCE.createXFeatureCall();
		callArgument.setFeature(ordinal);
		mfCall.getMemberCallArguments().add(callArgument);

		xAssign.setValue(mfCall);
		return xAssign;
	}

	private XMemberFeatureCall createUpdate(String dtoPackage, String dtoName) {
		XMemberFeatureCall update = XbaseFactory.eINSTANCE.createXMemberFeatureCall();
		update.setExplicitOperationCall(true);

		// feature
		JvmOperation oper = TypesFactory.eINSTANCE.createJvmOperation();
		JvmGenericType dtoServiceType = TypesFactory.eINSTANCE.createJvmGenericType();
		dtoServiceType.setPackageName(ORG_ECLIPSE_OSBP_DSL_DTO_LIB_SERVICES_IMPL);
		dtoServiceType.setSimpleName(ABSTRACT_DTO_SERVICE);
		oper.setDeclaringType(dtoServiceType);
		oper.setSimpleName("update");
		oper.setReturnType(typeRefs.getTypeForName(Void.TYPE, context.serviceResource));
		oper.setVisibility(JvmVisibility.PUBLIC);
		
		// parameters(feature)
		JvmFormalParameter para = TypesFactory.eINSTANCE.createJvmFormalParameter();
		JvmParameterizedTypeReference paraType = TypesFactory.eINSTANCE.createJvmParameterizedTypeReference();
		JvmTypeParameter tp = TypesFactory.eINSTANCE.createJvmTypeParameter();
		tp.setName("DTO");
		JvmGenericType gt = TypesFactory.eINSTANCE.createJvmGenericType();
		gt.setPackageName(ORG_ECLIPSE_OSBP_DSL_DTO_LIB_SERVICES_IMPL);
		gt.setSimpleName(ABSTRACT_DTO_SERVICE);
		tp.setDeclarator(gt);
		paraType.setType(tp);
		para.setParameterType(paraType);
		oper.getParameters().add(para);
		
		// memberCallTarget
		XCastedExpression casted = XbaseFactory.eINSTANCE.createXCastedExpression();
		XFeatureCall fCall = XbaseFactory.eINSTANCE.createXFeatureCall();
		JvmFormalParameter para2 = TypesFactory.eINSTANCE.createJvmFormalParameter();
		para2.setName(NamingConventionsUtil.toFirstLower(dtoName));
		para2.setParameterType(typeRefs.getTypeForName(dtoPackage+"."+dtoName, context.serviceResource));
		fCall.setFeature(para2);
		casted.setTarget(fCall);
		casted.setType(typeRefs.getTypeForName(dtoPackage+"."+dtoName, context.serviceResource));
		update.setMemberCallTarget(casted);

		update.setFeature(oper);
		
		return update;
	}

	/**
	 * Creates a named object type reference.
	 *
	 * @param name the name
	 * @return the jvm formal parameter
	 */
	private JvmParameterizedTypeReference createObjectType(String name) {
		JvmParameterizedTypeReference paraType = TypesFactory.eINSTANCE.createJvmParameterizedTypeReference();
		JvmTypeParameter tp = TypesFactory.eINSTANCE.createJvmTypeParameter();
		JvmGenericType gt = TypesFactory.eINSTANCE.createJvmGenericType();
		gt.setPackageName(JAVA_LANG);
		gt.setSimpleName("Object");
		tp.setDeclarator(gt);
		tp.setName(name);
		paraType.setType(tp);
		return paraType;
	}

	/**
	 * Creates the ordinal operation of an enum.
	 * -> currently not used
	 * @return the JvmOperation
	 */
	private JvmOperation createOrdinalOperation() {
		JvmOperation oper = TypesFactory.eINSTANCE.createJvmOperation();
		oper.setSimpleName("ordinal");
		JvmGenericType enumType = TypesFactory.eINSTANCE.createJvmGenericType();
		enumType.setPackageName(JAVA_LANG);
		enumType.setSimpleName("Enum");
		oper.setDeclaringType(enumType);
		oper.setReturnType(typeRefs.getTypeForName(Integer.TYPE, context.serviceResource));
		oper.setVisibility(JvmVisibility.PUBLIC);
		oper.setFinal(true);
		return oper;
	}

	/**
	 * Gets the service package name.
	 *
	 * @param lDto the dto
	 * @return the service package name
	 */
	public String getServicePackageName(LDto lDto) {
		LTypedPackage lSourceTypePkg = (LTypedPackage) lDto.eContainer();
		return lSourceTypePkg.getName() + ".service";
	}
}
