/*******************************************************************************
 * Copyright (c) 2006, 2008 Eclipse.org
 * 
 * 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
 *******************************************************************************/
package org.eclipse.gmf.internal.xpand;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import org.eclipse.emf.common.util.Enumerator;
import org.eclipse.emf.ecore.EAnnotation;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EDataType;
import org.eclipse.emf.ecore.EEnum;
import org.eclipse.emf.ecore.EEnumLiteral;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EOperation;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EParameter;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.ETypedElement;
import org.eclipse.emf.ecore.EcoreFactory;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.gmf.internal.xpand.expression.PolymorphicResolver;
import org.eclipse.gmf.internal.xpand.migration.Activator;
import org.eclipse.gmf.internal.xpand.model.XpandDefinitionWrap;
import org.eclipse.gmf.internal.xpand.model.XpandIterator;

/**
 * XXX Guess, will need special support to recognize the fact
 * EJavaObject.isSupertypeOf(EObject)
 * 
 * @author artem
 */
@SuppressWarnings("unchecked")
public class BuiltinMetaModel {
    public final static String SET = "Set";
    public final static String LIST = "List";

	
	protected static EPackage XECORE = EcoreFactory.eINSTANCE.createEPackage();
	
	static {
		XECORE.setName("xecore");
		XECORE.setNsPrefix("xecore");
		XECORE.setNsURI("uri:org.eclipse.modeling/m2t/xpand/xecore/1.0");
	}

	private static EClass PARAMETERIZED_TYPE = EcoreFactory.eINSTANCE.createEClass();
	private static EReference PT_INNER_TYPE_REF = EcoreFactory.eINSTANCE.createEReference();
	private static EAttribute PT_INNER_TYPE_ATTR = EcoreFactory.eINSTANCE.createEAttribute();

	static {
		PARAMETERIZED_TYPE.setName("ParameterizedType");
		PARAMETERIZED_TYPE.getESuperTypes().add(EcorePackage.eINSTANCE.getEClass());
		PARAMETERIZED_TYPE.setAbstract(true);
		PT_INNER_TYPE_REF.setName("innerType");
		PT_INNER_TYPE_REF.setContainment(false);
		PT_INNER_TYPE_REF.setEType(EcorePackage.eINSTANCE.getEClass());

		PARAMETERIZED_TYPE.getEStructuralFeatures().add(PT_INNER_TYPE_REF);

		PT_INNER_TYPE_ATTR.setName("innerDataType");
		PT_INNER_TYPE_ATTR.setEType(EcorePackage.eINSTANCE.getEDataType());
		PARAMETERIZED_TYPE.getEStructuralFeatures().add(PT_INNER_TYPE_ATTR);
		XECORE.getEClassifiers().add(PARAMETERIZED_TYPE);
	}

	/**
	 * Checks whether classifier is one of user's model extension classes
	 * (conforming to ParameterizedType from our extended ECore meta-model).
	 * EClassifier instances available in analyze() methods are param
	 * candidates.
	 * 
	 * @param parameterizedTypeM1 -
	 *            e.g. EClass "Order", or XEClass "OrderList"
	 */
	public static boolean isParameterizedType(EClassifier parameterizedTypeM1) {
		return PARAMETERIZED_TYPE.isSuperTypeOf(parameterizedTypeM1.eClass());
	}

	// XXX revisit invocations, this check is doubled with isParameterizedType, perhaps, can refactor it 
	public static boolean isCollectionType(EClassifier parameterizedTypeM1) {
		// XXX this implementation is not really 'isCollectionType', it's just a copy of what was in the original code
		return isAssignableFrom(CollectionTypesSupport.COLLECTION_OF_OBJECT, parameterizedTypeM1);
	}

	public static EClassifier getInnerType(EClassifier parameterizedTypeM1) {
		assert isParameterizedType(parameterizedTypeM1);
		if (parameterizedTypeM1.eIsSet(PT_INNER_TYPE_REF)) {
			return (EClass) parameterizedTypeM1.eGet(PT_INNER_TYPE_REF);
		} else {
			return (EDataType) parameterizedTypeM1.eGet(PT_INNER_TYPE_ATTR);
		}
	}

	/**
	 * NOTE, parameterizedTypeM1 is M1 instance, you can't pass {@link BuiltinMetaModel#COLLECTION_TYPE} (or {@link BuiltinMetaModel#LIST_TYPE}) here,
	 * because COLLECTION_TYPE just extends PARAMETERIZED_TYPE, but still instance of EClass. We could, however, have COLLECTION_TYPE to be an
	 * instance of PARAMETERIZED_TYPE, and then we could use this method. The reasons not to do so (at least, now) are
	 * (a) didn't think it over yet (b) looks like extending M2 (sic!) dynamically, though I don't like even M1 polluting with type
	 * that happens.
	 * @param parameterizedTypeM1
	 * @param innerTypeM1
	 * @return
	 */
	public static EClass cloneParametrizedType(EClassifier parameterizedTypeM1, EClassifier innerTypeM1) {
		assert isParameterizedType(parameterizedTypeM1);
		return collectionTypes.getCollectionType(parameterizedTypeM1.eClass(), innerTypeM1);
	}

	/*package*/ static EClass internalNewParameterizedType(EClass parameterizedTypeM2, EClassifier inner) {
		assert PARAMETERIZED_TYPE.isSuperTypeOf(parameterizedTypeM2);
		EObject anInstance = XECORE.getEFactoryInstance().create(parameterizedTypeM2);
		assert anInstance instanceof EClass : "EClass is first supertype with instanceClass set";
		// e.g. "OrderCollection" or "IntegerList"
		((EClass) anInstance).setName(inner.getName() + parameterizedTypeM2.getName());
		anInstance.eSet(inner instanceof EClass ? PT_INNER_TYPE_REF : PT_INNER_TYPE_ATTR, inner);
		return (EClass) anInstance;
	}

	public static final EClass VOID = EcoreFactory.eINSTANCE.createEClass();

	static {
		VOID.setName("void");
		XECORE.getEClassifiers().add(VOID);
	}

	protected static CollectionTypesSupport collectionTypes = new CollectionTypesSupport();

	static {
		collectionTypes.init(XECORE, PARAMETERIZED_TYPE);
	}
	/**
	 * @param name
	 * @return true if name is one of M2 collection meta-types (either Collection, List, Set)
	 */
	public static boolean isCollectionMetaType(String name) {
		return collectionTypes.isCollectionMetaType(name);
	}

	public static EClass getCollectionType(String metaTypeName, EClassifier innerType) {
		return collectionTypes.getCollectionType(metaTypeName, innerType);
	}

	// XXX actually, it's odd to use abstract and vague 'collection' 
	public static EClass getCollectionType(EClassifier innerType) {
		return collectionTypes.getCollectionType(innerType);
	}
	public static EClass getListType(EClassifier innerType) {
		return collectionTypes.getListType(innerType);
	}
	public static EClass getSetType(EClassifier innerType) {
		return collectionTypes.getSetType(innerType);
	}

	public static final EClass DEFINITION_TYPE = EcoreFactory.eINSTANCE.createEClass();

	static {
		DEFINITION_TYPE.setName("xpand2::Definition");
		DEFINITION_TYPE.getESuperTypes().add(EcorePackage.eINSTANCE.getEClass());
		XECORE.getEClassifiers().add(DEFINITION_TYPE);
	}

	public static final EClass ITERATOR_TYPE = EcoreFactory.eINSTANCE.createEClass();

	static {
		ITERATOR_TYPE.setName("xpand2::Iterator");
		ITERATOR_TYPE.getESuperTypes().add(EcorePackage.eINSTANCE.getEClass());
		XECORE.getEClassifiers().add(ITERATOR_TYPE);
	}

	/**
	 * ECore doesn't support 'return types' for Enums, to my best knowledge,
	 * they are all integers. original EEnumType returns itself as static
	 * property's return type BTW, what if we'd like to get string value, name,
	 * instead
	 */
	public static EClassifier getReturnType(EEnumLiteral sp) {
		return sp.getEEnum();
	}

	// TODO obj.getClass lookup tree?
	public static EClassifier getType(Object obj) {
		if (obj == null) {
			return VOID;
		}
		if (obj instanceof Enumerator) {
			// unlike original impl, we don't return Enum as type
			// mostly because it's just too hard to look for actual enum
			// XXX perhaps, EEnumLiteral.getEEnum could help?
			return EcorePackage.eINSTANCE.getEEnumerator();
		}
		if (obj instanceof EObject) {
			return ((EObject) obj).eClass();
		}
		if (obj instanceof Collection) {
			EClassifier type = null;
			if (!((Collection) obj).isEmpty()) {
				// FIXME respect all! elements in the collection, not only the first one
				type = getType(((Collection) obj).iterator().next());
			}
			if (obj instanceof Set) {
				return collectionTypes.getSetType(type);
			}
			if (obj instanceof List) {
				return collectionTypes.getListType(type);
			}
			return collectionTypes.getCollectionType(type);
		}
		if (obj instanceof Boolean) {
			return EcorePackage.eINSTANCE.getEBoolean();
		}
		if ((obj instanceof Byte) || (obj instanceof Integer) || (obj instanceof Long) || obj instanceof Short) {
			return EcorePackage.eINSTANCE.getEInt();
		}
		if ((obj instanceof Float) || (obj instanceof Double)) {
			return EcorePackage.eINSTANCE.getEDouble();
		}
		if (obj instanceof String) {
			return EcorePackage.eINSTANCE.getEString();
		}
		if (obj instanceof XpandDefinitionWrap) {
			return DEFINITION_TYPE;
		}
		if (obj instanceof XpandIterator) {
			return ITERATOR_TYPE;
		}
		return EcorePackage.eINSTANCE.getEJavaObject();
	}

	/**
	 * FIXME HACK!!!
	 */
	public static Object newInstance(EClassifier t) {
		if (isCollectionType(t)) {
			return collectionTypes.newInstance(t);
		}
		if (t.getInstanceClass() != null) {
			try {
				return t.getInstanceClass().newInstance();
			} catch (Exception ex) {
				ex.printStackTrace();
			}
		}
		return null;
	}

	/**
	 * FIXME what if args has null or getType() returns null - we can't find an
	 * op then, and it's caller who knows how to handle this.
	 * 
	 * @param name
	 * @param args
	 * @param instance
	 * @return
	 */
	public static Operation executableOperation(String name, Object[] args, Object instance) {
		EClassifier[] argTypes = new EClassifier[args.length];
		for (int i = 0; i < args.length; i++) {
			argTypes[i] = getType(args[i]);
		}
		EOperation metaOp = findOperation(getType(instance), name, argTypes);
		if (metaOp == null) {
			return null;
		}
		if (InternalOperation.isInternalOp(metaOp)) {
			for (List<InternalOperation> ops : internalOperationsMap.values()) {
				for (InternalOperation internalOp : ops) {
					if (internalOp.metaOp == metaOp) {
						return new OperationEx(instance, args, internalOp);
					}
				}
			}
			throw new IllegalStateException("Can't find implementation of built-in operation" + metaOp);
		}
		return new Operation(instance, args, metaOp);
	}

	public static EOperation findOperation(EClassifier targetType, String name, EClassifier[] args) {
		List<EOperation> allOp;
		if (hasBuiltinSupport(targetType)) {
			// this one is to cover m2 types that are *propagated* to user's model, m1. Those like
			// boolean, integer, string, etc.
			allOp = findInternalOp(targetType);
		} else if (hasBuiltinSupport(targetType.eClass())){
			// this one is to cover collection types, because we register their operations
			// against meta-model (m2) instance, rather than against M1 
			allOp = findInternalOp(targetType.eClass());
		} else {
			if (false == (targetType instanceof EClass)) {
				return null;
			} else {
				allOp = new LinkedList<EOperation>(((EClass) targetType).getEAllOperations());
				allOp.addAll(findInternalOp(EcorePackage.eINSTANCE.getEJavaObject()));
			}
		}
		return PolymorphicResolver.filterOperation(allOp, name, targetType, Arrays.asList(args));
	}

	private static Map<String, String> attrNameSubsts = new TreeMap<String, String>();
	public static EOperation Collection_IsEmpty;
	public static EOperation Collection_Add;
	public static EOperation Collection_AddAll;
	public static EOperation Collection_Clear;
	public static EOperation Collection_Flatten;
	public static EOperation Collection_Size;
	public static EOperation Collection_Union;
	public static EOperation Collection_Intersect;
	public static EOperation Collection_Without;
	public static EOperation Collection_ToSet;
	public static EOperation Collection_ToList;
	public static EOperation Collection_Contains;
	public static EOperation Collection_ContainsAll;
	public static EOperation List_Get;
	public static EOperation List_First;
	public static EOperation List_Last;
	public static EOperation List_WithoutFirst;
	public static EOperation List_WithoutLast;
	public static EOperation List_PurgeDups;
	public static EOperation List_IndexOf;
	public static EOperation Boolean_NE;
	public static EOperation Int_Plus_Int;
	public static EOperation Int_Plus_Double;
	public static EOperation Int_Minus_Int;
	public static EOperation Int_Minus_Double;
	public static EOperation Int_Mult_Int;
	public static EOperation Int_Mult_Double;
	public static EOperation Int_Div_Int;
	public static EOperation Int_Div_Double;
	public static EOperation Int_Unary_Minus;
	public static EOperation Int_GreatOrEqual;
	public static EOperation Int_LessOrEqual;
	public static EOperation Int_Less;
	public static EOperation Int_Greater;
	public static EOperation Int_UpTo;
	public static EOperation Double_Plus_Double;
	public static EOperation Double_Plus_Int;
	public static EOperation Double_Minus_Double;
	public static EOperation Double_Minus_Int;
	public static EOperation Double_Mult_Double;
	public static EOperation Double_Mult_Int;
	public static EOperation Double_Div_Double;
	public static EOperation Double_Div_Int;
	public static EOperation Double_Unary_Minus;
	public static EOperation Object_EQ;
	public static EOperation EString_ToFirstUpper;
	public static EOperation EString_Plus_EJavaObject;
	public static EOperation EString_ToFirstLower;
	public static EOperation EString_ToCharList;
	public static EOperation EString_StartsWith;
	public static EOperation EString_EndsWith;
	public static EOperation EString_SubString_StartEnd;
	public static EOperation EString_SubString;
	public static EOperation EString_ToUpperCase;
	public static EOperation EString_ToLowerCase;
	public static EOperation EString_ReplaceAll;
	public static EOperation EString_ReplaceFirst;
	public static EOperation EString_Split;
	public static EOperation EString_Matches;
	public static EOperation EString_Trim;
	public static EOperation EString_Length;
	public static EOperation Object_CompareTo;
	public static EOperation Object_ToString;
	public static EOperation Object_NotEQ;
	static {
		attrNameSubsts.put("default_", "default");
	}
	public static EStructuralFeature getAttribute(EClassifier type, String name) {
		if (hasBuiltinSupport(type)) {
			return findInternalAttr(type, name);
		}
		if (type instanceof EClass) {
			return ((EClass) type).getEStructuralFeature(attrNameSubsts.containsKey(name) ? attrNameSubsts.get(name): name);
		}
		if (type instanceof EEnum || type == EcorePackage.eINSTANCE.getEEnumLiteral() || type == EcorePackage.eINSTANCE.getEEnumerator()) {
			return EcorePackage.eINSTANCE.getEEnumLiteral().getEStructuralFeature(name);
		}
		return null;
	}
	public static Object getValue(EStructuralFeature prop, Object instance) {
		if (instance instanceof Enumerator) {
			if (prop == EcorePackage.eINSTANCE.getEEnumLiteral_Literal()) {
				return ((Enumerator) instance).getLiteral();
			}
			if (prop == EcorePackage.eINSTANCE.getENamedElement_Name()) {
				return ((Enumerator) instance).getName();
			}
			if (prop == EcorePackage.eINSTANCE.getEEnumLiteral_Value()) {
				return ((Enumerator) instance).getValue();
			}
		}
		if (instance instanceof EObject) {
			return ((EObject) instance).eGet(prop);
		}
		// handle collection/set/list properties?
		return "HeyHo!";
	}

	private static boolean hasBuiltinSupport(EClassifier type) {
		return internalOperationsMap.containsKey(type);
	}

	private static EStructuralFeature findInternalAttr(EClassifier type, String name) {
		if (type instanceof EClass) {
			return ((EClass) type).getEStructuralFeature(name);
		}
		if (type instanceof EDataType && type == EcorePackage.eINSTANCE.getEEnumerator()) {
			// I do not know where EMF uses EEnumLiteralImpl and where Enumerator for EEnum value. 
			return EcorePackage.eINSTANCE.getEEnumLiteral().getEStructuralFeature(name);
		}
		// TODO Auto-generated method stub
		return null;
	}

	private static final Map<EClassifier,List<InternalOperation>>  internalOperationsMap = new HashMap<EClassifier, List<InternalOperation>>();

	static {
		final EcorePackage ecorePkg = EcorePackage.eINSTANCE;
		final OperationFactory opf = new OperationFactory();

		final List<InternalOperation> objectOps = new LinkedList<InternalOperation>();
		objectOps.add(new InternalOperation<Object>(Object_CompareTo = opf.create("compareTo", ecorePkg.getEBoolean(), ecorePkg.getEJavaObject())) {
			@Override
			public Object evaluate(Object target, Object[] params) {
				if (target == null) {
					return params[0] == null ? 0 : -1;
				}
				if (params[0] == null) {
					return 1;
				}
				if (target instanceof Comparable) {
					return ((Comparable) target).compareTo(params[0]);
				}
				// note, unlike ObjectTypeImpl we don't invoke toString registered against metatype here
				return String.valueOf(target).compareTo(String.valueOf(params[0]));
			}
		});
		objectOps.add(new InternalOperation<Object>(Object_ToString = opf.create("toString", ecorePkg.getEString())) {
			@Override
			public Object evaluate(Object target, Object[] params) {
				return String.valueOf(target);
			}
		});
		objectOps.add(new InternalOperation<Object>(Object_EQ = opf.create("==", boolean.class, Object.class)) {
			@Override
			public Object evaluate(Object target, Object[] params) {
				return target == null ? params[0] == null : target.equals(params[0]);
			}
		});
		objectOps.add(new InternalOperation<Object>(Object_NotEQ = opf.create("!=", boolean.class, Object.class)) {
			@Override
			public Object evaluate(Object target, Object[] params) {
				return target == null ? params[0] != null : !target.equals(params[0]);
			}
		});
		List<InternalOperation> unmodifiableObjectOps = Collections.unmodifiableList(objectOps);
		internalOperationsMap.put(ecorePkg.getEJavaObject(), unmodifiableObjectOps);
		// EEnumerator are enum literal instances at runtime (#evaluate),
		// while EEnum are their types during #analyze phase
		internalOperationsMap.put(ecorePkg.getEEnumerator(), unmodifiableObjectOps);
		internalOperationsMap.put(ecorePkg.getEEnum(), unmodifiableObjectOps);

		final List<InternalOperation> stringOps = new LinkedList<InternalOperation>();

		stringOps.add(new InternalOperation<String>(EString_Plus_EJavaObject = opf.create("+",ecorePkg.getEString(),ecorePkg.getEJavaObject())) {
			@Override
			public Object evaluate(String target, Object[] params) {
				return target + String.valueOf(params[0]);
			}
		});
		stringOps.add(new InternalOperation<String>(EString_ToFirstUpper = opf.create("toFirstUpper",ecorePkg.getEString())) {
			@Override
			public Object evaluate(String target, Object[] params) {
				return StringHelper.firstUpper(target);
			}
		});
		stringOps.add(new InternalOperation<String>(EString_ToFirstLower = opf.create("toFirstLower",ecorePkg.getEString())) {
			@Override
			public Object evaluate(String target, Object[] params) {
				return StringHelper.firstLower(target);
			}
		});
		stringOps.add(new InternalOperation<String>(EString_ToCharList = opf.create("toCharList",collectionTypes.getListType(ecorePkg.getEString()))) {
			@Override
			public Object evaluate(String target, Object[] params) {
				ArrayList<String> rv = new ArrayList<String>(target.length());
				for (int i = 0; i < target.length(); i++) {
					rv.add(target.substring(i, i+1));
				}
				return rv;
			}
		});
		InternalOperation internalOp;
		stringOps.add(internalOp = opf.createReflective(String.class, "startsWith", String.class));
		EString_StartsWith = internalOp.metaOp;
		stringOps.add(internalOp = opf.createReflective(String.class, "endsWith", String.class));
		EString_EndsWith = internalOp.metaOp;
		InternalOperation subStringOp = opf.createReflective(String.class, "substring", int.class, int.class);
		subStringOp.metaOp.setName("subString");
		EString_SubString_StartEnd = subStringOp.metaOp;
		stringOps.add(subStringOp);
		subStringOp = opf.createReflective(String.class, "substring", int.class);
		subStringOp.metaOp.setName("subString");
		EString_SubString = subStringOp.metaOp;
		stringOps.add(subStringOp);
		stringOps.add(internalOp = opf.createReflective(String.class, "toUpperCase"));
		EString_ToUpperCase = internalOp.metaOp;
		stringOps.add(internalOp = opf.createReflective(String.class, "toLowerCase"));
		EString_ToLowerCase = internalOp.metaOp;
		stringOps.add(internalOp = opf.createReflective(String.class, "replaceAll", String.class, String.class));
		EString_ReplaceAll = internalOp.metaOp;
		stringOps.add(internalOp = opf.createReflective(String.class, "replaceFirst", String.class, String.class));
		EString_ReplaceFirst = internalOp.metaOp;
		stringOps.add(internalOp = opf.createReflective(String.class, "split", String.class));
		EString_Split = internalOp.metaOp;
		stringOps.add(internalOp = opf.createReflective(String.class, "matches", String.class));
		EString_Matches = internalOp.metaOp;
		stringOps.add(internalOp = opf.createReflective(String.class, "trim"));
		EString_Trim = internalOp.metaOp;
		stringOps.add(internalOp = opf.createReflective(String.class, "length"));
		EString_Length = internalOp.metaOp;
		stringOps.addAll(unmodifiableObjectOps);
		internalOperationsMap.put(ecorePkg.getEString(), Collections.unmodifiableList(stringOps));

		final List<InternalOperation> booleanOps = new LinkedList<InternalOperation>();
		booleanOps.add(new InternalOperation<Boolean>(Boolean_NE = opf.create("!", boolean.class)) {
			@Override
			public Object evaluate(Boolean target, Object[] params) {
				return Boolean.valueOf(!target.booleanValue());
			}
		});
		booleanOps.addAll(unmodifiableObjectOps);
		internalOperationsMap.put(ecorePkg.getEBoolean(), Collections.unmodifiableList(booleanOps));
		final List<InternalOperation> voidOps = new LinkedList<InternalOperation>();
		voidOps.addAll(unmodifiableObjectOps);
		internalOperationsMap.put(VOID, Collections.unmodifiableList(voidOps));

		//---------------------------------------------------------------------------------
		class InternalSumOp extends InternalOperation<Number> {
			InternalSumOp(EOperation metaOp) {
				super(metaOp);
			}
			@Override
			public Object evaluate(Number target, Object[] params) {
				if (target instanceof Double || params[0] instanceof Double) {
					return new Double(target.doubleValue() + ((Number) params[0]).doubleValue());
				} else {
					return new Integer(target.intValue() + ((Number) params[0]).intValue());
				}
			}
			
		}; 
		class InternalSubOp extends InternalOperation<Number> {
			InternalSubOp(EOperation metaOp) {
				super(metaOp);
			}
			@Override
			public Object evaluate(Number target, Object[] params) {
				if (target instanceof Double || params[0] instanceof Double) {
					return new Double(target.doubleValue() - ((Number) params[0]).doubleValue());
				} else {
					return new Integer(target.intValue() - ((Number) params[0]).intValue());
				}
			}
			
		}; 
		class InternalMulOp extends InternalOperation<Number> {
			InternalMulOp(EOperation metaOp) {
				super(metaOp);
			}
			@Override
			public Object evaluate(Number target, Object[] params) {
				if (target instanceof Double || params[0] instanceof Double) {
					return new Double(target.doubleValue() * ((Number) params[0]).doubleValue());
				} else {
					return new Integer(target.intValue() * ((Number) params[0]).intValue());
				}
			}
			
		}; 
		class InternalDivOp extends InternalOperation<Number> {
			InternalDivOp(EOperation metaOp) {
				super(metaOp);
			}
			@Override
			public Object evaluate(Number target, Object[] params) {
				if (target instanceof Double || params[0] instanceof Double) {
					return new Double(target.doubleValue() / ((Number) params[0]).doubleValue());
				} else {
					return new Integer(target.intValue() / ((Number) params[0]).intValue());
				}
			}
			
		};
		class InternalNegateOp extends InternalOperation<Number> {
			InternalNegateOp(EOperation metaOp) {
				super(metaOp);
			}
			@Override
			public Object evaluate(Number target, Object[] params) {
				if (target instanceof Double) {
					return -target.doubleValue();
				}
				return -target.intValue();
			}
		}
		//---------------------------------------------------------------------------------

		final List<InternalOperation> intOps = new LinkedList<InternalOperation>();
		intOps.add(new InternalSumOp(Int_Plus_Int = opf.create("+", int.class, int.class)));
		intOps.add(new InternalSumOp(Int_Plus_Double = opf.create("+", int.class, double.class)));
		intOps.add(new InternalSubOp(Int_Minus_Int = opf.create("-", int.class, int.class)));
		intOps.add(new InternalSubOp(Int_Minus_Double = opf.create("-", double.class, double.class)));
		intOps.add(new InternalMulOp(Int_Mult_Int = opf.create("*", int.class, int.class)));
		intOps.add(new InternalMulOp(Int_Mult_Double = opf.create("*", int.class, double.class)));
		intOps.add(new InternalDivOp(Int_Div_Int = opf.create("/", int.class, int.class)));
		intOps.add(new InternalDivOp(Int_Div_Double = opf.create("/", int.class, double.class)));
		intOps.add(new InternalNegateOp(Int_Unary_Minus = opf.create("-", int.class)));
//		intOps.add(new InternalOperation<Number>(opf.create("==", boolean.class, int.class)) {
//			@Override
//			public Object evaluate(Number target, Object[] params) {
//				//we may need this to handle cases like {Long(5), Long(4)}.exists(a | a == 5)
//				return Boolean.valueOf(target.intValue() == ((Integer) params[0]).intValue());
//			}
//			
//		});
		intOps.add(new InternalOperation<Number>(Int_GreatOrEqual = opf.create(">=", boolean.class, int.class)) {
			@Override
			public Object evaluate(Number target, Object[] params) {
				return Boolean.valueOf(target.intValue() >= ((Number) params[0]).intValue());
			}
		});
		intOps.add(new InternalOperation<Number>(Int_LessOrEqual = opf.create("<=", boolean.class, int.class)) {
			@Override
			public Object evaluate(Number target, Object[] params) {
				return Boolean.valueOf(target.intValue() <= ((Number) params[0]).intValue());
			}
		});
		intOps.add(new InternalOperation<Number>(Int_Less = opf.create("<", boolean.class, int.class)) {
			@Override
			public Object evaluate(Number target, Object[] params) {
				return Boolean.valueOf(target.intValue() < ((Number) params[0]).intValue());
			}
		});
		intOps.add(new InternalOperation<Number>(Int_Greater = opf.create(">", boolean.class, int.class)) {
			@Override
			public Object evaluate(Number target, Object[] params) {
				return Boolean.valueOf(target.intValue() > ((Number) params[0]).intValue());
			}
		});
		intOps.add(new InternalOperation<Number>(Int_UpTo = opf.create("upTo", collectionTypes.getListType(ecorePkg.getEInt()), ecorePkg.getEInt())) {
			@Override
			public Object evaluate(Number target, Object[] params) {
                final ArrayList<Integer> result = new ArrayList<Integer>();
                for (int l1 = target.intValue(), l2 = ((Number) params[0]).intValue(); l1 <= l2; l1++) {
                    result.add(new Integer(l1));
                }
                return result;
			}
			
		});
		intOps.addAll(unmodifiableObjectOps);
		List<InternalOperation> unmodifiableListIntOps = Collections.unmodifiableList(intOps);
		internalOperationsMap.put(ecorePkg.getEIntegerObject(), unmodifiableListIntOps);
		internalOperationsMap.put(ecorePkg.getEInt(), unmodifiableListIntOps);

		final List<InternalOperation> doubleOps = new LinkedList<InternalOperation>();
		doubleOps.add(new InternalSumOp(Double_Plus_Double = opf.create("+", double.class, double.class)));
		doubleOps.add(new InternalSumOp(Double_Plus_Int = opf.create("+", double.class, int.class)));
		doubleOps.add(new InternalSubOp(Double_Minus_Double = opf.create("-", double.class, double.class)));
		doubleOps.add(new InternalSubOp(Double_Minus_Int = opf.create("-", double.class, int.class)));
		doubleOps.add(new InternalMulOp(Double_Mult_Double = opf.create("*", double.class, double.class)));
		doubleOps.add(new InternalMulOp(Double_Mult_Int = opf.create("*", double.class, int.class)));
		doubleOps.add(new InternalDivOp(Double_Div_Double = opf.create("/", double.class, double.class)));
		doubleOps.add(new InternalDivOp(Double_Div_Int = opf.create("/", double.class, int.class)));
		doubleOps.add(new InternalNegateOp(Double_Unary_Minus = opf.create("-", double.class)));
		doubleOps.addAll(unmodifiableObjectOps);
		internalOperationsMap.put(ecorePkg.getEDouble(), doubleOps);

		final List<InternalOperation> collectionOps = new LinkedList<InternalOperation>();
		collectionOps.add(new InternalOperation<Collection>(Collection_IsEmpty = opf.create("isEmpty", ecorePkg.getEBoolean())) {
			@Override
			public Object evaluate(Collection target, Object[] params) {
				// TODO isEmpty is rather attribute
				return target.isEmpty();
			}
		});
		collectionOps.add(new InternalOperation<Collection>(Collection_Add = opf.create("add", CollectionTypesSupport.COLLECTION_OF_OBJECT, ecorePkg.getEJavaObject())) {
			@Override
			public Object evaluate(Collection target, Object[] params) {
				target.add(params[0]);
				return target;
			}
		});
		collectionOps.add(new InternalOperation<Collection>(Collection_AddAll = opf.create("addAll", CollectionTypesSupport.COLLECTION_OF_OBJECT, CollectionTypesSupport.COLLECTION_OF_OBJECT)) {
			@Override
			public Object evaluate(Collection target, Object[] params) {
				target.addAll((Collection) params[0]);
				return target;
			}
		});
		collectionOps.add(new InternalOperation<Collection>(Collection_Clear = opf.create("clear", CollectionTypesSupport.COLLECTION_OF_OBJECT)) {
			@Override
			public Object evaluate(Collection target, Object[] params) {
				target.clear();
				return target;
			}
		});
		collectionOps.add(new InternalOperation<Collection>(Collection_Flatten = opf.create("flatten", CollectionTypesSupport.COLLECTION_OF_OBJECT)) {
			@Override
			public Object evaluate(Collection target, Object[] params) {
				LinkedList rv = new LinkedList();
				for (Object o : target) {
					if (o instanceof Collection) {
						// XXX unlike original xpand, we do not flatten recursively
						rv.addAll((Collection) o);
					} else {
						rv.add(o);
					}
				}
				return rv;
			}
		});
		collectionOps.add(new InternalOperation<Collection>(Collection_Size = opf.create("size", ecorePkg.getEInt())) {
			@Override
			public Object evaluate(Collection target, Object[] params) {
				return target.size();
			}
		});
		collectionOps.add(new InternalOperation<Collection>(Collection_Union = opf.create("union", CollectionTypesSupport.COLLECTION_OF_OBJECT, CollectionTypesSupport.COLLECTION_OF_OBJECT)) {
			@Override
			public Object evaluate(Collection target, Object[] params) {
				LinkedHashSet<Object> rv = new LinkedHashSet<Object>(target);
				rv.addAll((Collection) params[0]);
				return rv;
			}
		});
		collectionOps.add(new InternalOperation<Collection>(Collection_Intersect = opf.create("intersect", CollectionTypesSupport.COLLECTION_OF_OBJECT, CollectionTypesSupport.COLLECTION_OF_OBJECT)) {
			@Override
			public Object evaluate(Collection target, Object[] params) {
				LinkedHashSet<Object> rv = new LinkedHashSet<Object>(target);
				rv.retainAll((Collection) params[0]);
				return rv;
			}
		});
		collectionOps.add(new InternalOperation<Collection>(Collection_Without = opf.create("without", CollectionTypesSupport.COLLECTION_OF_OBJECT, CollectionTypesSupport.COLLECTION_OF_OBJECT)) {
			@Override
			public Object evaluate(Collection target, Object[] params) {
				LinkedHashSet<Object> rv = new LinkedHashSet<Object>(target);
				rv.removeAll((Collection) params[0]);
				return rv;
			}
		});
		collectionOps.add(new InternalOperation<Collection>(Collection_ToSet = opf.create("toSet", CollectionTypesSupport.SET_OF_OBJECT)) {
			@Override
			public Object evaluate(Collection target, Object[] params) {
				return new LinkedHashSet<Object>(target);
			}
		});
		collectionOps.add(new InternalOperation<Collection>(Collection_ToList = opf.create("toList", CollectionTypesSupport.LIST_OF_OBJECT)) {
			@Override
			public Object evaluate(Collection target, Object[] params) {
				return new LinkedList<Object>(target);
			}
		});
		collectionOps.add(new InternalOperation<Collection>(Collection_Contains = opf.create("contains", ecorePkg.getEBoolean(), ecorePkg.getEJavaObject())) {
			@Override
			public Object evaluate(Collection target, Object[] params) {
				return target.contains(params[0]);
			}
		});
		collectionOps.add(new InternalOperation<Collection>(Collection_ContainsAll = opf.create("containsAll", ecorePkg.getEBoolean(), CollectionTypesSupport.COLLECTION_OF_OBJECT)) {
			@Override
			public Object evaluate(Collection target, Object[] params) {
				return target.containsAll((Collection) params[0]);
			}
		});
		List<InternalOperation> unmodifiableListCollectionOps = Collections.unmodifiableList(collectionOps);
		internalOperationsMap.put(CollectionTypesSupport.COLLECTION_TYPE, unmodifiableListCollectionOps);
		internalOperationsMap.put(CollectionTypesSupport.SET_TYPE, unmodifiableListCollectionOps);
		final List<InternalOperation> listOps = new LinkedList<InternalOperation>(unmodifiableListCollectionOps);
		listOps.add(new InternalOperation<List>(List_Get = opf.create("get", ecorePkg.getEJavaObject(), ecorePkg.getEInt())) {
			@Override
			public Object evaluate(List target, Object[] params) {
				int index = ((Number) params[0]).intValue();
				return index < target.size() ? target.get(index) : null;
			}
		});
		listOps.add(new InternalOperation<List>(List_First = opf.create("first", ecorePkg.getEJavaObject())) {
			@Override
			public Object evaluate(List target, Object[] params) {
				return target.isEmpty() ? null : target.get(0);
			}
		});
		listOps.add(new InternalOperation<List>(List_Last = opf.create("last", ecorePkg.getEJavaObject())) {
			@Override
			public Object evaluate(List target, Object[] params) {
				return target.isEmpty() ? null : target.get(target.size() - 1);
			}
		});
		listOps.add(new InternalOperation<List>(List_WithoutFirst = opf.create("withoutFirst", CollectionTypesSupport.LIST_OF_OBJECT)) {
			@Override
			public Object evaluate(List target, Object[] params) {
				if (!target.isEmpty()) {
					LinkedList rv = new LinkedList(target);
					rv.removeFirst();
					return rv;
				}
				return target;
			}
		});
		listOps.add(new InternalOperation<List>(List_WithoutLast = opf.create("withoutLast", CollectionTypesSupport.LIST_OF_OBJECT)) {
			@Override
			public Object evaluate(List target, Object[] params) {
				if (!target.isEmpty()) {
					LinkedList rv = new LinkedList(target);
					rv.removeLast();
					return rv;
				}
				return target;
			}
		});
		listOps.add(new InternalOperation<List>(List_PurgeDups = opf.create("purgeDups", CollectionTypesSupport.LIST_OF_OBJECT)) {
			@Override
			public Object evaluate(List target, Object[] params) {
				if (target.isEmpty()) {
					return target;
				}
				return new LinkedList<Object>(new LinkedHashSet<Object>(target));
			}
		});
		listOps.add(new InternalOperation<List>(List_IndexOf = opf.create("indexOf", ecorePkg.getEInt(), ecorePkg.getEJavaObject())) {
			@Override
			public Object evaluate(List target, Object[] params) {
				return target.indexOf(params[0]);
			}
		});
		internalOperationsMap.put(CollectionTypesSupport.LIST_TYPE, Collections.unmodifiableList(listOps));

		final List<InternalOperation> definitionOps = new LinkedList<InternalOperation>();
		definitionOps.add(new InternalOperation<XpandDefinitionWrap>(opf.create("proceed", VOID)) {
			@Override
			public Object evaluate(XpandDefinitionWrap target, Object[] params) {
				target.proceed();
				return null;
			}
		});
		internalOperationsMap.put(DEFINITION_TYPE, Collections.unmodifiableList(definitionOps));
		
		final List<InternalOperation> iteratorOps = new LinkedList<InternalOperation>();
		iteratorOps.add(new InternalOperation<XpandIterator>(opf.create("isFirstIteration", ecorePkg.getEBoolean())) {
			@Override
			public Object evaluate(XpandIterator target, Object[] params) {
				return target.isFirstIteration();
			}
		});
		internalOperationsMap.put(ITERATOR_TYPE, Collections.unmodifiableList(iteratorOps));
	}

	private static List<EOperation> findInternalOp(EClassifier targetType) {
		List<InternalOperation> ops = internalOperationsMap.get(targetType);
		if (ops != null) {
			List<EOperation> rv = new ArrayList<EOperation>(ops.size());
			for (InternalOperation iop : ops) {
				rv.add(iop.metaOp);
			}
			return rv;
		}
		if (targetType.eClass() == EcorePackage.eINSTANCE.getEClass()) {
			// not instanceof because parametric type and all other XECore
			// classes have different operations, at least
			// meanwhile, when they are dynamic
			return((EClass) targetType).getEAllOperations();
		}
		// TODO Auto-generated method stub
		// String length, +, startsWith, endsWith, subString, toUpperCase, toFirstUpper, toFirstLower, toCharList, replaceAll, replaceFirst, split, matches, trim
		// Int/Real +-*/ > >= < <= != ==
		// Collection toList, toSet, toString, add, addAll, contains, containsAll, remove, removeAll, without, intersect, flatten ;
		// properties - size, isEmpty
		// List get, indexOf, last, first, withoutFirst, withoutLast
		// Set - none
		return null;
	}

	public static EClassifier getTypedElementType(ETypedElement p) {
		if (p.isMany()) {
			return p.isOrdered() ? getListType(p.getEType()) : p.isUnique() ? getSetType(p.getEType()) : getCollectionType(p.getEType());
		}
		return p.getEType();
	}

	private static class OperationFactory {
		EOperation create(String name, Class returnType, Class ... params) {
			EClassifier[] paramsNew = new EClassifier[params.length];
			for (int i = 0; i < paramsNew.length; i++) {
				paramsNew[i] = toEClassifier(params[i]);
				assert params[i] != null;
			}
			EClassifier rt = toEClassifier(returnType);
			assert rt != null : "Unrecognized return type:" + returnType;
			return create(name, rt, paramsNew);
		}

		/**
		 * NOTE, targetType is NOT operation's return type, but method owning class 
		 */
		InternalOperation createReflective(Class targetType, String methodName, Class ... params) {
			try {
				final Method m = targetType.getMethod(methodName, params);
				assert m != null;
				return new InternalOperation<Object>(create(methodName, m.getReturnType(), params)) {
					public Object evaluate(Object target, Object[] params) {
						try {
							Object rv = m.invoke(target, params);
							if (rv != null && rv.getClass().isArray()) {
								return new LinkedList(Arrays.asList((Object[]) rv));
							}
							return rv;
						} catch (Exception e) {
							Activator.logError(e);
							return null;
						}
					}
				};
			} catch (NoSuchMethodException ex) {
				assert false : ex.getMessage();
			}
			return null;
		}

		private EClassifier toEClassifier(Class targetType) {
			if (targetType == void.class) {
				return VOID;
			}
			for (EClassifier c : EcorePackage.eINSTANCE.getEClassifiers()) {
				if (c.getInstanceClass() == targetType) {
					return c;
				}
			}
			if (targetType.isArray()) {
				EClassifier t = toEClassifier(targetType.getComponentType());
				assert t != null : "Unrecognized array component type:" + targetType;
				return getListType(t);
			}
			// TODO other packages
			return null;
		}

		EOperation create(String name, EClassifier returnType, EClassifier ... params) {
			EOperation op = EcoreFactory.eINSTANCE.createEOperation();
			op.setName(name);
			op.setEType(returnType);
			for (EClassifier c : params) {
				EParameter p1 = EcoreFactory.eINSTANCE.createEParameter();
				p1.setName("arg" + c.getName());
				p1.setEType(c);
				op.getEParameters().add(p1);
			}
			return op;
		}
	}

	private static abstract class InternalOperation<T> {
		private final EOperation metaOp;
		private static String INTERNAL_OP_ANNOTATION = "::internalop::";

		private InternalOperation(EOperation metaOp) {
			assert metaOp != null;
			this.metaOp = metaOp;
			EAnnotation internalOpAnn = EcoreFactory.eINSTANCE.createEAnnotation();
			internalOpAnn.setSource(INTERNAL_OP_ANNOTATION);
			metaOp.getEAnnotations().add(internalOpAnn);
		}

		public abstract Object evaluate(T target, Object[] params);

		static boolean isInternalOp(EOperation op) {
			return op.getEAnnotation(INTERNAL_OP_ANNOTATION) != null;
		}
	}

	public static class OperationEx extends Operation {
		private final InternalOperation<Object> internalOp;
		private OperationEx(Object targetObject, Object[] args, InternalOperation<Object> internalOp) {
			super(targetObject, args, internalOp.metaOp);
			this.internalOp = internalOp;
		}
		@Override
		public Object evaluate() {
			return internalOp.evaluate(targetObject, args);
		}
	}

	private static final Map<EOperation, Method> externalOpImplementations = new HashMap<EOperation, Method>(); 

	public static void registerOperationImpl(EOperation metaOp, Method implementation) {
		assert metaOp != null;
		assert implementation != null;
		assert Modifier.isStatic(implementation.getModifiers());
		externalOpImplementations.put(metaOp, implementation);
	}

	public static class Operation {
		protected final EOperation metaOp;
		protected final Object[] args;
		protected final Object targetObject;

		private Operation(Object targetObject, Object[] args, EOperation metaOp) {
			this.targetObject = targetObject;
			this.args = args;
			this.metaOp = metaOp;
			
		}
		public Object evaluate() {
            try {
                final Method m;
                if (externalOpImplementations.containsKey(metaOp)) {
                	m = externalOpImplementations.get(metaOp);
                } else {
                	m = targetObject.getClass().getMethod(metaOp.getName(), getParameterClasses());
                }
                return m.invoke(targetObject, args);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
		}

		private Class[] getParameterClasses() {
			List<EParameter> emfParams = metaOp.getEParameters();
			final Class[] paramClasses = new Class[emfParams.size()];
            for (int i = 0, x = emfParams.size(); i < x; i++) {
                final EParameter param = emfParams.get(i);
        		// XXX works only for generated classes, or those with instance
				// class set,
                // and doesn't work with dynamic models, right?
                paramClasses[i] = param.getEType().getInstanceClass();
            }
            return paramClasses;
		}
	}

	/**
	 * @return true if first argument is more general and second is more
	 *         specific, think Object and String
	 * @see AbstractTypeImpl.isAssignableFrom(this, t)
	 */
	public static boolean isAssignableFrom(EClassifier c1, EClassifier t) {
		if ((t == null) || (c1 == null)) {
			return false;
		}
		if (BuiltinMetaModel.primEquals(c1, t)) {
			return true;
		}
		if (t.equals(VOID)) {
			return true;
		}
		if (false == (t instanceof EClass)) {
			if (c1 instanceof EEnum && t == EcorePackage.eINSTANCE.getEEnumerator()) {
				return true; // HACK - any enumerator instance can be assigned to any enum attribute. 
			}
			if (c1 instanceof EDataType && t instanceof EDataType) {
				return isCompatibleDataTypes((EDataType) c1, (EDataType) t);
			}
			return false;
		}
		if (c1 instanceof EDataType) {
			Class c1Class = ((EDataType) c1).getInstanceClass();
			return c1Class.isAssignableFrom(t.getInstanceClass() == null ? Object.class : t.getInstanceClass()); 
		}
		if (isParameterizedType(c1) && isParameterizedType(t)) {
			return c1.eClass().isSuperTypeOf(t.eClass()) && isAssignableFrom(getInnerType(c1), getInnerType(t));
		}
		// == c1.isSuperTypeOf(t);
		for (EClass superType : ((EClass) t).getEAllSuperTypes()) {
			if (BuiltinMetaModel.primEquals(superType, c1)) {
				return true;
			}
		}
		return false;
	}

	private static boolean primEquals(EClassifier c1, EClassifier obj) {
	    if (obj == null) {
			return false;
		}
	    if (c1 == obj) {
	        return true;
	    }
	    final boolean namesEqual = c1.getName().equals(obj.getName());
	    if (!namesEqual) {
	    	return false;
	    }
	    if (c1.getEPackage() == null) {
	    	return obj.getEPackage() == null;
	    }
    	if (obj.getEPackage() == null) {
    		return false;
    	}
    	if (c1.getEPackage().getNsURI() == null) {
    		return obj.getEPackage().getNsURI() == null;
    	}
   		return c1.getEPackage().getNsURI().equals(obj.getEPackage().getNsURI());  
	}

	private static boolean isCompatibleDataTypes(EDataType dt1, EDataType dt2) {
		try {
			final Class dt1Class = dt1.getInstanceClass();
			final Class dt2Class = dt2.getInstanceClass();
			if (dt1Class != null && dt2Class != null) {
				if (dt1Class == Object.class) {
					// anything (with or without wrapping) can be assigned to object
					return true;
				}
				if (dt1Class.isPrimitive() && !dt2Class.isPrimitive()) {
					Field f = dt2Class.getField("TYPE");
					return dt1Class.equals(f.get(null));
				} else if (!dt1Class.isPrimitive() && dt2Class.isPrimitive()) {
					Field f = dt1Class.getField("TYPE");
					return dt2Class.equals(f.get(null));
				}
				return dt1Class.isAssignableFrom(dt2Class);
			}
			if (dt1Class != null && dt2Class == null) {
				// special case for dt2 datatype from dynamic model instance
				// (e.g. model file in same workspace as template)
				// hence no instance classes yet, but anything is assignable to Object
				// Fixed while resolving #analyze of enum literals compare (==)
				return dt1Class == Object.class;
			}
		} catch (NoSuchFieldException ex) {
			// IGNORE
		} catch (IllegalAccessException ex) {
			// IGNORE
		}
		return false;
	}
	public static List<EStructuralFeature> getAllFeatures(EClassifier targetType) {
		// FIXME @see getAllOperations
		if (targetType instanceof EClass) {
			return ((EClass) targetType).getEAllStructuralFeatures();
		}
		return Collections.emptyList();
	}

	public static List<EOperation> getAllOperation(EClassifier targetType) {
		// FIXME - either have datatypes like int/real as 'honest' EClasses, or
		// provide their operations here
		if (hasBuiltinSupport(targetType)) {
			return findInternalOp(targetType);
		}
		if (targetType instanceof EClass) {
			return ((EClass) targetType).getEAllOperations();
		}
		/*
		 * XXX might be not bad idea to use java reflection to provide
		 * datatype's possible operations if (targetType instanceof EDataType &&
		 * false == targetType instanceof EEnum) { EDataType dt = (EDataType)
		 * targetType; dt.getInstanceClass().getMethods() }
		 */
		return Collections.emptyList();
	}
}
