/*
 * Copyright (c) 2003, 2004 IBM Corporation and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 *
 * Contributors:
 *   IBM - Initial API and implementation
 *
 * $Id: ProfileOperations.java,v 1.15 2004/12/03 22:32:52 khussey Exp $
 */
package org.eclipse.uml2.internal.operation;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.eclipse.emf.common.util.AbstractTreeIterator;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.TreeIterator;
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.EFactory;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.EcoreFactory;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.uml2.Classifier;
import org.eclipse.uml2.DataType;
import org.eclipse.uml2.Element;
import org.eclipse.uml2.ElementImport;
import org.eclipse.uml2.Enumeration;
import org.eclipse.uml2.EnumerationLiteral;
import org.eclipse.uml2.Extension;
import org.eclipse.uml2.Generalization;
import org.eclipse.uml2.Implementation;
import org.eclipse.uml2.InstanceValue;
import org.eclipse.uml2.Interface;
import org.eclipse.uml2.Model;
import org.eclipse.uml2.NamedElement;
import org.eclipse.uml2.PackageImport;
import org.eclipse.uml2.PrimitiveType;
import org.eclipse.uml2.Profile;
import org.eclipse.uml2.ProfileApplication;
import org.eclipse.uml2.Property;
import org.eclipse.uml2.Stereotype;
import org.eclipse.uml2.Type;
import org.eclipse.uml2.UML2Package;
import org.eclipse.uml2.VisibilityKind;
import org.eclipse.uml2.util.UML2Resource;
import org.eclipse.uml2.util.UML2Switch;

/**
 * A static utility class that provides operations related to profiles.
 */
public final class ProfileOperations
		extends UML2Operations {

	/**
	 * The source for the attributes annotation on profiles.
	 */
	public static final String ANNOTATION_SOURCE__ATTRIBUTES = "attributes"; //$NON-NLS-1$

	/**
	 * The source for the ePackages annotation on profiles.
	 */
	public static final String ANNOTATION_SOURCE__E_PACKAGES = "ePackages"; //$NON-NLS-1$

	/**
	 * The key for the version details entry in the attributes annotation on
	 * profiles.
	 */
	public static final String ANNOTATION_DETAILS_KEY__VERSION = "version"; //$NON-NLS-1$

	/**
	 * Constructs a new Profile Operations. This constructor should never be
	 * called because this is a static utility class.
	 */
	private ProfileOperations() {
		super();
	}

	/**
	 * Retrieves a name suitable for an Ecore representation of the specified
	 * named element.
	 * 
	 * @param namedElement
	 *            The named element for which to retrieve an Ecore name.
	 * @return The Ecore named element name.
	 */
	protected static String getENamedElementName(NamedElement namedElement) {
		String qualifiedName = namedElement.getQualifiedName();

		if (!isEmpty(qualifiedName)) {
			StringBuffer eNamedElementName = new StringBuffer();
			String[] names = qualifiedName.split(namedElement.separator());

			for (int i = 0, length = names.length; i < length; i++) {
				appendValidIdentifier(eNamedElementName, names[i]);

				if (i + 1 < length) {
					eNamedElementName.append("__"); //$NON-NLS-1$
				}
			}

			return eNamedElementName.toString();
		}

		return getValidIdentifier(namedElement.getName());
	}

	/**
	 * Retrieves a name suitable for an Ecore representation of the specified
	 * profile.
	 * 
	 * @param profile
	 *            The profile for which to retrieve an Ecore name.
	 * @return The Ecore package name.
	 */
	public static String getEPackageName(Profile profile) {
		return getENamedElementName(profile) + '_' + getVersion(profile);
	}

	/**
	 * Retrieves a name suitable for an Ecore representation of the specified
	 * classifier.
	 * 
	 * @param classifier
	 *            The classifier for which to retrieve an Ecore name.
	 * @return The Ecore classifier name.
	 */
	public static String getEClassifierName(Classifier classifier) {
		return getENamedElementName(classifier);
	}

	/**
	 * Retrieves the specified version of the Ecore package representing the
	 * specified profile.
	 * 
	 * @param profile
	 *            The profile for which to retrieve the Ecore package.
	 * @param version
	 *            The version of the Ecore package to retrieve.
	 * @return The Ecore package representing the profile, or <code>null</code>.
	 */
	public static EPackage getEPackage(Profile profile, String version) {

		for (Iterator ePackages = getEAnnotation(ANNOTATION_SOURCE__E_PACKAGES,
			profile).getContents().iterator(); ePackages.hasNext();) {

			EPackage ePackage = (EPackage) ePackages.next();

			if (safeEquals(version, ePackage.getName().substring(
				ePackage.getName().lastIndexOf('_') + 1))) {

				return ePackage;
			}
		}

		return null;
	}

	/**
	 * Retrieves the Ecore classifier representing the specified type from the
	 * specified Ecore package.
	 * 
	 * @param ePackage
	 *            The Ecore package from which to retrieve the classifier.
	 * @param type
	 *            The type for which to retrieve the Ecore classifier.
	 * @return The Ecore classifier representing the type.
	 */
	public static EClassifier getEClassifier(EPackage ePackage, Type type) {
		EClassifier eClassifier = ePackage.getEClassifier(type.getName());

		if (null == eClassifier) {

			if (PrimitiveType.class.isInstance(type)) {

				if ("Boolean".equals(type.getName())) { //$NON-NLS-1$
					eClassifier = EcorePackage.eINSTANCE.getEBoolean();
				} else if ("Integer".equals(type.getName())) { //$NON-NLS-1$
					eClassifier = EcorePackage.eINSTANCE.getEInt();
				} else if ("String".equals(type.getName())) { //$NON-NLS-1$
					eClassifier = EcorePackage.eINSTANCE.getEString();
				} else if ("UnlimitedNatural".equals(type.getName())) { //$NON-NLS-1$
					eClassifier = EcorePackage.eINSTANCE.getEInt();
				} else if ("boolean".equals(type.getName())) { //$NON-NLS-1$
					eClassifier = EcorePackage.eINSTANCE.getEBoolean();
				} else if ("byte".equals(type.getName())) { //$NON-NLS-1$
					eClassifier = EcorePackage.eINSTANCE.getEByte();
				} else if ("char".equals(type.getName())) { //$NON-NLS-1$
					eClassifier = EcorePackage.eINSTANCE.getEChar();
				} else if ("double".equals(type.getName())) { //$NON-NLS-1$
					eClassifier = EcorePackage.eINSTANCE.getEDouble();
				} else if ("float".equals(type.getName())) { //$NON-NLS-1$
					eClassifier = EcorePackage.eINSTANCE.getEFloat();
				} else if ("int".equals(type.getName())) { //$NON-NLS-1$
					eClassifier = EcorePackage.eINSTANCE.getEInt();
				} else if ("long".equals(type.getName())) { //$NON-NLS-1$
					eClassifier = EcorePackage.eINSTANCE.getELong();
				} else if ("short".equals(type.getName())) { //$NON-NLS-1$
					eClassifier = EcorePackage.eINSTANCE.getEShort();
				} else if (EDataType.class.isInstance(EcorePackage.eINSTANCE
					.getEClassifier(type.getName()))) {

					eClassifier = EcorePackage.eINSTANCE.getEClassifier(type
						.getName());
				} else {
					eClassifier = EcorePackage.eINSTANCE.getEString();
				}
			} else {
				eClassifier = createEClassifier(ePackage, type);
			}
		}

		return eClassifier;
	}

	/**
	 * Creates an Ecore package to represent the specified profile.
	 * 
	 * @param profile
	 *            The profile for which to create an Ecore package.
	 * @return The new Ecore package.
	 */
	public static EPackage createEPackage(Profile profile) {
		EPackage ePackage = EcoreFactory.eINSTANCE.createEPackage();

		ePackage.setName(getEPackageName(profile));
		ePackage.setNsPrefix(ePackage.getName());
		ePackage.setNsURI("http:///" + EcoreUtil.generateUUID() + "." //$NON-NLS-1$ //$NON-NLS-2$
			+ UML2Resource.PROFILE_FILE_EXTENSION);

		for (Iterator ownedTypes = profile.getOwnedTypes().iterator(); ownedTypes
			.hasNext();) {

			createEClassifier(ePackage, (Type) ownedTypes.next());
		}

		return ePackage;
	}

	/**
	 * Creates an Ecore classifier in the specified Ecore package to represent
	 * the specified type; if such an Ecore classifier already exists, it is
	 * returned.
	 * 
	 * @param ePackage
	 *            The Ecore package in which to create the Ecore classifier.
	 * @param type
	 *            The type for which to create an Ecore classifier.
	 * @return The (new) Ecore classifier.
	 */
	protected static EClassifier createEClassifier(final EPackage ePackage,
			Type type) {

		return (EClassifier) new UML2Switch() {

			public Object caseClass(org.eclipse.uml2.Class class_) {
				return createEClass(ePackage, class_);
			}

			public Object caseEnumeration(Enumeration enumeration) {
				return createEEnum(ePackage, enumeration);
			}

			public Object caseInterface(Interface interface_) {
				return createEClass(ePackage, interface_);
			}

			public Object caseStereotype(Stereotype stereotype) {
				return createEClass(ePackage, stereotype);
			}
		}.doSwitch(type);
	}

	/**
	 * Creates an Ecore class in the specified Ecore package to represent the
	 * specified stereotype; if such an Ecore class already exists, it is
	 * returned.
	 * 
	 * @param ePackage
	 *            The Ecore package in which to create the Ecore class.
	 * @param stereotype
	 *            The stereotype for which to create an Ecore class.
	 * @return The (new) Ecore class.
	 */
	public static EClass createEClass(EPackage ePackage, Stereotype stereotype) {
		EClass eClass = (EClass) ePackage
			.getEClassifier(getEClassifierName(stereotype));

		if (null == eClass) {
			eClass = EcoreFactory.eINSTANCE.createEClass();

			createEAnnotation(
				StereotypeOperations.ANNOTATION_SOURCE__STEREOTYPE, eClass)
				.getReferences().add(stereotype);

			eClass.setName(getEClassifierName(stereotype));
			eClass.setAbstract(stereotype.isAbstract());

			ePackage.getEClassifiers().add(eClass);

			for (Iterator ownedAttributes = stereotype.getOwnedAttributes()
				.iterator(); ownedAttributes.hasNext();) {

				Property property = (Property) ownedAttributes.next();

				if (!isEmpty(property.getName())
					&& !Extension.class.isInstance(property.getAssociation())
					&& null != property.getType()) {

					if (DataType.class.isInstance(property.getType())) {
						createEAttribute(eClass, property);
					} else {
						createEReference(eClass, property);
					}
				}
			}

			for (Iterator generalizations = stereotype.getGeneralizations()
				.iterator(); generalizations.hasNext();) {

				Classifier general = ((Generalization) generalizations.next())
					.getGeneral();

				if (Stereotype.class.isInstance(general)) {
					eClass.getESuperTypes().add(
						createEClass(ePackage, (Stereotype) general));
				}
			}
		}

		return eClass;
	}

	/**
	 * Creates an Ecore class in the specified Ecore package to represent the
	 * specified class; if such an Ecore class already exists, it is returned.
	 * 
	 * @param ePackage
	 *            The Ecore package in which to create the Ecore class.
	 * @param class_
	 *            The class for which to create an Ecore class.
	 * @return The (new) Ecore class.
	 */
	public static EClass createEClass(EPackage ePackage,
			org.eclipse.uml2.Class class_) {
		EClass eClass = (EClass) ePackage
			.getEClassifier(getEClassifierName(class_));

		if (null == eClass) {
			eClass = EcoreFactory.eINSTANCE.createEClass();

			eClass.setName(getEClassifierName(class_));
			eClass.setAbstract(class_.isAbstract());

			ePackage.getEClassifiers().add(eClass);

			for (Iterator ownedAttributes = class_.getOwnedAttributes()
				.iterator(); ownedAttributes.hasNext();) {

				Property property = (Property) ownedAttributes.next();

				if (!isEmpty(property.getName()) && null != property.getType()) {

					if (DataType.class.isInstance(property.getType())) {
						createEAttribute(eClass, property);
					} else {
						createEReference(eClass, property);
					}
				}
			}

			for (Iterator generalizations = class_.getGeneralizations()
				.iterator(); generalizations.hasNext();) {

				Classifier general = ((Generalization) generalizations.next())
					.getGeneral();

				if (org.eclipse.uml2.Class.class.isInstance(general)) {
					eClass.getESuperTypes()
						.add(
							createEClass(ePackage,
								(org.eclipse.uml2.Class) general));
				}
			}

			for (Iterator implementations = class_.getImplementations()
				.iterator(); implementations.hasNext();) {

				Interface contract = ((Implementation) implementations.next())
					.getContract();

				if (null != contract) {
					eClass.getESuperTypes().add(
						createEClass(ePackage, contract));
				}
			}
		}

		return eClass;
	}

	/**
	 * Creates an Ecore class in the specified Ecore package to represent the
	 * specified interface; if such an Ecore class already exists, it is
	 * returned.
	 * 
	 * @param ePackage
	 *            The Ecore package in which to create the Ecore class.
	 * @param interface_
	 *            The interface for which to create an Ecore class.
	 * @return The (new) Ecore class.
	 */
	public static EClass createEClass(EPackage ePackage, Interface interface_) {
		EClass eClass = (EClass) ePackage
			.getEClassifier(getEClassifierName(interface_));

		if (null == eClass) {
			eClass = EcoreFactory.eINSTANCE.createEClass();

			eClass.setName(getEClassifierName(interface_));
			eClass.setAbstract(true);
			eClass.setInterface(true);

			ePackage.getEClassifiers().add(eClass);

			for (Iterator ownedAttributes = interface_.getOwnedAttributes()
				.iterator(); ownedAttributes.hasNext();) {

				Property property = (Property) ownedAttributes.next();

				if (!isEmpty(property.getName()) && null != property.getType()) {

					if (DataType.class.isInstance(property.getType())) {
						createEAttribute(eClass, property);
					} else {
						createEReference(eClass, property);
					}
				}
			}

			for (Iterator generalizations = interface_.getGeneralizations()
				.iterator(); generalizations.hasNext();) {

				Classifier general = ((Generalization) generalizations.next())
					.getGeneral();

				if (Interface.class.isInstance(general)) {
					eClass.getESuperTypes().add(
						createEClass(ePackage, (Interface) general));
				}
			}
		}

		return eClass;
	}

	/**
	 * Creates an Ecore enum in the specified Ecore package to represent the
	 * specified enumeration; if such an Ecore enum already exists, it is
	 * returned.
	 * 
	 * @param ePackage
	 *            The Ecore package in which to create the Ecore enum.
	 * @param enumeration
	 *            The enumeration for which to create an Ecore enum.
	 * @return The (new) Ecore enum.
	 */
	public static EEnum createEEnum(EPackage ePackage, Enumeration enumeration) {
		EEnum eEnum = (EEnum) ePackage
			.getEClassifier(getEClassifierName(enumeration));

		if (null == eEnum) {
			eEnum = EcoreFactory.eINSTANCE.createEEnum();

			eEnum.setName(getEClassifierName(enumeration));

			ePackage.getEClassifiers().add(eEnum);

			for (int index = 0; index < enumeration.getOwnedLiterals().size(); index++) {
				EnumerationLiteral enumerationLiteral = (EnumerationLiteral) enumeration
					.getOwnedLiterals().get(index);

				EEnumLiteral eEnumLiteral = EcoreFactory.eINSTANCE
					.createEEnumLiteral();

				createEAnnotation(
					StereotypeOperations.ANNOTATION_SOURCE__ENUMERATION_LITERAL,
					eEnumLiteral).getReferences().add(enumerationLiteral);

				eEnumLiteral.setName(getValidIdentifier(enumerationLiteral
					.getName()));
				eEnumLiteral.setValue(index);

				eEnum.getELiterals().add(eEnumLiteral);
			}
		}

		return eEnum;
	}

	/**
	 * Creates an Ecore attribute in the specified Ecore class to represent the
	 * specified property; if such an Ecore attribute already exists, it is
	 * returned.
	 * 
	 * @param eClass
	 *            The Ecore class in which to create the Ecore attribute.
	 * @param property
	 *            The property for which to create an Ecore attribute.
	 * @return The (new) Ecore attribute.
	 */
	public static EAttribute createEAttribute(EClass eClass, Property property) {
		EAttribute eAttribute = (EAttribute) eClass
			.getEStructuralFeature(property.getName());

		if (null == eAttribute) {
			eAttribute = EcoreFactory.eINSTANCE.createEAttribute();

			eAttribute.setName(getValidIdentifier(property.getName()));
			eAttribute.setChangeable(!property.isReadOnly());
			eAttribute.setUpperBound(property.getUpper());
			eAttribute.setLowerBound(property.getLower());
			eAttribute.setUnique(property.isUnique());
			eAttribute.setEType(getEClassifier(eClass.getEPackage(), property
				.getType()));

			if (InstanceValue.class.isInstance(property.getDefaultValue())
				&& EnumerationLiteral.class
					.isInstance(((InstanceValue) property.getDefaultValue())
						.getInstance())) {

				eAttribute
					.setDefaultValueLiteral(((EnumerationLiteral) ((InstanceValue) property
						.getDefaultValue()).getInstance()).getName());
			} else {

				try {
					EcorePackage.eINSTANCE.getEFactoryInstance()
						.createFromString(eAttribute.getEAttributeType(),
							property.getDefault());
					eAttribute.setDefaultValueLiteral(property.getDefault());
				} catch (Exception e) {
					// ignore
				}
			}

			eClass.getEStructuralFeatures().add(eAttribute);
		}

		return eAttribute;
	}

	/**
	 * Creates an Ecore reference in the specified Ecore class to represent the
	 * specified property; if such an Ecore reference already exists, it is
	 * returned.
	 * 
	 * @param eClass
	 *            The Ecore class in which to create the Ecore reference.
	 * @param property
	 *            The property for which to create an Ecore reference.
	 * @return The (new) Ecore reference.
	 */
	public static EReference createEReference(EClass eClass, Property property) {
		EReference eReference = (EReference) eClass
			.getEStructuralFeature(property.getName());

		if (null == eReference) {
			eReference = EcoreFactory.eINSTANCE.createEReference();

			eReference.setName(getValidIdentifier(property.getName()));
			eReference.setChangeable(true);
			eReference.setContainment(true);
			eReference.setUpperBound(property.getUpper());
			eReference.setLowerBound(property.getLower());
			eReference.setUnique(property.isUnique());
			eReference.setEType(getEClassifier(eClass.getEPackage(), property
				.getType()));

			eClass.getEStructuralFeatures().add(eReference);
		}

		return eReference;
	}

	/**
	 * Applies the current version of the specified profile to the specified
	 * package; if a different version is already applied, automatically
	 * migrates any associated stereotype values on a "best effort" basis
	 * (matching classifiers and structural features by name).
	 * 
	 * @param profile
	 *            The profile to be applied.
	 * @param package_
	 *            The package to which to apply the profile.
	 * @throws IllegalArgumentException
	 *             If the profile is not defined or its current version is
	 *             already applied.
	 */
	public static void apply(Profile profile, org.eclipse.uml2.Package package_) {

		if (null == profile
			|| null == getEPackage(profile, profile.getVersion())) {

			throw new IllegalArgumentException(String.valueOf(profile));
		}

		if (null == package_) {
			throw new IllegalArgumentException(String.valueOf(package_));
		}

		ProfileApplication profileApplication = null;

		for (Iterator allProfileApplications = getAllProfileApplications(
			package_).iterator(); allProfileApplications.hasNext();) {

			profileApplication = (ProfileApplication) allProfileApplications
				.next();

			Profile importedProfile = profileApplication.getImportedProfile();

			if (profile == importedProfile) {

				if (profile.getVersion().equals(getVersion(profileApplication))) {
					throw new IllegalArgumentException(String.valueOf(profile));
				}

				break;
			} else {
				EPackage importedEPackage = getEPackage(importedProfile,
					getVersion(profileApplication));

				if (null != importedEPackage
					&& getEPackage(profile, profile.getVersion()).getNsURI()
						.equals(importedEPackage.getNsURI())) {

					throw new IllegalArgumentException(String.valueOf(profile));
				}

				profileApplication = null;
			}
		}

		if (null == profileApplication) {
			profileApplication = (ProfileApplication) package_
				.createPackageImport(UML2Package.eINSTANCE
					.getProfileApplication());
			profileApplication.setImportedProfile(profile);

			package_.getAppliedProfiles().add(profileApplication);
		} else {

			if (package_ != profileApplication.getImportingNamespace()) {
				throw new IllegalArgumentException(String.valueOf(package_));
			}

			TreeIterator eAllContents = new AbstractTreeIterator(package_, true) {

				public Iterator getChildren(Object parent) {
					return ((EObject) parent).eContents().iterator();
				}
			};

			List eAnnotationsToRemove = new ArrayList();

			while (eAllContents.hasNext()) {
				EObject eObject = (EObject) eAllContents.next();

				if (Element.class.isInstance(eObject)) {
					Element element = (Element) eObject;
					EAnnotation appliedStereotypesEAnnotation = getEAnnotation(
						StereotypeOperations.ANNOTATION_SOURCE__APPLIED_STEREOTYPES,
						element);
					List appliedStereotypes = appliedStereotypesEAnnotation
						.getContents();

					for (Iterator stereotypeApplications = getStereotypeApplications(
						profile, element).iterator(); stereotypeApplications
						.hasNext();) {

						EObject oldStereotypeApplication = (EObject) stereotypeApplications
							.next();

						Stereotype stereotype = StereotypeOperations
							.getStereotype(oldStereotypeApplication);

						if (null == stereotype) {
							appliedStereotypes.remove(oldStereotypeApplication);
						} else {
							EClass eClass = StereotypeOperations.getEClass(
								stereotype, profile.getVersion());
							EObject newStereotypeApplication = eClass
								.getEPackage().getEFactoryInstance().create(
									eClass);

							copyValues(oldStereotypeApplication,
								newStereotypeApplication);

							appliedStereotypes.set(appliedStereotypes
								.indexOf(oldStereotypeApplication),
								newStereotypeApplication);
						}
					}

					if (appliedStereotypes.isEmpty()) {
						eAnnotationsToRemove.add(appliedStereotypesEAnnotation);
					}
				}
			}

			for (Iterator eAnnotations = eAnnotationsToRemove.iterator(); eAnnotations
				.hasNext();) {

				((EAnnotation) eAnnotations.next()).setEModelElement(null);
			}
		}

		getOrCreateEAnnotation(ANNOTATION_SOURCE__ATTRIBUTES,
			profileApplication).getDetails().put(
			ANNOTATION_DETAILS_KEY__VERSION, profile.getVersion());
	}

	protected static void copyValues(EObject sourceEObject,
			EObject targetEObject) {

		for (Iterator targetEStructuralFeatures = targetEObject.eClass()
			.getEAllStructuralFeatures().iterator(); targetEStructuralFeatures
			.hasNext();) {

			EStructuralFeature targetEStructuralFeature = (EStructuralFeature) targetEStructuralFeatures
				.next();

			EStructuralFeature sourceEStructuralFeature = sourceEObject
				.eClass().getEStructuralFeature(
					targetEStructuralFeature.getName());

			if (null != sourceEStructuralFeature
				&& sourceEObject.eIsSet(sourceEStructuralFeature)) {

				try {
					switch (targetEStructuralFeature.getEType().eClass()
						.getClassifierID()) {

						case EcorePackage.ECLASS :
							copyEClassValue(sourceEObject,
								sourceEStructuralFeature, targetEObject,
								targetEStructuralFeature);

							break;
						case EcorePackage.EDATA_TYPE :
							copyEDataTypeValue(sourceEObject,
								sourceEStructuralFeature, targetEObject,
								targetEStructuralFeature);

							break;
						case EcorePackage.EENUM :
							copyEEnumValue(sourceEObject,
								sourceEStructuralFeature, targetEObject,
								targetEStructuralFeature);

							break;
					}
				} catch (Exception e) {
					System.err.println(e);
				}
			}
		}
	}

	protected static void copyEClassValue(EObject sourceEObject,
			EStructuralFeature sourceEStructuralFeature, EObject targetEObject,
			EStructuralFeature targetEStructuralFeature) {
		Object sourceValue = sourceEObject.eGet(sourceEStructuralFeature);

		EClass targetEClass = (EClass) targetEStructuralFeature.getEType();

		if (targetEStructuralFeature.isMany()) {
			EList targetEList = (EList) targetEObject
				.eGet(targetEStructuralFeature);

			if (sourceEStructuralFeature.isMany()) {
				EList sourceEList = (EList) sourceValue;

				for (int i = 0; i < sourceEList.size(); i++) {
					EObject targetValue = targetEClass.getEPackage()
						.getEFactoryInstance().create(targetEClass);
					copyValues((EObject) sourceEList.get(i), targetValue);
					targetEList.add(i, targetValue);
				}
			} else {
				EObject targetValue = targetEClass.getEPackage()
					.getEFactoryInstance().create(targetEClass);
				copyValues((EObject) sourceValue, targetValue);
				targetEList.add(targetValue);
			}
		} else {
			EObject targetValue = targetEClass.getEPackage()
				.getEFactoryInstance().create(targetEClass);
			copyValues((EObject) (sourceEStructuralFeature.isMany()
				? ((EList) sourceValue).get(0)
				: sourceValue), targetValue);
			targetEObject.eSet(targetEStructuralFeature, targetValue);
		}
	}

	protected static void copyEDataTypeValue(EObject sourceEObject,
			EStructuralFeature sourceEStructuralFeature, EObject targetEObject,
			EStructuralFeature targetEStructuralFeature) {
		Object sourceValue = sourceEObject.eGet(sourceEStructuralFeature);

		EDataType sourceEDataType = (EDataType) sourceEStructuralFeature
			.getEType();
		EFactory sourceEFactory = sourceEDataType.getEPackage()
			.getEFactoryInstance();
		EDataType targetEDataType = (EDataType) targetEStructuralFeature
			.getEType();
		EFactory targetEFactory = targetEDataType.getEPackage()
			.getEFactoryInstance();

		if (targetEStructuralFeature.isMany()) {
			EList targetEList = (EList) targetEObject
				.eGet(targetEStructuralFeature);

			if (sourceEStructuralFeature.isMany()) {
				EList sourceEList = (EList) sourceValue;

				for (int i = 0; i < sourceEList.size(); i++) {
					targetEList.add(i, targetEFactory.createFromString(
						targetEDataType, sourceEFactory.convertToString(
							sourceEDataType, sourceEList.get(i))));
				}
			} else {
				targetEList.add(targetEFactory.createFromString(
					targetEDataType, sourceEFactory.convertToString(
						sourceEDataType, sourceValue)));
			}
		} else {
			targetEObject.eSet(targetEStructuralFeature, targetEFactory
				.createFromString(targetEDataType, sourceEFactory
					.convertToString(sourceEDataType, sourceEStructuralFeature
						.isMany()
						? ((EList) sourceValue).get(0)
						: sourceValue)));
		}
	}

	protected static void copyEEnumValue(EObject sourceEObject,
			EStructuralFeature sourceEStructuralFeature, EObject targetEObject,
			EStructuralFeature targetEStructuralFeature) {
		Object sourceValue = sourceEObject.eGet(sourceEStructuralFeature);

		EEnum targetEEnum = (EEnum) targetEStructuralFeature.getEType();

		if (targetEStructuralFeature.isMany()) {
			EList targetEList = (EList) targetEObject
				.eGet(targetEStructuralFeature);

			if (sourceEStructuralFeature.isMany()) {
				EList sourceEList = (EList) sourceValue;

				for (int i = 0; i < sourceEList.size(); i++) {
					targetEList.add(i, targetEEnum.getEEnumLiteral(
						((EEnumLiteral) sourceEList.get(i)).getName())
						.getInstance());
				}
			} else {
				targetEList.add(targetEEnum.getEEnumLiteral(
					((EEnumLiteral) sourceValue).getName()).getInstance());
			}
		} else {
			targetEObject.eSet(targetEStructuralFeature, targetEEnum
				.getEEnumLiteral(
					((EEnumLiteral) (sourceEStructuralFeature.isMany()
						? ((EList) sourceValue).get(0)
						: sourceValue)).getName()).getInstance());
		}
	}

	/**
	 * Defines the specified profile by (re)creating Ecore representations of
	 * its current contents and incrementing its version.
	 * 
	 * @param profile
	 *            The profile to be defined.
	 * @throws IllegalArgumentException
	 *             If the profile has no qualified name.
	 */
	public static void define(Profile profile) {

		if (null == profile || isEmpty(profile.getQualifiedName())) {
			throw new IllegalArgumentException(String.valueOf(profile));
		}

		String version = getVersion(profile);
		getOrCreateEAnnotation(ANNOTATION_SOURCE__ATTRIBUTES, profile)
			.getDetails().put(ANNOTATION_DETAILS_KEY__VERSION, null == version
				? String.valueOf(0)
				: String.valueOf(new Integer(Integer.parseInt(version) + 1)));

		getOrCreateEAnnotation(ANNOTATION_SOURCE__E_PACKAGES, profile)
			.getContents().add(0, createEPackage(profile));
	}

	/**
	 * Retrieves the set of all profile applications on the specified package,
	 * including profiles applications on its nesting package(s).
	 * 
	 * @param package_
	 *            The package for which to retrieve the profile applications.
	 * @return The profile applications on the package.
	 */
	protected static Set getAllProfileApplications(
			org.eclipse.uml2.Package package_) {
		Set allProfileApplications = new HashSet();

		while (null != package_) {
			allProfileApplications.addAll(package_.getAppliedProfiles());

			EObject eContainer = package_.eContainer();

			package_ = Element.class.isInstance(eContainer)
				? ((Element) eContainer).getNearestPackage()
				: null;
		}

		return allProfileApplications;
	}

	/**
	 * Retrieves the set of all profiles that are applied to the specified
	 * package, including profiles applied to its nesting package(s).
	 * 
	 * @param package_
	 *            The package for which to retrieve the applied profiles.
	 * @return The profiles applied to the package.
	 */
	public static Set getAllAppliedProfiles(org.eclipse.uml2.Package package_) {
		Set allAppliedProfiles = new HashSet();

		if (null == package_) {
			return allAppliedProfiles;
		}

		for (Iterator appliedProfiles = package_.getAppliedProfiles()
			.iterator(); appliedProfiles.hasNext();) {

			ProfileApplication profileApplication = (ProfileApplication) appliedProfiles
				.next();

			if (null != profileApplication.getImportedProfile()) {
				allAppliedProfiles.add(profileApplication.getImportedProfile());
			}
		}

		EObject eContainer = package_.eContainer();

		if (Element.class.isInstance(eContainer)) {
			allAppliedProfiles
				.addAll(getAllAppliedProfiles(((Element) eContainer)
					.getNearestPackage()));
		}

		return allAppliedProfiles;
	}

	/**
	 * Retrieves the version of the specified profile.
	 * 
	 * @param profile
	 *            The profile whose version is to be retrieved.
	 * @return The version of the profile, or <code>null</code> if undefined.
	 */
	public static String getVersion(Profile profile) {

		if (null == profile) {
			return null;
		}

		return (String) getEAnnotation(ANNOTATION_SOURCE__ATTRIBUTES, profile)
			.getDetails().get(ANNOTATION_DETAILS_KEY__VERSION);
	}

	/**
	 * Retrieves the version of the specified profile that is applied to the
	 * specified package or (one of) its nesting package(s).
	 * 
	 * @param profile
	 *            The profile whose applied version to retrieve.
	 * @param package_
	 *            The package for which to retrieve the profile version.
	 * @return The version of the profile, or <code>null</code> if not
	 *         applied.
	 */
	public static String getAppliedVersion(Profile profile,
			org.eclipse.uml2.Package package_) {

		if (null == profile || null == package_) {
			return null;
		}

		ProfileApplication profileApplication = getProfileApplication(profile,
			package_);

		if (null != profileApplication) {
			return getVersion(profileApplication);
		}

		EObject eContainer = package_.eContainer();

		if (Element.class.isInstance(eContainer)) {
			return getAppliedVersion(profile, ((Element) eContainer)
				.getNearestPackage());
		}

		return null;
	}

	protected static String getVersion(ProfileApplication profileApplication) {
		return (String) getEAnnotation(ANNOTATION_SOURCE__ATTRIBUTES,
			profileApplication).getDetails().get(
			ANNOTATION_DETAILS_KEY__VERSION);
	}

	protected static ProfileApplication getProfileApplication(Profile profile,
			org.eclipse.uml2.Package package_) {

		for (Iterator appliedProfiles = package_.getAppliedProfiles()
			.iterator(); appliedProfiles.hasNext();) {

			ProfileApplication profileApplication = (ProfileApplication) appliedProfiles
				.next();

			if (profile == profileApplication.getImportedProfile()) {
				return profileApplication;
			}
		}

		return null;
	}

	protected static Set getStereotypeApplications(Profile profile,
			Element element) {
		Set stereotypeApplications = new HashSet();

		List ePackages = getEAnnotation(ANNOTATION_SOURCE__E_PACKAGES, profile)
			.getContents();

		for (Iterator appliedStereotypes = getEAnnotation(
			StereotypeOperations.ANNOTATION_SOURCE__APPLIED_STEREOTYPES,
			element).getContents().iterator(); appliedStereotypes.hasNext();) {

			EObject stereotypeApplication = (EObject) appliedStereotypes.next();

			if (ePackages
				.contains(stereotypeApplication.eClass().getEPackage())) {

				stereotypeApplications.add(stereotypeApplication);
			}
		}

		return stereotypeApplications;
	}

	/**
	 * Determines whether the specified profile is applied to the specified
	 * package.
	 * 
	 * @param profile
	 *            The profile to test for application.
	 * @param package_
	 *            The package for which to determine profile application.
	 * @return <code>true</code> if the profile is applied to the package;
	 *         <code>false</code> otherwise.
	 */
	public static boolean isApplied(Profile profile,
			org.eclipse.uml2.Package package_) {

		if (null == profile || !isDefined(profile)) {
			return false;
		}

		if (null == package_) {
			return false;
		}

		return null != getProfileApplication(profile, package_);
	}

	/**
	 * Determines whether the specified profile is defined.
	 * 
	 * @param profile
	 *            The profile to test for definition.
	 * @return <code>true</code> if the profile is defined; <code>false</code>
	 *         otherwise.
	 */
	public static boolean isDefined(Profile profile) {
		return null == profile
			? false
			: getEAnnotation(ANNOTATION_SOURCE__E_PACKAGES, profile)
				.getContents().size() > 0;
	}

	/**
	 * Unapplies the specified profile from the specified package.
	 * 
	 * @param profile
	 *            The profile to be unapplied.
	 * @param package_
	 *            The package from which to unapply the profile.
	 * @throws IllegalArgumentException
	 *             If the profile is not applied to the package.
	 */
	public static void unapply(Profile profile,
			org.eclipse.uml2.Package package_) {

		if (null == profile || !isApplied(profile, package_)) {
			throw new IllegalArgumentException(String.valueOf(profile));
		}

		TreeIterator eAllContents = new AbstractTreeIterator(package_, true) {

			public Iterator getChildren(Object parent) {
				return ((EObject) parent).eContents().iterator();
			}
		};

		List eAnnotationsToRemove = new ArrayList();

		while (eAllContents.hasNext()) {
			EObject eObject = (EObject) eAllContents.next();

			if (Element.class.isInstance(eObject)) {
				Element element = (Element) eObject;

				EAnnotation appliedStereotypesEAnnotation = getEAnnotation(
					StereotypeOperations.ANNOTATION_SOURCE__APPLIED_STEREOTYPES,
					element);

				appliedStereotypesEAnnotation.getContents().removeAll(
					getStereotypeApplications(profile, element));

				if (appliedStereotypesEAnnotation.getContents().isEmpty()) {
					eAnnotationsToRemove.add(appliedStereotypesEAnnotation);
				}
			}
		}

		for (Iterator eAnnotations = eAnnotationsToRemove.iterator(); eAnnotations
			.hasNext();) {

			((EAnnotation) eAnnotations.next()).setEModelElement(null);
		}

		package_.getPackageImports().remove(
			getProfileApplication(profile, package_));
	}

	/**
	 * Retrieves the set of metaclasses referenced by the specified profile.
	 * 
	 * @param profile
	 *            The profile for which to retrieve referenced metaclasses.
	 * @return The metaclasses referenced by the profile.
	 */
	public static Set getReferencedMetaclasses(Profile profile) {
		Set referencedMetaclasses = new HashSet();

		if (null == profile) {
			return referencedMetaclasses;
		}

		for (Iterator metaclassReferences = profile.getMetaclassReferences()
			.iterator(); metaclassReferences.hasNext();) {

			referencedMetaclasses.add(((ElementImport) metaclassReferences
				.next()).getImportedElement());
		}

		return referencedMetaclasses;
	}

	/**
	 * References the specified metaclass in the specified profile with private
	 * visibility.
	 * 
	 * @param profile
	 *            The profile in which to reference the metaclass.
	 * @param class_
	 *            The metaclass to reference.
	 * @exception IllegalArgumentException
	 *                If the profile already references the metaclass.
	 */
	public static void referenceMetaclass(Profile profile,
			org.eclipse.uml2.Class class_) {

		if (null == profile) {
			throw new IllegalArgumentException(String.valueOf(profile));
		}

		if (null == class_
			|| profile.getReferencedMetaclasses().contains(class_)) {

			throw new IllegalArgumentException(String.valueOf(class_));
		}

		ElementImport elementImport = profile
			.createElementImport(UML2Package.eINSTANCE.getElementImport());

		elementImport.setVisibility(VisibilityKind.PRIVATE_LITERAL);
		elementImport.setImportedElement(class_);

		profile.getMetaclassReferences().add(elementImport);
	}

	/**
	 * Retrieves the set of metamodels referenced by the specified profile.
	 * 
	 * @param profile
	 *            The profile for which to retrieve referenced metamodels.
	 * @return The metamodels referenced by the profile.
	 */
	public static Set getReferencedMetamodels(Profile profile) {
		Set referencedMetamodels = new HashSet();

		if (null == profile) {
			return referencedMetamodels;
		}

		for (Iterator metamodelReferences = profile.getMetamodelReferences()
			.iterator(); metamodelReferences.hasNext();) {

			referencedMetamodels.add(((PackageImport) metamodelReferences
				.next()).getImportedPackage());
		}

		return referencedMetamodels;
	}

	/**
	 * References the specified metamodel in the specified profile with private
	 * visibility.
	 * 
	 * @param profile
	 *            The profile in which to reference the metamodel.
	 * @param model
	 *            The metamodel to reference.
	 * @exception IllegalArgumentException
	 *                If the profile already references the metamodel.
	 */
	public static void referenceMetamodel(Profile profile, Model model) {

		if (null == profile) {
			throw new IllegalArgumentException(String.valueOf(profile));
		}

		if (null == model || profile.getReferencedMetamodels().contains(model)) {
			throw new IllegalArgumentException(String.valueOf(model));
		}

		PackageImport packageImport = profile
			.createPackageImport(UML2Package.eINSTANCE.getPackageImport());

		packageImport.setVisibility(VisibilityKind.PRIVATE_LITERAL);
		packageImport.setImportedPackage(model);

		profile.getMetamodelReferences().add(packageImport);
	}

	/**
	 * Creates and returns an instance of (the Ecore representation of) the
	 * specified classifier defined in the specified profile.
	 * 
	 * @param profile
	 *            The profile in which the classifier is defined.
	 * @param classifier
	 *            The classifier whose Ecore representation is to be
	 *            instantiated.
	 * @return An (Ecore) instance of the classifier.
	 * @exception IllegalArgumentException
	 *                If the classifier is not defined in the profile or cannot
	 *                be instantiated.
	 */
	public static EObject create(final Profile profile, Classifier classifier) {
		final EPackage ePackage = getEPackage(profile, getVersion(profile));

		if (null == ePackage) {
			throw new IllegalArgumentException(String.valueOf(profile));
		}

		if (null == classifier || !profile.getOwnedTypes().contains(classifier)) {
			throw new IllegalArgumentException(String.valueOf(classifier));
		}

		return (EObject) new UML2Switch() {

			public Object caseClass(org.eclipse.uml2.Class class_) {

				if (!class_.isAbstract()) {
					EClass eClass = (EClass) ePackage
						.getEClassifier(getEClassifierName(class_));

					if (null != eClass) {
						return ePackage.getEFactoryInstance().create(eClass);
					}
				}

				return null;
			}

			public Object caseClassifier(Classifier classifier) {
				throw new IllegalArgumentException(String.valueOf(classifier));
			}

			public Object caseStereotype(Stereotype stereotype) {
				throw new IllegalArgumentException(String.valueOf(stereotype));
			}
		}.doSwitch(classifier);
	}

}