/*******************************************************************************
 * Copyright (c) 2010, 2016 Willink Transformations and others.
 * 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:
 *   E.D.Willink - initial API and implementation
 * 	 E.D.Willink (Obeo) - Bug 416287 - tuple-valued constraints
 *******************************************************************************/
package org.eclipse.ocl.pivot.internal.ecore.as2es;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.emf.common.util.EMap;
import org.eclipse.emf.common.util.URI;
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.EModelElement;
import org.eclipse.emf.ecore.ENamedElement;
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.ETypeParameter;
import org.eclipse.emf.ecore.ETypedElement;
import org.eclipse.emf.ecore.EcoreFactory;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.xmi.impl.EMOFExtendedMetaData;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.pivot.Annotation;
import org.eclipse.ocl.pivot.AnyType;
import org.eclipse.ocl.pivot.CollectionType;
import org.eclipse.ocl.pivot.Constraint;
import org.eclipse.ocl.pivot.DataType;
import org.eclipse.ocl.pivot.Detail;
import org.eclipse.ocl.pivot.Element;
import org.eclipse.ocl.pivot.Enumeration;
import org.eclipse.ocl.pivot.EnumerationLiteral;
import org.eclipse.ocl.pivot.Import;
import org.eclipse.ocl.pivot.LanguageExpression;
import org.eclipse.ocl.pivot.Model;
import org.eclipse.ocl.pivot.NamedElement;
import org.eclipse.ocl.pivot.Namespace;
import org.eclipse.ocl.pivot.Operation;
import org.eclipse.ocl.pivot.Package;
import org.eclipse.ocl.pivot.Parameter;
import org.eclipse.ocl.pivot.PivotPackage;
import org.eclipse.ocl.pivot.PrimitiveType;
import org.eclipse.ocl.pivot.Property;
import org.eclipse.ocl.pivot.TemplateParameter;
import org.eclipse.ocl.pivot.TemplateSignature;
import org.eclipse.ocl.pivot.TemplateableElement;
import org.eclipse.ocl.pivot.Type;
import org.eclipse.ocl.pivot.TypedElement;
import org.eclipse.ocl.pivot.internal.delegate.DelegateInstaller;
import org.eclipse.ocl.pivot.internal.manager.Orphanage;
import org.eclipse.ocl.pivot.internal.utilities.PivotConstantsInternal;
import org.eclipse.ocl.pivot.internal.utilities.PivotUtilInternal;
import org.eclipse.ocl.pivot.util.AbstractExtendingVisitor;
import org.eclipse.ocl.pivot.util.Visitable;
import org.eclipse.ocl.pivot.utilities.ClassUtil;
import org.eclipse.ocl.pivot.utilities.PivotConstants;
import org.eclipse.ocl.pivot.utilities.StringUtil;
import org.eclipse.ocl.pivot.utilities.ValueUtil;
import org.eclipse.ocl.pivot.values.Bag;
import org.eclipse.ocl.pivot.values.IntegerValue;
import org.eclipse.ocl.pivot.values.OrderedSet;
import org.eclipse.ocl.pivot.values.UnlimitedNaturalValue;

import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;

public class AS2EcoreDeclarationVisitor
extends AbstractExtendingVisitor<Object, AS2Ecore>
{
	public static final @NonNull DuplicateConstraintsFilter duplicateConstraintsFilter = new DuplicateConstraintsFilter();
	public static final @NonNull DuplicateOperationsFilter duplicateOperationsFilter = new DuplicateOperationsFilter();
	public static final @NonNull DuplicatePropertiesFilter duplicatePropertiesFilter = new DuplicatePropertiesFilter();
	public static final @NonNull NonDuplicateConstraintsFilter nonDuplicateConstraintsFilter = new NonDuplicateConstraintsFilter();
	public static final @NonNull NonDuplicateOperationsFilter nonDuplicateOperationsFilter = new NonDuplicateOperationsFilter();
	public static final @NonNull NonDuplicatePropertiesFilter nonDuplicatePropertiesFilter = new NonDuplicatePropertiesFilter();

	protected static class DuplicateConstraintsFilter implements Predicate<Constraint>
	{
		@Override
		public boolean apply(@Nullable Constraint aConstraint) {
			if (aConstraint == null) {
				return false;
			}
			if (aConstraint.getRedefinedConstraints().size() == 0) {
				return false;
			}
			return true;
		}
	}

	protected static class DuplicateOperationsFilter implements Predicate<Operation>
	{
		@Override
		public boolean apply(@Nullable Operation anOperation) {
			if (anOperation == null) {
				return false;
			}
			if (anOperation.getRedefinedOperations().size() == 0) {
				return false;
			}
			if ("containingActivity".equals(anOperation.getName()) && "ActivityNode".equals(anOperation.getOwningClass().getName())) {
				return false;		// FIXME Bug 405061 workaround
			}
			return true;
			//			return (anOperation != null) && (anOperation.getRedefinedOperation().size() != 0);
		}
	}

	protected static class DuplicatePropertiesFilter implements Predicate<Property>
	{
		@Override
		public boolean apply(@Nullable Property aProperty) {
			if (aProperty == null) {
				return false;
			}
			if (aProperty.getRedefinedProperties().size() == 0) {
				return false;
			}
			return ClassUtil.safeEquals(aProperty.getName(), aProperty.getRedefinedProperties().get(0).getName());
		}
	}

	protected static class NonDuplicateConstraintsFilter implements Predicate<Constraint>
	{
		@Override
		public boolean apply(@Nullable Constraint aConstraint) {
			if (aConstraint == null) {
				return false;
			}
			if (aConstraint.getRedefinedConstraints().size() == 0) {
				return true;
			}
			return false;
		}
	}

	protected static class NonDuplicateOperationsFilter implements Predicate<Operation>
	{
		@Override
		public boolean apply(@Nullable Operation anOperation) {
			if (anOperation == null) {
				return false;
			}
			if (anOperation.getRedefinedOperations().size() == 0) {
				return true;
			}
			if ("containingActivity".equals(anOperation.getName()) && "ActivityNode".equals(anOperation.getOwningClass().getName())) {
				return true;		// FIXME Bug 405061 workaround
			}
			return false;
			//			return (anOperation != null) && (anOperation.getRedefinedOperation().size() == 0);
		}
	}

	protected static class NonDuplicatePropertiesFilter implements Predicate<Property>
	{
		@Override
		public boolean apply(@Nullable Property aProperty) {
			if (aProperty == null) {
				return false;
			}
			if (aProperty.getRedefinedProperties().size() == 0) {
				return true;
			}
			return !ClassUtil.safeEquals(aProperty.getName(), aProperty.getRedefinedProperties().get(0).getName());
			//			return (aProperty != null) && (aProperty.getRedefinedProperty().size() == 0);
		}
	}

	protected final @NonNull DelegateInstaller delegateInstaller;

	public AS2EcoreDeclarationVisitor(@NonNull AS2Ecore context) {
		super(context);
		this.delegateInstaller = context.getDelegateInstaller();
	}

	protected void copyClassifier(@NonNull EClassifier eClassifier, org.eclipse.ocl.pivot.@NonNull Class pivotType) {
		copyNamedElement(eClassifier, pivotType);
		@SuppressWarnings("null")@NonNull List<ETypeParameter> eTypeParameters = eClassifier.getETypeParameters();
		copyTemplateSignature(eTypeParameters, pivotType);
		if (pivotType.eIsSet(PivotPackage.Literals.CLASS__INSTANCE_CLASS_NAME)) {
			eClassifier.setInstanceClassName(pivotType.getInstanceClassName());
		}
		else {
			eClassifier.eUnset(EcorePackage.Literals.ECLASSIFIER__INSTANCE_CLASS_NAME);
		}
		//		visitAll(eClassifier.getETypeParameters(), pivotType.getTypeParameters());
		delegateInstaller.installDelegates(eClassifier, pivotType);
		for (Constraint pivotInvariant : pivotType.getOwnedInvariants()) {
			if (!pivotInvariant.isIsCallable()) {
				safeVisit(pivotInvariant);		// Results are inserted directly
			}
		}
	}

	protected @Nullable EAnnotation copyConstraint(@NonNull EModelElement eModelElement, @NonNull Constraint pivotConstraint) {
		EAnnotation eAnnotation = delegateInstaller.createConstraintDelegate(eModelElement, pivotConstraint, context.getEcoreURI());
		if (eAnnotation != null) {
			if (eModelElement instanceof EOperation) {
				AS2Ecore.copyAnnotationComments(eAnnotation, pivotConstraint);
			}
			else {
				AS2Ecore.copyComments(eAnnotation, pivotConstraint);
			}
		}
		return eAnnotation;
	}

	protected void copyDataTypeOrEnum(@NonNull EDataType eDataType, @NonNull DataType pivotDataType) {
		copyClassifier(eDataType, pivotDataType);
		eDataType.setSerializable(pivotDataType.isIsSerializable());
	}

	protected void copyDetails(@NonNull EAnnotation eAnnotation, @NonNull Annotation pivotAnnotation) {
		copyModelElement(eAnnotation, pivotAnnotation);
		@SuppressWarnings("null")@NonNull List<EAnnotation> eAnnotations = eAnnotation.getEAnnotations();
		safeVisitAll(eAnnotations, pivotAnnotation.getOwnedAnnotations());
		for (Detail pivotDetail : pivotAnnotation.getOwnedDetails()) {
			String name = pivotDetail.getName();
			String value = StringUtil.splice(pivotDetail.getValues(), "");
			eAnnotation.getDetails().put(name, value);
		}
	}

	protected void copyModelElement(@NonNull EModelElement eModelElement, @NonNull Element pivotModelElement) {
		context.putCreated(pivotModelElement, eModelElement);
		AS2Ecore.copyComments(eModelElement, pivotModelElement);
	}

	protected void copyNamedElement(@NonNull ENamedElement eNamedElement, @NonNull NamedElement pivotNamedElement) {
		copyModelElement(eNamedElement, pivotNamedElement);
		String name = pivotNamedElement.getName();
		if ("containingActivity".equals(name)) {		// FIXME Bug 405061 workaround
			EObject eContainer = pivotNamedElement.eContainer();
			if ((eContainer instanceof Type) && "ActivityNode".equals(((Type)eContainer).getName())) {
				name = "ActivityNode_" + name;
			}
		}
		else if ("inActivity".equals(name)) {		// FIXME Bug 420330 workaround
			EObject eContainer = pivotNamedElement.eContainer();
			if ((eContainer instanceof Type) && "StructuredActivityNode".equals(((Type)eContainer).getName())) {
				name = "activity";
			}
		}
		eNamedElement.setName(name);
		@SuppressWarnings("null")@NonNull List<EAnnotation> eAnnotations = eNamedElement.getEAnnotations();
		safeVisitAll(eAnnotations, pivotNamedElement.getOwnedAnnotations());
	}

	protected void copyTemplateSignature(@NonNull List<ETypeParameter> eTypeParameters, TemplateableElement pivotElement) {
		TemplateSignature templateSignature = pivotElement.getOwnedSignature();
		if (templateSignature != null) {
			List<TemplateParameter> parameters = templateSignature.getOwnedParameters();
			safeVisitAll(eTypeParameters, parameters);
		}
	}

	protected void copyTypedElement(@NonNull ETypedElement eTypedElement, @NonNull TypedElement pivotTypedElement) {
		copyNamedElement(eTypedElement, pivotTypedElement);
		context.defer(pivotTypedElement);		// Defer type/multiplicity setting
	}

	protected @Nullable EAnnotation createOppositeEAnnotation(@NonNull Property property) {
		String lower = null;
		String ordered = null;
		String unique = null;
		String upper = null;
		IntegerValue lowerValue;
		UnlimitedNaturalValue upperValue;
		Type propertyType = property.getType();
		Type type;
		if (propertyType instanceof CollectionType) {
			CollectionType collectionType = (CollectionType)propertyType;
			type = collectionType.getElementType();
			lowerValue = collectionType.getLowerValue();
			upperValue = collectionType.getUpperValue();
			if (collectionType.isOrdered() != PivotConstantsInternal.DEFAULT_IMPLICIT_OPPOSITE_ORDERED) {
				ordered = Boolean.toString(collectionType.isOrdered());
			}
			if (collectionType.isUnique() != PivotConstantsInternal.DEFAULT_IMPLICIT_OPPOSITE_UNIQUE) {
				unique = Boolean.toString(collectionType.isUnique());
			}
			if (!PivotConstantsInternal.DEFAULT_IMPLICIT_OPPOSITE_LOWER_VALUE.equals(lowerValue)) {
				lower = lowerValue.toString();
			}
			if (!PivotConstantsInternal.DEFAULT_IMPLICIT_OPPOSITE_UPPER_VALUE.equals(upperValue)) {
				upper = upperValue.toString();
			}
		}
		else {
			type = propertyType;
			lowerValue = property.isIsRequired() ? ValueUtil.ONE_VALUE : ValueUtil.ZERO_VALUE;
			upperValue = ValueUtil.UNLIMITED_ONE_VALUE;
			if (!ValueUtil.ZERO_VALUE.equals(lowerValue)) {
				lower = lowerValue.toString();
			}
			if (!ValueUtil.UNLIMITED_ONE_VALUE.equals(upperValue)) {
				upper = upperValue.toString();
			}
		}
		String name = property.getName();
		if (name.equals(type.getName()) && (lower == null) && (ordered == null) && (unique == null) && (upper == null)) {
			return null;
		}
		lower = null;
		ordered = null;
		unique = null;
		upper = null;
		if (propertyType instanceof CollectionType) {
			CollectionType collectionType = (CollectionType)propertyType;
			if (collectionType.isOrdered() != PivotConstantsInternal.ANNOTATED_IMPLICIT_OPPOSITE_ORDERED) {
				ordered = Boolean.toString(collectionType.isOrdered());
			}
			if (collectionType.isUnique() != PivotConstantsInternal.ANNOTATED_IMPLICIT_OPPOSITE_UNIQUE) {
				unique = Boolean.toString(collectionType.isUnique());
			}
		}
		if (!PivotConstantsInternal.ANNOTATED_IMPLICIT_OPPOSITE_LOWER_VALUE.equals(lowerValue)) {
			lower = lowerValue.toString();
		}
		if (!PivotConstantsInternal.ANNOTATED_IMPLICIT_OPPOSITE_UPPER_VALUE.equals(upperValue)) {
			upper = upperValue.toString();
		}
		EAnnotation eAnnotation = EcoreFactory.eINSTANCE.createEAnnotation();
		eAnnotation.setSource(EMOFExtendedMetaData.EMOF_PROPERTY_OPPOSITE_ROLE_NAME_ANNOTATION_SOURCE);
		EMap<String, String> details = eAnnotation.getDetails();
		details.put(EMOFExtendedMetaData.EMOF_COMMENT_BODY, name);
		if (lower != null) {
			details.put("lower", lower);
		}
		if (ordered != null) {
			details.put("ordered", ordered);
		}
		if (unique != null) {
			details.put("unique", unique);
		}
		if (upper != null) {
			details.put("upper", upper);
		}
		return eAnnotation;
	}

	public <T extends EObject> void safeVisitAll(@NonNull List<T> eObjects, @NonNull Iterable<? extends Element> pivotObjects) {
		for (Element pivotObject : pivotObjects) {
			@SuppressWarnings("unchecked")
			T eObject = (T) safeVisit(pivotObject);
			if (eObject != null) {
				eObjects.add(eObject);
			}
			// else error
		}
	}

	@Override
	public EObject visiting(@NonNull Visitable visitable) {
		throw new IllegalArgumentException("Unsupported " + visitable.eClass().getName() + " for AS2Ecore Declaration pass");
	}

	@Override
	public EObject visitAnnotation(@NonNull Annotation pivotAnnotation) {
		@SuppressWarnings("null")
		@NonNull EAnnotation eAnnotation = EcoreFactory.eINSTANCE.createEAnnotation();
		copyDetails(eAnnotation, pivotAnnotation);
		eAnnotation.setSource(pivotAnnotation.getName());
		@SuppressWarnings("null")@NonNull List<EObject> contents = eAnnotation.getContents();
		safeVisitAll(contents, pivotAnnotation.getOwnedContents());
		if (!pivotAnnotation.getReferences().isEmpty()) {
			context.defer(pivotAnnotation);
		}
		return eAnnotation;
	}

	@Override
	public EObject visitAnyType(@NonNull AnyType pivotAnyType) {
		if (pivotAnyType.getOwnedBindings().size() > 0) {
			return null;
		}
		@SuppressWarnings("null")
		@NonNull EClass eClass = EcoreFactory.eINSTANCE.createEClass();
		copyClassifier(eClass, pivotAnyType);
		Class<?> instanceClass = null;
		String name = pivotAnyType.getName();
		if ("OclAny".equals(name)) {
			instanceClass = Object.class;
		}
		eClass.setInstanceClass(instanceClass);
		eClass.setAbstract(true);
		eClass.setInterface(true);
		return eClass;
	}

	@Override
	public EObject visitClass(org.eclipse.ocl.pivot.@NonNull Class pivotClass) {
		if (pivotClass.getOwnedBindings().size() > 0) {
			return null;
		}
		@SuppressWarnings("null")
		@NonNull EClass eClass = EcoreFactory.eINSTANCE.createEClass();
		copyClassifier(eClass, pivotClass);
		Class<?> instanceClass = null;
		boolean isAbstract = pivotClass.isIsAbstract();
		boolean isInterface = pivotClass.isIsInterface();
		String className = pivotClass.getName();
		if ("OclComparable".equals(className)) {
			instanceClass = Object.class;
			isAbstract = true;
			isInterface = true;
		}
		else if ("OclElement".equals(className)) {
			instanceClass = Object.class;
			isAbstract = true;
			isInterface = true;
		}
		else if ("OclInvalid".equals(className)) {
			instanceClass = Object.class;
			isAbstract = true;
			isInterface = true;
		}
		else if ("OclLambda".equals(className)) {
			instanceClass = Object.class;
			isAbstract = true;
			isInterface = true;
		}
		else if ("OclMessage".equals(className)) {
			instanceClass = Object.class;
			isAbstract = true;
			isInterface = true;
		}
		//		else if ("OclSelf".equals(className)) {
		//			instanceClass = Object.class;
		//			isAbstract = true;
		//			isInterface = true;
		//		}
		else if ("OclState".equals(className)) {
			instanceClass = Object.class;
			isAbstract = true;
			isInterface = true;
		}
		else if ("OclSummable".equals(className)) {
			instanceClass = Object.class;
			isAbstract = true;
			isInterface = true;
		}
		else if ("OclTuple".equals(className)) {
			instanceClass = Object.class;
			isAbstract = true;
			isInterface = true;
		}
		else if ("OclType".equals(className)) {
			instanceClass = Object.class;
			isAbstract = true;
			isInterface = true;
		}
		else if ("OclVoid".equals(className)) {
			instanceClass = Object.class;
			isAbstract = true;
			isInterface = true;
		}
		eClass.setAbstract(isAbstract);
		eClass.setInterface(isInterface);
		if (instanceClass != null) {
			eClass.setInstanceClass(instanceClass);
		}
		context.defer(pivotClass);		// Defer superclass resolution
		@SuppressWarnings("null")@NonNull List<EOperation> eOperations = eClass.getEOperations();
		@NonNull Iterable<Constraint> nonDuplicateConstraints = Iterables.filter(pivotClass.getOwnedInvariants(), nonDuplicateConstraintsFilter);
		//		safeVisitAll(eOperations, nonDuplicateConstraints);
		@NonNull Iterable<Operation> nonDuplicateOperations = Iterables.filter(pivotClass.getOwnedOperations(), nonDuplicateOperationsFilter);
		safeVisitAll(eOperations, nonDuplicateOperations);
		@SuppressWarnings("null")@NonNull List<EStructuralFeature> eStructuralFeatures = eClass.getEStructuralFeatures();
		@NonNull Iterable<Property> nonDuplicateProperties = Iterables.filter(pivotClass.getOwnedProperties(), nonDuplicatePropertiesFilter);
		safeVisitAll(eStructuralFeatures, nonDuplicateProperties);
		Map<String, Object> options = context.getOptions();
		String invariantPrefix = AS2Ecore.getInvariantPrefix(options);
		for (Constraint pivotInvariant : nonDuplicateConstraints) {
			if (pivotInvariant.isIsCallable()) {
				String name = pivotInvariant.getName();
				if (invariantPrefix != null) {
					name = invariantPrefix + name;
				}
				EOperation eOperation = AS2Ecore.createConstraintEOperation(pivotInvariant, name, options);
				eOperations.add(eOperation);
				context.putCreated(pivotInvariant, eOperation);
				copyConstraint(eOperation, pivotInvariant);
			}
		}
		if (!context.isSuppressDuplicates()) {
			List<ETypedElement> eDuplicates = null;
			@NonNull Iterable<Constraint> duplicateConstraints = Iterables.filter(pivotClass.getOwnedInvariants(), duplicateConstraintsFilter);
			for (Constraint asConstraint : duplicateConstraints) {
				if (eDuplicates == null) {
					eDuplicates = new ArrayList<ETypedElement>();
				}
				//				Object eOperation = safeVisit(asConstraint);
				if (asConstraint.isIsCallable()) {
					EOperation eOperation = AS2Ecore.createConstraintEOperation(asConstraint, asConstraint.getName(), options);
					eOperations.add(eOperation);
					context.putCreated(asConstraint, eOperation);
					copyConstraint(eOperation, asConstraint);
					eDuplicates.add(eOperation);
					context.defer(asConstraint);		// Defer references
				}
			}
			@NonNull Iterable<Operation> duplicateOperations = Iterables.filter(pivotClass.getOwnedOperations(), duplicateOperationsFilter);
			for (Operation asOperation : duplicateOperations) {
				if (eDuplicates == null) {
					eDuplicates = new ArrayList<ETypedElement>();
				}
				Object eOperation = safeVisit(asOperation);
				if (eOperation instanceof EOperation) {
					eDuplicates.add((EOperation)eOperation);
				}
			}
			@NonNull Iterable<Property> duplicateProperties = Iterables.filter(pivotClass.getOwnedProperties(), duplicatePropertiesFilter);
			for (Property asProperty : duplicateProperties) {
				if (eDuplicates == null) {
					eDuplicates = new ArrayList<ETypedElement>();
				}
				Object eStructuralFeature = safeVisit(asProperty);
				if (eStructuralFeature instanceof EStructuralFeature) {
					eDuplicates.add((EStructuralFeature) eStructuralFeature);
				}
			}
			if (eDuplicates != null) {
				EAnnotation eAnnotation = eClass.getEAnnotation(PivotConstantsInternal.DUPLICATES_ANNOTATION_SOURCE);
				if (eAnnotation == null) {
					eAnnotation = EcoreFactory.eINSTANCE.createEAnnotation();
					eAnnotation.setSource(PivotConstantsInternal.DUPLICATES_ANNOTATION_SOURCE);
					eClass.getEAnnotations().add(eAnnotation);
				}
				context.refreshList(eAnnotation.getContents(), eDuplicates);
			}
		}
		return eClass;
	}

	@Override
	public EObject visitCollectionType(@NonNull CollectionType pivotCollectionType) {
		if (pivotCollectionType.getOwnedBindings().size() > 0) {
			return null;
		}
		@SuppressWarnings("null")
		@NonNull EClass eClass = EcoreFactory.eINSTANCE.createEClass();
		copyClassifier(eClass, pivotCollectionType);
		Class<?> instanceClass = null;
		String name = pivotCollectionType.getName();
		if ("Bag".equals(name)) {
			instanceClass = Bag.class;
		}
		else if ("Collection".equals(name)) {
			instanceClass = Collection.class;
		}
		else if ("OrderedCollection".equals(name)) {
			instanceClass = Collection.class;
		}
		else if ("OrderedSet".equals(name)) {
			instanceClass = OrderedSet.class;
		}
		else if ("Sequence".equals(name)) {
			instanceClass = List.class;
		}
		else if ("Set".equals(name)) {
			instanceClass = Set.class;
		}
		else if ("UniqueCollection".equals(name)) {
			instanceClass = Collection.class;
		}
		@SuppressWarnings("null")@NonNull List<EStructuralFeature> eStructuralFeatures = eClass.getEStructuralFeatures();
		@NonNull Iterable<Property> nonDuplicateProperties = Iterables.filter(pivotCollectionType.getOwnedProperties(), nonDuplicatePropertiesFilter);
		safeVisitAll(eStructuralFeatures, nonDuplicateProperties);
		eClass.setInstanceClass(instanceClass);
		eClass.setAbstract(true);
		eClass.setInterface(true);
		context.defer(pivotCollectionType);		// Defer superclass resolution
		return eClass;
	}

	@Override
	public EObject visitConstraint(@NonNull Constraint pivotConstraint) {
		Element eContainer = (Element)pivotConstraint.eContainer();
		if (eContainer != null) {
			EModelElement eModelElement = context.getCreated(EModelElement.class, eContainer);
			if (eModelElement != null) {
				copyConstraint(eModelElement, pivotConstraint);
				return null;
			}
		}
		return null;
	}

	@Override
	public EObject visitDataType(@NonNull DataType pivotDataType) {
		if (pivotDataType.getOwnedBindings().size() > 0) {
			return null;
		}
		@SuppressWarnings("null")
		@NonNull EDataType eDataType = EcoreFactory.eINSTANCE.createEDataType();
		copyDataTypeOrEnum(eDataType, pivotDataType);
		return eDataType;
	}

	@Override
	public EObject visitEnumeration(@NonNull Enumeration pivotEnumeration) {
		if (pivotEnumeration.getOwnedBindings().size() > 0) {
			return null;
		}
		@SuppressWarnings("null")
		@NonNull EEnum eEnum = EcoreFactory.eINSTANCE.createEEnum();
		copyDataTypeOrEnum(eEnum, pivotEnumeration);
		@SuppressWarnings("null")@NonNull List<EEnumLiteral> eLiterals = eEnum.getELiterals();
		safeVisitAll(eLiterals, pivotEnumeration.getOwnedLiterals());
		return eEnum;
	}

	@Override
	public EObject visitEnumerationLiteral(@NonNull EnumerationLiteral pivotEnumLiteral) {
		@SuppressWarnings("null")
		@NonNull EEnumLiteral eEnumLiteral = EcoreFactory.eINSTANCE.createEEnumLiteral();
		copyNamedElement(eEnumLiteral, pivotEnumLiteral);
		if (pivotEnumLiteral.eIsSet(PivotPackage.Literals.ENUMERATION_LITERAL__VALUE)) {
			eEnumLiteral.setValue(pivotEnumLiteral.getValue().intValue());
		}
		else {
			eEnumLiteral.eUnset(EcorePackage.Literals.EENUM_LITERAL__VALUE);
		}
		return eEnumLiteral;
	}

	@Override
	public Object visitModel(@NonNull Model pivotModel) {
		EModelElement firstElement = null;
		List<EObject> outputObjects = new ArrayList<EObject>();
		for (@SuppressWarnings("null")org.eclipse.ocl.pivot.@NonNull Package pivotObject : pivotModel.getOwnedPackages()) {
			if (!Orphanage.isTypeOrphanage(pivotObject) && !PivotUtilInternal.isImplicitPackage(pivotObject)) {
				Object ecoreObject = safeVisit(pivotObject);
				if (ecoreObject instanceof EObject) {
					outputObjects.add((EObject) ecoreObject);
					if ((firstElement == null) && (ecoreObject instanceof EModelElement)) {
						firstElement = (EModelElement) ecoreObject;
					}
				}
			}
		}
		List<Import> imports = pivotModel.getOwnedImports();
		if (imports.size() > 0) {
			if (imports.size() > 0) {
				imports = new ArrayList<Import>(imports);
				Collections.sort(imports, new Comparator<Import>()
				{
					@Override
					public int compare(Import o1, Import o2) {
						String n1 = o1.getName();
						String n2 = o2.getName();
						if (n1 == null) n1 = "";
						if (n2 == null) n1 = "";
						return n1.compareTo(n2);
					}
				}
						);
			}
			EAnnotation importAnnotation = null;
			URI ecoreURI = context.getEcoreURI();
			for (Import anImport : imports) {
				Namespace importedNamespace = anImport.getImportedNamespace();
				if (importedNamespace != null) {
					if (importAnnotation == null) {
						importAnnotation = EcoreFactory.eINSTANCE.createEAnnotation();
						importAnnotation.setSource(PivotConstants.IMPORT_ANNOTATION_SOURCE);
					}
					EObject eTarget = importedNamespace.getESObject();
					if (eTarget != null) {
						URI uri = null;
						if ((eTarget instanceof EPackage) && ClassUtil.isRegistered(eTarget.eResource())) {
							String nsURI = ((EPackage)eTarget).getNsURI();
							if (nsURI != null) {
								uri = URI.createURI(nsURI);
							}
						}
						if (uri == null) {
							uri = EcoreUtil.getURI(eTarget);
						}
						URI uri2 = uri.deresolve(ecoreURI, true, true, true);
						importAnnotation.getDetails().put(anImport.getName(), uri2.toString());
					}
					else if (importedNamespace instanceof org.eclipse.ocl.pivot.Package) {
						importAnnotation.getDetails().put(anImport.getName(), ((org.eclipse.ocl.pivot.Package)importedNamespace).getURI());
					}
					else {
						importAnnotation.getDetails().put(anImport.getName(), importedNamespace.toString());
					}
				}
			}
			if ((firstElement != null) && (importAnnotation != null)) {
				firstElement.getEAnnotations().add(importAnnotation);
			}
		}
		return outputObjects;
	}

	@Override
	public EObject visitOperation(@NonNull Operation pivotOperation) {
		if (pivotOperation.getOwnedBindings().size() > 0) {
			return null;
		}
		@SuppressWarnings("null")
		@NonNull EOperation eOperation = EcoreFactory.eINSTANCE.createEOperation();
		copyTypedElement(eOperation, pivotOperation);
		@SuppressWarnings("null")@NonNull List<ETypeParameter> eTypeParameters = eOperation.getETypeParameters();
		copyTemplateSignature(eTypeParameters, pivotOperation);
		@SuppressWarnings("null")@NonNull List<EParameter> eParameters = eOperation.getEParameters();
		safeVisitAll(eParameters, pivotOperation.getOwnedParameters());
		//		safeVisitAll(eOperation.getEGenericExceptions(), pivotOperation.getRaisedException());
		LanguageExpression bodyExpression = pivotOperation.getBodyExpression();
		if (bodyExpression != null) {
			EAnnotation eBodyConstraint = delegateInstaller.createOperationDelegate(eOperation, bodyExpression, context.getEcoreURI());
			if (eBodyConstraint != null) {
				//				AS2Ecore.copyComments(eBodyConstraint, bodyExpression);
			}
		}
		for (Constraint pivotConstraint : pivotOperation.getOwnedPreconditions()) {
			safeVisit(pivotConstraint);		// Results are inserted directly
		}
		for (Constraint pivotConstraint : pivotOperation.getOwnedPostconditions()) {
			safeVisit(pivotConstraint);		// Results are inserted directly
		}
		if (pivotOperation.isIsTransient()) {
			EAnnotation eAnnotation = EcoreFactory.eINSTANCE.createEAnnotation();
			eAnnotation.setSource(PivotConstants.OPERATION_ANNOTATION_SOURCE);
			EMap<String, String> details = eAnnotation.getDetails();
			details.put(PivotConstants.OPERATION_IS_TRANSIENT, "true");
			eOperation.getEAnnotations().add(eAnnotation);
		}
		return eOperation;
	}

	@Override
	public EObject visitPackage(@NonNull Package pivotPackage) {
		@SuppressWarnings("null")
		@NonNull EPackage ePackage = EcoreFactory.eINSTANCE.createEPackage();
		copyNamedElement(ePackage, pivotPackage);
		context.defer(pivotPackage);		// Defer delegate annotation analysis
		if (pivotPackage.eIsSet(PivotPackage.Literals.PACKAGE__NS_PREFIX)) {
			ePackage.setNsPrefix(pivotPackage.getNsPrefix());
		}
		if (pivotPackage.eIsSet(PivotPackage.Literals.PACKAGE__URI)) {
			ePackage.setNsURI(pivotPackage.getURI());
		}
		@SuppressWarnings("null")@NonNull List<EPackage> eSubpackages = ePackage.getESubpackages();
		safeVisitAll(eSubpackages, pivotPackage.getOwnedPackages());
		@SuppressWarnings("null")@NonNull List<EClassifier> eClassifiers = ePackage.getEClassifiers();
		safeVisitAll(eClassifiers, pivotPackage.getOwnedClasses());
		return ePackage;
	}

	@Override
	public EObject visitParameter(@NonNull Parameter pivotParameter) {
		@SuppressWarnings("null")
		@NonNull EParameter eParameter = EcoreFactory.eINSTANCE.createEParameter();
		copyTypedElement(eParameter, pivotParameter);
		return eParameter;
	}

	@Override
	public EObject visitPrimitiveType(@NonNull PrimitiveType pivotPrimitiveType) {
		if (pivotPrimitiveType.getOwnedBindings().size() > 0) {
			return null;
		}
		@SuppressWarnings("null")
		@NonNull EDataType eDataType = EcoreFactory.eINSTANCE.createEDataType();
		copyDataTypeOrEnum(eDataType, pivotPrimitiveType);
		/*		Class<?> instanceClass = null;
		String name = pivotPrimitiveType.getName();
		if ("Boolean".equals(name)) {
			instanceClass = Boolean.class;
		}
		else if ("Integer".equals(name)) {
			instanceClass = IntegerValue.class;
		}
		else if ("Real".equals(name)) {
			instanceClass = RealValue.class;
		}
		else if ("String".equals(name)) {
			instanceClass = String.class;
		}
		else if ("UnlimitedNatural".equals(name)) {
			instanceClass = UnlimitedNaturalValue.class;
		}
		eDataType.setInstanceClass(instanceClass); */
		return eDataType;
	}

	@Override
	public EObject visitProperty(@NonNull Property pivotProperty) {
		if (pivotProperty.isIsImplicit()) {
			return null;
		}
		EStructuralFeature eStructuralFeature;
		Type type = pivotProperty.getType();
		CollectionType ecoreCollectionType = context.isEcoreCollection(type);
		if (ecoreCollectionType != null) {
			type = ecoreCollectionType.getElementType();
		}
		if (type instanceof DataType) {
			EAttribute eAttribute = EcoreFactory.eINSTANCE.createEAttribute();
			eAttribute.setID(pivotProperty.isIsID());
			eStructuralFeature = eAttribute;
		}
		else {
			EReference eReference = EcoreFactory.eINSTANCE.createEReference();
			if ((pivotProperty.getOpposite() != null) || !pivotProperty.getKeys().isEmpty()) {
				context.defer(pivotProperty);
			}
			eReference.setContainment(pivotProperty.isIsComposite());
			eReference.setResolveProxies(pivotProperty.isIsResolveProxies());
			eStructuralFeature = eReference;
		}
		Property opposite = pivotProperty.getOpposite();
		if ((opposite != null) && opposite.isIsImplicit()) {
			EAnnotation eAnnotation = createOppositeEAnnotation(opposite);
			if (eAnnotation != null) {
				eStructuralFeature.getEAnnotations().add(eAnnotation);
			}
		}
		copyTypedElement(eStructuralFeature, pivotProperty);
		eStructuralFeature.setChangeable(!pivotProperty.isIsReadOnly());
		eStructuralFeature.setDerived(pivotProperty.isIsDerived());
		eStructuralFeature.setTransient(pivotProperty.isIsTransient());
		eStructuralFeature.setUnsettable(pivotProperty.isIsUnsettable());
		eStructuralFeature.setVolatile(pivotProperty.isIsVolatile());
		//		Object defaultValue = pivotProperty.getDefaultValue();
		String defaultValueLiteral = pivotProperty.getDefaultValueString();
		/*		if (defaultValue != null) {
			if (defaultValue instanceof String) {
				defaultValueLiteral = (String)defaultValue;
			}
			else if (defaultValue instanceof Boolean) {
				defaultValueLiteral = defaultValue.toString();
			}
			else if (defaultValue instanceof Value) {
				defaultValueLiteral = defaultValue.toString();
			}
			else if (defaultValue instanceof EnumerationLiteral) {
				defaultValueLiteral = ((EnumerationLiteral)defaultValue).getName();
			}
//			else if (defaultValue instanceof EnumerationLiteralId) {						// type is Enumeration
//				defaultValueLiteral = ((EnumerationLiteralId)defaultValue).getName();
//			}
			else {			// FIXME Use URI for lack of Ecore support
				defaultValueLiteral = String.valueOf(defaultValue);		// FIXME need init EAnnotation for generality
			}
/ *			String defaultValueLiteral = eObject.getDefaultValueLiteral();
			Object boxedValue;
			EClassifier eType = eObject.getEType();
			if (type instanceof DataType) {
				EDataType eDataType = (EDataType)eType;
				EFactory eFactoryInstance = eDataType.getEPackage().getEFactoryInstance();
				Object unboxedValue = eFactoryInstance.createFromString(eDataType, defaultValueLiteral);
				boxedValue = metamodelManager.getIdResolver().boxedValueOf(unboxedValue);
				pivotElement.setDefaultValue(boxedValue);
			}
			else {
				URI uri = URI.createURI(defaultValueLiteral);
				boxedValue = metamodelManager.getExternalResourceSet().getEObject(uri, false);
			}
			pivotElement.setDefaultValue(boxedValue); * /


		} */
		if (defaultValueLiteral != null) {
			eStructuralFeature.setDefaultValueLiteral(defaultValueLiteral);
		}
		else {
			eStructuralFeature.eUnset(EcorePackage.Literals.ESTRUCTURAL_FEATURE__DEFAULT_VALUE_LITERAL);
		}
		LanguageExpression defaultExpression = pivotProperty.getOwnedExpression();
		if (defaultExpression != null) {
			delegateInstaller.createPropertyDelegate(eStructuralFeature, defaultExpression, context.getEcoreURI());
		}
		/*		for (Property redefinedProperty : pivotProperty.getRedefinedProperty()) {
			EAnnotation eAnnotation = EcoreFactory.eINSTANCE.createEAnnotation();
			eAnnotation.setSource(PivotConstants.REDEFINES_ANNOTATION_SOURCE);
			eStructuralFeature.getEAnnotations().add(eAnnotation);
		} */
		return eStructuralFeature;
	}

	@Override
	public EObject visitTemplateParameter(@NonNull TemplateParameter pivotTemplateParameter) {
		ETypeParameter eTypeParameter = EcoreFactory.eINSTANCE.createETypeParameter();
		eTypeParameter.setName(pivotTemplateParameter.getName());
		context.putCreated(pivotTemplateParameter, eTypeParameter);
		if (!pivotTemplateParameter.getConstrainingClasses().isEmpty()) {
			context.defer(pivotTemplateParameter);
		}
		return eTypeParameter;
	}
}
