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

import com.google.inject.Inject
import java.util.ArrayList
import javax.persistence.PreRemove
import org.eclipse.osbp.dsl.common.xtext.extensions.TreeAppendableExtensions
import org.eclipse.osbp.dsl.common.xtext.jvmmodel.CommonTypesBuilder
import org.eclipse.osbp.dsl.entity.xtext.jvmmodel.AnnotationCompiler
import org.eclipse.osbp.dsl.entity.xtext.linker.EntityLinker
import org.eclipse.osbp.dsl.semantic.common.types.LClass
import org.eclipse.osbp.dsl.semantic.common.types.LFeature
import org.eclipse.osbp.dsl.semantic.common.types.LPackage
import org.eclipse.osbp.dsl.semantic.common.types.LType
import org.eclipse.osbp.dsl.semantic.entity.LBean
import org.eclipse.osbp.dsl.semantic.entity.LBeanFeature
import org.eclipse.osbp.dsl.semantic.entity.LBeanReference
import org.eclipse.osbp.dsl.semantic.entity.LEntity
import org.eclipse.osbp.dsl.semantic.entity.LEntityFeature
import org.eclipse.osbp.dsl.semantic.entity.LEntityReference
import org.eclipse.osbp.dsl.semantic.entity.LOperation
import org.eclipse.xtext.common.types.JvmField
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.util.EcoreGenericsUtil
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1
import org.eclipse.osbp.runtime.common.historized.UUIDHist
import org.eclipse.osbp.dsl.semantic.entity.LEntityAttribute
import org.eclipse.osbp.dsl.semantic.common.types.LReference
import org.eclipse.osbp.dsl.semantic.common.types.LStateClass

class EntityTypesBuilder extends CommonTypesBuilder {

	@Inject extension ModelExtensions
	@Inject extension NamingExtensions
	@Inject extension TreeAppendableExtensions

	@Inject AnnotationCompiler annotationCompiler
	@Inject TypesFactory typesFactory;
	@Inject TypeReferences references;

	@Inject EcoreGenericsUtil ecoreGenericsUtil;
	@Inject EntityLinker linker;

	def htmlCode(CharSequence s) {
		"<code>".concat(String::valueOf(s)).concat("</code>")
	}

	def dispatch JvmOperation toDispose(LEntity lClass) {
		val op = typesFactory.createJvmOperation();
		op.visibility = JvmVisibility::PUBLIC
		op.returnType = references.getTypeForName(Void::TYPE, lClass)
		op.simpleName = "dispose"

		annotationCompiler.addDisposeFieldAnnotation(lClass, op)

		op.documentation = '''
		Calling dispose will destroy that instance. The internal state will be 
		set to 'disposed' and methods of that object must not be used anymore. 
		Each call will result in runtime exceptions.<br>
		If this object keeps composition containments, these will be disposed too. 
		So the whole composition containment tree will be disposed on calling this method.'''

		setBody(op, [ // ITreeAppendable
			if(it == null) return
			val p = it.trace(lClass)
			p >> '''
				if (isDisposed()) {
				  return;
				}
			'''
			val compositionContainmentProps = lClass.features.filter[it|it instanceof LEntityReference && (it as LEntityReference).cascading]
			if (!compositionContainmentProps.empty) {
				p >> "try " >>> "{"
				p >> "// Dispose all the composition references.\n"
				for (prop : compositionContainmentProps) {
					val fieldRef = "this.".concat(prop.toName.toFirstLower)
					val typeName = prop.typeName
					val typeVar = typeName.toFirstLower
					if (prop.toMany) {
						p >> '''
							if («fieldRef» != null) {
							  for («typeName» «typeVar» : «fieldRef») {
							    «typeVar».dispose();
							  }
							  «fieldRef» = null;
							}
						'''
					} else {
						p >> '''
							if («fieldRef» != null) {
							  «fieldRef».dispose();
							  «fieldRef» = null;
							}
						'''
					}
				}
				p <<< "}"
				p >>> "finally {"

			// p.increaseIndentation
			}
			if (lClass.superType != null) {
				p >> "super.dispose();"
			} else {
				p >> "disposed = true;"
			}
			if (!compositionContainmentProps.empty) {
				p <<< "}"
			}
		])

		associate(lClass, op)
	}

	def dispatch JvmOperation toDispose(LBean lClass) {
		val op = typesFactory.createJvmOperation();
		op.visibility = JvmVisibility::PUBLIC
		op.returnType = references.getTypeForName(Void::TYPE, lClass)
		op.simpleName = "dispose"

		annotationCompiler.addDisposeFieldAnnotation(lClass, op)

		op.documentation = '''
		Calling dispose will destroy that instance. The internal state will be 
		set to 'disposed' and methods of that object must not be used anymore. 
		Each call will result in runtime exceptions.<br>
		If this object keeps composition containments, these will be disposed too. 
		So the whole composition containment tree will be disposed on calling this method.'''

		setBody(op, [ // ITreeAppendable
			if(it == null) return
			val p = it.trace(lClass)
			p >> '''
				if (isDisposed()) {
				  return;
				}
			'''
			val compositionContainmentProps = lClass.features.filter[it|it instanceof LEntityReference && (it as LEntityReference).cascading]
			if (!compositionContainmentProps.empty) {
				p >> "try " >>> "{"
				p >> "// Dispose all the composition references.\n"
				for (prop : compositionContainmentProps) {
					val fieldRef = "this.".concat(prop.toName.toFirstLower)
					val typeName = prop.typeName
					val typeVar = typeName.toFirstLower
					if (prop.toMany) {
						p >> '''
							if («fieldRef» != null) {
							  for («typeName» «typeVar» : «fieldRef») {
							    «typeVar».dispose();
							  }
							  «fieldRef» = null;
							}
						'''
					} else {
						p >> '''
							if («fieldRef» != null) {
							  «fieldRef».dispose();
							  «fieldRef» = null;
							}
						'''
					}
				}
				p <<< "}"
				p >>> "finally {"

			// p.increaseIndentation
			}
			if (lClass.superType != null) {
				p >> "super.dispose();"
			} else {
				p >> "disposed = true;"
			}
			if (!compositionContainmentProps.empty) {
				p <<< "}"
			}
		])

		associate(lClass, op)
	}

	def JvmField toField(LStateClass stateClass) {
		val JvmField jvmField = typesFactory.createJvmField();
		jvmField.simpleName = stateClass.toName.toFirstLower
		jvmField.visibility = JvmVisibility::PRIVATE

		jvmField.type = cloneWithProxies(stateClass.toTypeReferenceWithMultiplicity)
		jvmField.documentation = stateClass.getDocumentation

		annotationCompiler.processAnnotation(stateClass, jvmField);
		associate(stateClass, jvmField);
	}

	override JvmField toField(LFeature prop) {
		prop.internalToField
	}

	def dispatch JvmField internalToField(LBeanFeature prop) {
		val JvmField jvmField = typesFactory.createJvmField();
		jvmField.simpleName = prop.toName
		jvmField.visibility = JvmVisibility::PRIVATE

		jvmField.type = cloneWithProxies(prop.toTypeReferenceWithMultiplicity)
		jvmField.documentation = prop.getDocumentation

		annotationCompiler.processAnnotation(prop, jvmField);
		associate(prop, jvmField);
	}

	def dispatch JvmField internalToField(LBeanReference prop) {
		val JvmField jvmField = typesFactory.createJvmField();
		jvmField.simpleName = prop.toName
		jvmField.visibility = JvmVisibility::PRIVATE

		jvmField.type = prop.toTypeReferenceWithMultiplicity
		jvmField.documentation = prop.getDocumentation

		annotationCompiler.processAnnotation(prop, jvmField);
		associate(prop, jvmField);
	}

	def dispatch JvmField internalToField(LEntityAttribute prop) {
		val LEntity entity = prop.entity
		val JvmField jvmField = typesFactory.createJvmField();
		jvmField.simpleName = prop.toName
		jvmField.visibility = JvmVisibility::PRIVATE

		jvmField.type = cloneWithProxies(prop.toTypeReferenceWithMultiplicity)
		jvmField.documentation = prop.getDocumentation

		// if uuid or historized entity AND a uuid property is present too
		if (prop.isUUID && !(entity.timedependent || entity.historized)) {
			jvmField.setInitializer [
				if(it === null) return
				val p = it.trace(prop)
				p >> '''java.util.UUID.randomUUID().toString()'''
			]
		} else if (prop.isID && (entity.timedependent || entity.historized)) {
			jvmField.setInitializer [
				if(it === null) return
				val p = it.trace(prop)
				p >> '''new UUIDHist()'''
			]
		}

		annotationCompiler.processAnnotation(prop, jvmField);
		associate(prop, jvmField);
	}

	def dispatch JvmField internalToField(LEntityReference prop) {
		val LEntity entity = prop.entity
		val JvmField jvmField = typesFactory.createJvmField();
		jvmField.simpleName = prop.toName
		jvmField.visibility = JvmVisibility::PRIVATE

		jvmField.type = prop.toTypeReferenceWithMultiplicity
		jvmField.documentation = prop.getDocumentation

		// if uuid or historized entity AND a uuid property is present too
		if (prop.isUUID || ((entity.timedependent || entity.historized) &&
			entity.uuidPresent)) {
			jvmField.setInitializer [
				if(it == null) return
				val p = it.trace(prop)
				p >> '''java.util.UUID.randomUUID().toString()'''
			]
		}

		annotationCompiler.processAnnotation(prop, jvmField);
		associate(prop, jvmField);
	}

	def boolean uuidPresent(LEntity entity) {
		entity.allAttributes.exists[it.uuid]
	}

	def JvmOperation toMethod(LOperation sourceElement, String name, JvmTypeReference returnType,
		Procedure1<? super JvmOperation> initializer) {
		val op = typesFactory.createJvmOperation()
		op.simpleName = name
		op.visibility = JvmVisibility::PUBLIC
		op.returnType = cloneWithProxies(returnType)

		annotationCompiler.processAnnotation(sourceElement, op);
		associate(sourceElement, op);

		initializeSafely(op, initializer);
	}

	def JvmOperation toSetter(LEntityFeature prop) {
		if (prop.toMany) {
			throw new RuntimeException("toMany-References not allowed for setters!");
		}
		val paramName = prop.toMethodParamName
		val typeRef = prop.toTypeReference
		val opposite = if(prop instanceof LEntityReference) (prop as LEntityReference).resolvedOpposite else null
		val op = typesFactory.createJvmOperation();
		op.visibility = JvmVisibility::PUBLIC
		op.returnType = references.getTypeForName(Void::TYPE, prop)
		op.simpleName = prop.toSetterName
		op.parameters += prop.toParameter(paramName, typeRef)
		op.documentation = "Sets the " + paramName + " property to this instance." + if (opposite != null) {
			"\nSince the reference is a container reference, the opposite reference " + "(" + prop.typeName + "." +
				opposite.name.toFirstLower + ")\n" + "of the " + paramName +
				" will be handled automatically and no further coding is required to keep them in sync.\n" +
				"See {@link " + prop.typeName + "#" + opposite.toSetterName + "(" + prop.typeName + ")}."
		} else
			""

		setBody(op, [ // ITreeAppendable
			if(it == null) return
			val p = it.trace(prop);
			p >> prop.toCheckDisposedCall()
			val fieldRef = "this." + prop.toName
			if (opposite == null) {
				p >> fieldRef + " = " + paramName + ";"
			} else {
				p >> "if (" + fieldRef + " != null) " >>> "{"
				if (opposite.toMany) {
					p >> fieldRef + "." + opposite.toCollectionInternalRemoverName + "(this);"
				} else {
					p >> fieldRef + "." + opposite.toInternalSetterName + "(null);"
				}
				p <<< "}"
//					p >> fieldRef + " = " + paramName + ";\n"
				p >> "internalSet" + prop.toName.toFirstUpper + "(" + paramName + ");\n"
				p >> "if (" + fieldRef + " != null) " >>> "{"
				if (opposite.toMany) {
					p >> fieldRef + "." + opposite.toCollectionInternalAdderName + "(this);"
				} else {
					p >> fieldRef + "." + opposite.toInternalSetterName + "(this);"
				}
				p <<< "}"
			}
		])

		return associate(prop, op);
	}

	def JvmOperation toSetter(LStateClass prop) {
		val paramName = prop.name.toFirstLower
		val typeRef = prop.toTypeReference
		val op = typesFactory.createJvmOperation();
		op.visibility = JvmVisibility::PUBLIC
		op.returnType = references.getTypeForName(Void::TYPE, prop)
		op.simpleName = prop.toSetterName
		op.parameters += prop.toParameter(paramName, typeRef)
		op.documentation = "Sets the " + paramName + " property to this instance."

		setBody(op, [ // ITreeAppendable
			if(it == null) return
			val p = it.trace(prop);
			p >> prop.toCheckDisposedCall()
			val fieldRef = "this." + prop.toName.toFirstLower
			p >> fieldRef + " = " + paramName + ";"
		])

		return associate(prop, op);
	}

	def JvmOperation toSetter(LBeanFeature prop) {
		if (prop.toMany) {
			throw new RuntimeException("toMany-References not allowed for setters!");
		}
		val paramName = prop.toMethodParamName
		val typeRef = prop.toTypeReference
		val opposite = if(prop instanceof LBeanReference) (prop as LBeanReference).resolvedOpposite else null
		val op = typesFactory.createJvmOperation();
		op.visibility = JvmVisibility::PUBLIC
		op.returnType = references.getTypeForName(Void::TYPE, prop)
		op.simpleName = prop.toSetterName
		op.parameters += prop.toParameter(paramName, typeRef)
		op.documentation = "Sets the " + paramName + " property to this instance." + if (opposite != null) {
			"\nSince the reference is a container reference, the opposite reference " + "(" + prop.typeName + "." +
				opposite.name.toFirstLower + ")\n" + "of the " + paramName +
				" will be handled automatically and no further coding is required to keep them in sync.\n" +
				"See {@link " + prop.typeName + "#" + opposite.toSetterName + "(" + prop.typeName + ")}."
		} else
			""

		setBody(op, [ // ITreeAppendable
			if(it == null) return
			val p = it.trace(prop);
			p >> prop.toCheckDisposedCall()
			val fieldRef = "this." + prop.toName
			if (opposite == null) {
				p >> fieldRef + " = " + paramName + ";"
			} else {
				p >> "if (" + fieldRef + " != null) " >>> "{"
				if (opposite.toMany) {
					p >> fieldRef + "." + opposite.toCollectionInternalRemoverName + "(this);"
				} else {
					p >> fieldRef + "." + opposite.toInternalSetterName + "(null);"
				}
				p <<< "}"
				p >> fieldRef + " = " + paramName + ";\n"
				p >> "if (" + fieldRef + " != null) " >>> "{"
				if (opposite.toMany) {
					p >> fieldRef + "." + opposite.toCollectionInternalAdderName + "(this);"
				} else {
					p >> fieldRef + "." + opposite.toInternalSetterName + "(this);"
				}
				p <<< "}"

			// if (this.«fieldName» != null) {
			// «IF ref.opposite.toMany»
			// this.«fieldName».«ref.opposite.toCollectionInternalRemoverName»(this);
			// «ELSE»
			// this.«fieldName».«ref.opposite.toInternalSetterName»(null);
			// «ENDIF»
			// }
			// this.«fieldName» = «localVarName»;
			// if (this.«fieldName» != null) {
			// «IF ref.opposite.toMany»
			// this.«fieldName».«ref.opposite.toCollectionInternalAdderName»(this);
			// «ELSE»
			// this.«fieldName».«ref.opposite.toInternalSetterName»(this);
			// «ENDIF»
			// }
			}
		])

		return associate(prop, op);
	}

	/**
	 * Builds an adder method for a *toMany relation like
	 * <code>Order.addToOrderLines(OrderLine orderLine)</code>.
	 */
	def dispatch JvmOperation toAdder(LEntityFeature prop, String propertyName) {
		val paramName = prop.typeName.toFirstLower
		val JvmOperation op = typesFactory.createJvmOperation();
		op.visibility = JvmVisibility::PUBLIC
		op.returnType = references.getTypeForName(Void::TYPE, prop)
		op.simpleName = prop.toCollectionAdderName
		if (prop.toTypeReference != null) {
			op.parameters += prop.toParameter(paramName, prop.toTypeReference)
		}

		op.documentation = '''
		Adds the given «paramName» to this object. <p>
		«IF prop.opposite != null»
			Since the reference is a composition reference, the opposite reference («prop.typeName».«prop.opposite.name.
			toFirstLower»)
			of the «paramName» will be handled automatically and no further coding is required to keep them in sync. 
			See {@link «prop.typeName»#«prop.opposite.toSetterName»(«prop.typeName»)}.
		«ELSE»
			ATTENTION:<br>
			The reference is a composition reference, but no opposite is available.
			So the opposite will NOT be handled. Therefore you have to ensure that the parent of the reference
			is set properly.
		«ENDIF»'''

		setBody(op, [ // ITreeAppendable
			if(it == null) return
			val p = it.trace(prop);
			p += prop.toCheckDisposedCall()
			if (prop.opposite != null) {
				p >> paramName + "." + prop.opposite.toSetterName + "(this);"
			} else {
				p >> "if (!" + prop.toCollectionInternalGetterName + "().contains(" + paramName + "))" >>> "{"
				{
					p >> prop.toCollectionInternalAdderName + "(" + paramName + ");"
				}
				p <<< "}"
			}
		])
		return associate(prop, op);
	}

	/**
	 * Builds an adder method for a *toMany relation like
	 * <code>Order.addToOrderLines(OrderLine orderLine)</code>.
	 */
	def dispatch JvmOperation toAdder(LBeanFeature prop, String propertyName) {
		val paramName = prop.typeName.toFirstLower
		val JvmOperation op = typesFactory.createJvmOperation();
		op.visibility = JvmVisibility::PUBLIC
		op.returnType = references.getTypeForName(Void::TYPE, prop)
		op.simpleName = prop.toCollectionAdderName
		if (prop.toTypeReference != null) {
			op.parameters += prop.toParameter(paramName, prop.toTypeReference)
		}

		op.documentation = '''
		Adds the given «paramName» to this object. <p>
		«IF prop.opposite != null»
			Since the reference is a composition reference, the opposite reference («prop.typeName».«prop.opposite.name.
			toFirstLower»)
			of the «paramName» will be handled automatically and no further coding is required to keep them in sync. 
			See {@link «prop.typeName»#«prop.opposite.toSetterName»(«prop.typeName»)}.
		«ELSEIF !(prop.type instanceof LBean)»
			ATTENTION:<br>
			The reference is a composition reference, but no opposite is available.
			So the opposite will NOT be handled. Therefore you have to ensure that the parent of the reference
			is set properly.
		«ENDIF»'''

		setBody(op, [ // ITreeAppendable
			if(it == null) return
			val p = it.trace(prop);
			p += prop.toCheckDisposedCall()
			if (prop.opposite != null) {
				p >> paramName + "." + prop.opposite.toSetterName + "(this);"
			} else {
				p >> "if (!" + prop.toGetterName + "().contains(" + paramName + "))" >>> "{"
				{
					p >> prop.toCollectionInternalAdderName + "(" + paramName + ");"
				}
				p <<< "}"
			}
		])
		return associate(prop, op);
	}

	/**
	 * Builds a setter method for a *toMany relation like
	 * <code>Order.setOrderLines(List&lt;OrderLine&gt; orderLines)</code>.
	 */
	def JvmOperation toCollectionSetter(LFeature prop, String propertyName) {
		val paramName = prop.typeName.toFirstLower
		val JvmOperation op = typesFactory.createJvmOperation();
		op.visibility = JvmVisibility::PUBLIC
		op.returnType = references.getTypeForName(Void::TYPE, prop)
		op.simpleName = prop.toSetterName
		if (prop.toTypeReference != null) {
			op.parameters += prop.toParameter(propertyName, prop.toTypeReferenceWithMultiplicity)
		}
		op.documentation = '''
		Sets the given «propertyName» to the object. Currently contained «propertyName» instances will be removed.
		
		@param «propertyName» the list of new instances'''
		op.body = '''
			// remove the old «paramName»
			for(«prop.typeName» oldElement : new ArrayList<«prop.typeName»>(this.«prop.toCollectionInternalGetterName»())){
			  «prop.toCollectionRemoverName»(oldElement);
			}
			
			// add the new «paramName»
			for(«prop.typeName» newElement : «propertyName»){
			  «prop.toCollectionAdderName»(newElement);
			}
		'''
		return associate(prop, op);
	}

//	/**
//	 * A getter to return the historized compound key.
//	 */
//	def JvmOperation toGetHistCompoundKey(LType type, String idProp, String validFromProp) {
//		val JvmOperation op = typesFactory.createJvmOperation();
//		op.visibility = JvmVisibility::PUBLIC
//		op.returnType = references.getTypeForName(typeof(UUIDHist), type)
//		op.simpleName = "getHistCompoundKey"
//
//		op.documentation = '''
//		Returns the compound id for historized objects'''
//		op.body = '''
//			return new HistCompoundId(«idProp», «validFromProp»);
//		'''
//		return associate(type, op);
//	}

	/**
	 * Builds a setter method for a *toMany relation like
	 * <code>Order.setOrderLines(List&lt;OrderLine&gt; orderLines)</code>.
	 */
	def JvmOperation toPreRemove(LEntity entity) {
		val JvmOperation op = typesFactory.createJvmOperation();
		op.visibility = JvmVisibility::PROTECTED
		op.returnType = references.getTypeForName(Void::TYPE, entity)
		op.simpleName = "preRemove"
		op.documentation = '''Iterates all cross references and removes them from the parent to avoid ConstraintViolationException'''
		op.annotations += entity.toAnnotation(typeof(PreRemove))

		op.body = '''
			«FOR ref : entity.references»
				«IF !ref.cascading && ref.opposite != null && ref.bounds.toMany»
					// remove the «ref.name»
					for(«ref.typeName» oldElement : new ArrayList<«ref.typeName»>(this.«ref.toCollectionInternalGetterName»())){
					  «ref.toCollectionRemoverName»(oldElement);
					}
				«ENDIF»
			«ENDFOR»
		'''
		return associate(entity, op);
	}

	def JvmVisibility getInternalMethodVisibility(LFeature ref) {
		val LPackage ownerPackage = (ref.eContainer() as LType).package;
		val LPackage refPackage = ref.type.package;
		if (ownerPackage.equals(refPackage)) {
			null // package visibility
		} else {
			JvmVisibility::PUBLIC
		}
	}

	override JvmOperation toIsDisposed(LClass lClass) {
		val op = super.toIsDisposed(lClass)
		annotationCompiler.addDisposeFieldAnnotation(lClass, op)
		return op
	}

	def JvmField toDiposeField(LType sourceElement) {
		val JvmField field = sourceElement.toPrimitiveTypeField("disposed", Boolean::TYPE)
		associate(sourceElement, field)
		annotationCompiler.addDisposeFieldAnnotation(sourceElement, field)
		return field
	}

	def JvmOperation toInternalSetter(LFeature prop) {
		val paramName = prop.toMethodParamName
		val typeRef = prop.toTypeReference
		val JvmOperation result = typesFactory.createJvmOperation();
		result.visibility = JvmVisibility::PUBLIC
		result.returnType = references.getTypeForName(Void::TYPE, prop)
		result.simpleName = prop.toInternalSetterName
		result.parameters += prop.toParameter(paramName, typeRef)

		result.documentation = '''For internal use only!'''

		setBody(result, [ // ITreeAppendable
			if(it == null) return
			val p = it.trace(prop)
			p >> "this." + prop.toName + " = " + paramName + ";"
		])
		return associate(prop, result);
	}

	def JvmOperation toInternalAdder(LFeature prop) {
		val paramName = prop.typeName.toFirstLower
		val typeRef = prop.toTypeReference
		val JvmOperation op = typesFactory.createJvmOperation();
		op.visibility = JvmVisibility::PUBLIC
		op.returnType = references.getTypeForName(Void::TYPE, prop)
		op.simpleName = prop.toCollectionInternalAdderName

		val param = prop.toParameter(paramName, typeRef);
		if (param != null) {
			op.parameters += param
		}

		op.documentation = '''For internal use only!'''

		op.body = '''
		if(«paramName» == null) {
			return;
		}
		
		«««		if(!«prop.toCollectionInternalGetterName»().contains(«paramName»)) {
		«prop.toCollectionInternalGetterName»().add(«paramName»);
		«««		}
		'''
		return associate(prop, op);
	}

	def JvmOperation toInternalRemover(LFeature prop) {
		val paramName = prop.typeName.toFirstLower
		val typeRef = prop.toTypeReference
		val op = typesFactory.createJvmOperation();
		op.visibility = JvmVisibility::PUBLIC
		op.returnType = references.getTypeForName(Void::TYPE, prop)
		op.simpleName = prop.toCollectionInternalRemoverName

		val param = prop.toParameter(paramName, typeRef);
		if (param != null) {
			op.parameters += param
		}

		op.documentation = '''For internal use only!'''

		setBody(op, [ // ITreeAppendable
			if(it == null) return
			val p = it.trace(prop)
			p >> prop.toCollectionInternalGetterName + "()" + ".remove(" + paramName + ");"
		])
		return associate(prop, op)
	}

	def JvmOperation toInternalCollectionGetter(LFeature prop, String name) {
		val fieldName = name.toFirstLower
		val JvmOperation op = typesFactory.createJvmOperation()
		op.visibility = JvmVisibility::PUBLIC
		op.returnType = prop.toTypeReferenceWithMultiplicity
		op.simpleName = prop.toCollectionInternalGetterName
		op.documentation = "For internal use only! Returns the list of " + htmlCode(prop.typeName) +
			"s thereby lazy initializing it."
		setBody(op, [ // ITreeAppendable
			if(it == null) return;
			var p = it.trace(prop);
			val fieldRef = "this." + fieldName
			p >> "if (" + fieldRef + " == null)" >>> " {"
			{
				p >> fieldRef >> " = new " >> newTypeRef(prop, typeof(ArrayList), prop.toTypeReference) >> "();"
			}
			p <<< "}"
			p >> "return " + fieldRef + ";"
		])
		prop.associate(op)
	}

	/**
	 * Builds a remover method for a *toMany relation like
	 * <code>Order.removeFromOrderLines(OrderLine orderLine)</code>.
	 */
	def JvmOperation toRemover(LFeature prop, String propertyName) {
		val paramName = prop.typeName.toFirstLower
		val JvmOperation op = typesFactory.createJvmOperation();
		op.visibility = JvmVisibility::PUBLIC
		op.returnType = references.getTypeForName(Void::TYPE, prop)
		op.simpleName = prop.toCollectionRemoverName
		if (prop.toTypeReference != null) {
			op.parameters += prop.toParameter(paramName, prop.toTypeReference)
		}
		if (prop.opposite != null) {
			op.documentation = '''
			Removes the given «paramName» from this object. <p>
			«IF prop instanceof LEntityReference && (prop as LEntityReference).cascading»
				Since the reference is a cascading reference, the opposite reference («prop.typeName».«prop.opposite.name.
				toFirstLower»)
				of the «paramName» will be handled automatically and no further coding is required to keep them in sync. 
				See {@link «prop.typeName»#«prop.opposite.toSetterName»(«prop.typeName»)}.
			«ENDIF»'''
		}
		setBody(op, [ // ITreeAppendable
			if(it == null) return
			val p = it.trace(prop);
			p += prop.toCheckDisposedCall()
			if (prop.opposite != null) {
				p >> paramName + "." + prop.opposite.toSetterName + "(null);"
			} else {
				p >> prop.toCollectionInternalGetterName + "().remove(" + paramName + ");"
			}
		])
		return associate(prop, op);
	}

//	def EObject createOSBPJvmProxy(EObject obj, EReference eRef, EReference eJvmRef,
//		SemanticLoadingResource resource) {
//		if (resource == null)
//			throw new IllegalStateException("object must be contained in a resource");
//		val InternalEObject target = (obj as InternalEObject).eGet(eRef, false, false) as InternalEObject;
//		val URI jvmTypeURI = resource.getJvmTypeURI(target.eProxyURI)
//		val JvmParameterizedTypeReference typeRef = TypesFactory.eINSTANCE.createJvmParameterizedTypeReference();
//		val JvmType proxy = TypesFactory.eINSTANCE.createJvmGenericType();
//		typeRef.setType(proxy);
//		(proxy as InternalEObject).eSetProxyURI(jvmTypeURI);
//		return typeRef;
//	}
}
