/**
 * 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 v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * 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

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[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[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)
	}

	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(LEntityFeature 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 property name == oid AND a uuid property is present too
		if (prop.isUUID || ((entity.timedependent || entity.historized) && prop.toName.equals(Constants::PROP__OID) &&
			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 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 property name == oid AND a uuid property is present too
		if (prop.isUUID || ((entity.timedependent || entity.historized) && prop.toName.equals(Constants::PROP__OID) &&
			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(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);
	}

	/**
     * 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.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;
//	}
}
