/*
 * Copyright (c) 2005, 2006 IBM Corporation 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:
 *   IBM - initial API and implementation
 *
 * $Id: UMLUtil.java,v 1.43 2006/12/14 15:49:34 khussey Exp $
 */
package org.eclipse.uml2.uml.util;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;

import org.eclipse.emf.common.util.BasicDiagnostic;
import org.eclipse.emf.common.util.BasicEMap;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.DiagnosticChain;
import org.eclipse.emf.common.util.ECollections;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.EMap;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.common.util.UniqueEList;
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.EGenericType;
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.ETypedElement;
import org.eclipse.emf.ecore.EcoreFactory;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EcoreSwitch;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.util.ExtendedMetaData;
import org.eclipse.emf.ecore.util.InternalEList;
import org.eclipse.emf.ecore.xml.type.XMLTypePackage;
import org.eclipse.uml2.common.util.CacheAdapter;
import org.eclipse.uml2.common.util.UML2Util;
import org.eclipse.uml2.uml.AggregationKind;
import org.eclipse.uml2.uml.Artifact;
import org.eclipse.uml2.uml.Association;
import org.eclipse.uml2.uml.BehavioredClassifier;
import org.eclipse.uml2.uml.Classifier;
import org.eclipse.uml2.uml.Comment;
import org.eclipse.uml2.uml.Constraint;
import org.eclipse.uml2.uml.DataType;
import org.eclipse.uml2.uml.DirectedRelationship;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.Enumeration;
import org.eclipse.uml2.uml.EnumerationLiteral;
import org.eclipse.uml2.uml.Extension;
import org.eclipse.uml2.uml.Feature;
import org.eclipse.uml2.uml.Generalization;
import org.eclipse.uml2.uml.Interface;
import org.eclipse.uml2.uml.InterfaceRealization;
import org.eclipse.uml2.uml.LiteralInteger;
import org.eclipse.uml2.uml.LiteralUnlimitedNatural;
import org.eclipse.uml2.uml.Model;
import org.eclipse.uml2.uml.MultiplicityElement;
import org.eclipse.uml2.uml.NamedElement;
import org.eclipse.uml2.uml.Namespace;
import org.eclipse.uml2.uml.Operation;
import org.eclipse.uml2.uml.PackageMerge;
import org.eclipse.uml2.uml.Parameter;
import org.eclipse.uml2.uml.ParameterDirectionKind;
import org.eclipse.uml2.uml.PrimitiveType;
import org.eclipse.uml2.uml.Profile;
import org.eclipse.uml2.uml.Property;
import org.eclipse.uml2.uml.RedefinableElement;
import org.eclipse.uml2.uml.Signal;
import org.eclipse.uml2.uml.Stereotype;
import org.eclipse.uml2.uml.StructuralFeature;
import org.eclipse.uml2.uml.StructuredClassifier;
import org.eclipse.uml2.uml.Type;
import org.eclipse.uml2.uml.TypedElement;
import org.eclipse.uml2.uml.UMLFactory;
import org.eclipse.uml2.uml.UMLPackage;
import org.eclipse.uml2.uml.UMLPlugin;
import org.eclipse.uml2.uml.ValueSpecification;
import org.eclipse.uml2.uml.VisibilityKind;
import org.eclipse.uml2.uml.resource.UMLResource;

/**
 * Utilities for working with UML elements and resources.
 * 
 * @since 2.0
 */
public class UMLUtil
		extends UML2Util {

	/**
	 * A qualified text provider that uses names of named elements as qualified
	 * text segments and :: as a separator.
	 */
	public static class QualifiedTextProvider
			extends UML2Util.QualifiedTextProvider {

		/**
		 * The default instance.
		 */
		public static final QualifiedTextProvider DEFAULT = new QualifiedTextProvider();

		@Override
		public String getText(EObject eObject) {

			return eObject instanceof NamedElement
				? ((NamedElement) eObject).getName()
				: super.getText(eObject);
		}

		@Override
		public String getSeparator() {
			return NamedElement.SEPARATOR;
		}

	}

	/**
	 * A copier that merges the contents of packages involved in package merge
	 * relationships based on the rules defined in the UML specification.
	 */
	public static class PackageMerger
			extends EcoreUtil.Copier {

		private static final long serialVersionUID = 1L;

		protected class BodyMatcher
				extends EStructuralFeatureMatcher {

			protected BodyMatcher(Comment comment) {
				super(comment, UMLPackage.Literals.COMMENT__BODY);
			}
		}

		protected class NameMatcher
				extends EStructuralFeatureMatcher {

			protected NameMatcher(NamedElement namedElement) {
				super(namedElement, UMLPackage.Literals.NAMED_ELEMENT__NAME);
			}
		}

		protected class KeyMatcher
				extends EClassMatcher {

			protected KeyMatcher(BasicEMap.Entry<String, String> entry) {
				super((EObject) entry);
			}

			@Override
			public boolean matches(EObject otherEObject) {
				return super.matches(otherEObject)
					&& safeEquals(((BasicEMap.Entry) eObject).getKey(),
						((BasicEMap.Entry) otherEObject).getKey());
			}
		}

		protected class ResultingQNameMatcher
				extends EClassMatcher {

			protected ResultingQNameMatcher(EObject eObject) {
				super(eObject);
			}

			@Override
			public boolean matches(EObject otherEObject) {
				return super.matches(otherEObject)
					&& safeEquals(getResultingQName(eObject),
						getResultingQName(otherEObject));
			}
		}

		protected class StringValueMatcher
				extends EClassMatcher {

			protected StringValueMatcher(ValueSpecification valueSpecification) {
				super(valueSpecification);
			}

			@Override
			public boolean matches(EObject otherEObject) {
				return super.matches(otherEObject)
					&& safeEquals(((ValueSpecification) eObject).stringValue(),
						((ValueSpecification) otherEObject).stringValue());
			}
		}

		protected class SourceMatcher
				extends EStructuralFeatureMatcher {

			protected SourceMatcher(EAnnotation eAnnotation) {
				super(eAnnotation, EcorePackage.Literals.EANNOTATION__SOURCE);
			}
		}

		protected class TypeMatcher
				extends NameMatcher {

			protected TypeMatcher(TypedElement typedElement) {
				super(typedElement);
			}

			@Override
			public boolean matches(EObject otherEObject) {

				if (super.matches(otherEObject)) {
					Type type = ((TypedElement) eObject).getType();
					Type otherType = ((TypedElement) otherEObject).getType();

					return new ResultingQNameMatcher(type).matches(otherType)
						|| (type instanceof Classifier
							&& otherType instanceof Classifier && (findEObject(
							((Classifier) type).allParents(),
							new ResultingQNameMatcher(otherType)) != null || findEObject(
							((Classifier) otherType).allParents(),
							new ResultingQNameMatcher(type)) != null));
				}

				return false;
			}
		}

		private static final boolean DEBUG = false;

		/**
		 * The option for handling cases where the staticity of merged
		 * properties does not match. Supported choices are
		 * <code>OPTION__IGNORE</code> and <code>OPTION__REPORT</code>.
		 */
		public static final String OPTION__DIFFERENT_PROPERTY_STATICITY = "DIFFERENT_PROPERTY_STATICITY"; //$NON-NLS-1$

		/**
		 * The option for handling cases where the uniqueness of merged
		 * properties does not match. Supported choices are
		 * <code>OPTION__IGNORE</code> and <code>OPTION__REPORT</code>.
		 */
		public static final String OPTION__DIFFERENT_PROPERTY_UNIQUENESS = "DIFFERENT_PROPERTY_UNIQUENESS"; //$NON-NLS-1$

		/**
		 * The option for handling cases where a redundant generalization is
		 * detected. Supported choices are <code>OPTION__IGNORE</code>,
		 * <code>OPTION__REPORT</code>, and <code>OPTION__DISCARD</code>.
		 */
		public static final String OPTION__REDUNDANT_GENERALIZATIONS = "REDUNDANT_GENERALIZATIONS"; //$NON-NLS-1$

		/**
		 * The option for handling cases where an implicit redefinition is
		 * detected. Supported choices are <code>OPTION__IGNORE</code>,
		 * <code>OPTION__REPORT</code>, and <code>OPTION__PROCESS</code>.
		 */
		public static final String OPTION__IMPLICIT_REDEFINITIONS = "IMPLICIT_REDEFINITIONS"; //$NON-NLS-1$

		/**
		 * The option for handling cases where an invalid redefinition is
		 * detected. Supported choices are <code>OPTION__IGNORE</code>,
		 * <code>OPTION__REPORT</code>, <code>OPTION__DISCARD</code>, and
		 * <code>OPTION__PROCESS</code>.
		 */
		public static final String OPTION__INVALID_REDEFINITIONS = "INVALID_REDEFINITIONS"; //$NON-NLS-1$

		/**
		 * The option for handling cases where an invalid subset is detected.
		 * Supported choices are <code>OPTION__IGNORE</code>,
		 * <code>OPTION__REPORT</code>, <code>OPTION__DISCARD</code>, and
		 * <code>OPTION__PROCESS</code>.
		 */
		public static final String OPTION__INVALID_SUBSETS = "INVALID_SUBSETS"; //$NON-NLS-1$

		/**
		 * The option for handling cases where an empty union is detected.
		 * Supported choices are <code>OPTION__IGNORE</code>,
		 * <code>OPTION__REPORT</code>, and <code>OPTION__PROCESS</code>.
		 */
		public static final String OPTION__EMPTY_UNIONS = "EMPTY_UNIONS"; //$NON-NLS-1$

		/**
		 * The option for handling cases where an association specialization is
		 * missing. Supported choices are <code>OPTION__IGNORE</code>,
		 * <code>OPTION__REPORT</code>, and <code>OPTION__PROCESS</code>.
		 */
		public static final String OPTION__ASSOCIATION_SPECIALIZATIONS = "ASSOCIATION_SPECIALIZATIONS"; //$NON-NLS-1$

		/**
		 * The option for handling cases where capability information is
		 * missing. Supported choices are <code>OPTION__IGNORE</code>,
		 * <code>OPTION__REPORT</code>, and <code>OPTION__PROCESS</code>.
		 */
		public static final String OPTION__CAPABILITIES = "CAPABILITIES"; //$NON-NLS-1$

		private static final int DIAGNOSTIC_CODE_OFFSET = 1000;

		/**
		 * The diagnostic code for cases where the staticity of merged
		 * properties does not match.
		 */
		public static final int DIFFERENT_PROPERTY_STATICITY = DIAGNOSTIC_CODE_OFFSET + 1;

		/**
		 * The diagnostic code for cases where the uniqueness of merged
		 * properties does not match.
		 */
		public static final int DIFFERENT_PROPERTY_UNIQUENESS = DIAGNOSTIC_CODE_OFFSET + 2;

		/**
		 * The diagnostic code for cases where a redundant generalization is
		 * detected.
		 */
		public static final int REDUNDANT_GENERALIZATION = DIAGNOSTIC_CODE_OFFSET + 3;

		/**
		 * The diagnostic code for cases where an implicit redefinition is
		 * detected.
		 */
		public static final int IMPLICIT_REDEFINITION = DIAGNOSTIC_CODE_OFFSET + 4;

		/**
		 * The diagnostic code for cases where an invalid redefinition is
		 * detected.
		 */
		public static final int INVALID_REDEFINITION = DIAGNOSTIC_CODE_OFFSET + 5;

		/**
		 * The diagnostic code for cases where an invalid subset is detected.
		 */
		public static final int INVALID_SUBSET = DIAGNOSTIC_CODE_OFFSET + 6;

		/**
		 * The diagnostic code for cases where an empty union is detected.
		 */
		public static final int EMPTY_UNION = DIAGNOSTIC_CODE_OFFSET + 7;

		/**
		 * The diagnostic code for cases where an association specialization is
		 * missing.
		 */
		public static final int ASSOCIATION_SPECIALIZATION = DIAGNOSTIC_CODE_OFFSET + 8;

		/**
		 * The diagnostic code for cases where capability information is
		 * missing.
		 */
		public static final int CAPABILITY = DIAGNOSTIC_CODE_OFFSET + 9;

		protected org.eclipse.uml2.uml.Package receivingPackage = null;

		protected Collection<org.eclipse.uml2.uml.Package> mergedPackages = null;

		protected final Map<EObject, List<EObject>> resultingToMergedEObjectMap = new LinkedHashMap<EObject, List<EObject>>();

		private final Map<EObject, EObject> copierMap = new LinkedHashMap<EObject, EObject>();

		@Override
		public void clear() {
			copierMap.clear();
		}

		@Override
		public boolean containsKey(Object key) {
			return copierMap.containsKey(key);
		}

		@Override
		public boolean containsValue(Object value) {
			return copierMap.containsValue(value);
		}

		@Override
		public Set<Map.Entry<EObject, EObject>> entrySet() {
			return copierMap.entrySet();
		}

		@Override
		public EObject get(Object key) {
			return copierMap.get(key);
		}

		@Override
		public boolean isEmpty() {
			return copierMap.isEmpty();
		}

		@Override
		public Set<EObject> keySet() {
			return copierMap.keySet();
		}

		@Override
		public EObject put(EObject key, EObject value) {
			return copierMap.put(key, value);
		}

		@Override
		public void putAll(Map<? extends EObject, ? extends EObject> t) {
			copierMap.putAll(t);
		}

		@Override
		public EObject remove(Object key) {
			return copierMap.remove(key);
		}

		@Override
		public int size() {
			return copierMap.size();
		}

		@Override
		public Collection<EObject> values() {
			return copierMap.values();
		}

		protected <EO extends EObject> List<EO> getMatchCandidates(EO eObject) {
			Element baseElement = getBaseElement(eObject);

			if (baseElement == null) {
				EStructuralFeature eContainingFeature = eObject
					.eContainingFeature();

				if (eContainingFeature.isMany()) {
					@SuppressWarnings("unchecked")
					List<EO> values = (List<EO>) get(eObject.eContainer())
						.eGet(eContainingFeature);
					return values;
				} else {
					@SuppressWarnings("unchecked")
					EO value = (EO) get(eObject.eContainer()).eGet(
						eContainingFeature);
					return Collections.<EO> singletonList(value);
				}
			} else {
				@SuppressWarnings("unchecked")
				List<EO> stereotypeApplications = (List<EO>) ((Element) get(baseElement))
					.getStereotypeApplications();
				return stereotypeApplications;
			}
		}

		protected <EO extends EObject> List<EO> getMergedEObjects(
				EO resultingEObject) {
			@SuppressWarnings("unchecked")
			List<EO> mergedEObjects = (List<EO>) resultingToMergedEObjectMap
				.get(resultingEObject);

			return mergedEObjects == null
				? Collections.<EO> singletonList(resultingEObject)
				: (List<EO>) mergedEObjects;
		}

		protected <EO extends EObject> EO getPreviouslyMergedEObject(
				EO resultingEObject) {
			List<EO> mergedEObjects = getMergedEObjects(resultingEObject);
			return mergedEObjects.get(mergedEObjects.size() - 1);
		}

		protected String getResultingQName(EObject eObject) {
			StringBuffer resultingQName = appendResultingQName(
				new StringBuffer(), eObject, QualifiedTextProvider.DEFAULT);

			return resultingQName.toString();
		}

		private StringBuffer appendResultingQName(StringBuffer resultingQName,
				EObject eObject, QualifiedTextProvider qualifiedTextProvider) {
			eObject = mergedPackages.contains(eObject)
				? receivingPackage
				: eObject;

			EObject eContainer = eObject.eContainer();

			if (eContainer != null) {
				appendResultingQName(resultingQName, eContainer,
					qualifiedTextProvider);

				if (resultingQName.length() > 0) {
					resultingQName.append(qualifiedTextProvider.getSeparator());
				}
			}

			return getQualifiedTextSegment(eObject, qualifiedTextProvider,
				resultingQName);
		}

		protected void mergeAssociation_IsDerived(
				Association receivingAssociation, Association mergedAssociation) {
			receivingAssociation.setIsDerived(receivingAssociation.isDerived()
				|| mergedAssociation.isDerived());
		}

		protected void mergeClassifier_IsAbstract(
				Classifier receivingClassifier, Classifier mergedClassifier) {
			receivingClassifier.setIsAbstract(receivingClassifier.isAbstract()
				&& mergedClassifier.isAbstract());
		}

		protected void mergeLiteralInteger_Value(
				LiteralInteger receivingLiteralInteger,
				LiteralInteger mergedLiteralInteger) {
			receivingLiteralInteger.setValue(getLesserLowerBound(
				receivingLiteralInteger.getValue(), mergedLiteralInteger
					.getValue()));
		}

		protected void mergeLiteralUnlimitedNatural_Value(
				LiteralUnlimitedNatural receivingLiteralUnlimitedNatural,
				LiteralUnlimitedNatural mergedLiteralUnlimitedNatural) {
			receivingLiteralUnlimitedNatural.setValue(getGreaterUpperBound(
				receivingLiteralUnlimitedNatural.getValue(),
				mergedLiteralUnlimitedNatural.getValue()));
		}

		protected void mergeMultiplicityElement_IsOrdered(
				MultiplicityElement receivingMultiplicityElement,
				MultiplicityElement mergedMultiplicityElement) {
			receivingMultiplicityElement
				.setIsOrdered(receivingMultiplicityElement.isOrdered()
					|| mergedMultiplicityElement.isOrdered());
		}

		protected void mergeMultiplicityElement_IsUnique(
				MultiplicityElement receivingMultiplicityElement,
				MultiplicityElement mergedMultiplicityElement) {
			receivingMultiplicityElement
				.setIsUnique(receivingMultiplicityElement.isUnique()
					&& mergedMultiplicityElement.isUnique());
		}

		protected void mergeNamedElement_Visibility(
				NamedElement receivingNamedElement,
				NamedElement mergedNamedElement) {

			if (receivingNamedElement.getVisibility() == VisibilityKind.PRIVATE_LITERAL
				&& mergedNamedElement.getVisibility() == VisibilityKind.PRIVATE_LITERAL) {

				receivingNamedElement
					.setVisibility(VisibilityKind.PRIVATE_LITERAL);
			} else if (receivingNamedElement.isSetVisibility()) {
				receivingNamedElement
					.setVisibility(VisibilityKind.PUBLIC_LITERAL);
			}
		}

		protected void mergeProperty_IsDerived(Property receivingProperty,
				Property mergedProperty) {
			receivingProperty.setIsDerived(receivingProperty.isDerived()
				|| mergedProperty.isDerived());
		}

		protected void mergeProperty_IsDerivedUnion(Property receivingProperty,
				Property mergedProperty) {
			receivingProperty.setIsDerivedUnion(receivingProperty
				.isDerivedUnion()
				|| mergedProperty.isDerivedUnion());
		}

		protected void mergeStructuralFeature_IsReadOnly(
				StructuralFeature receivingStructuralFeature,
				StructuralFeature mergedStructuralFeature) {
			receivingStructuralFeature.setIsReadOnly(receivingStructuralFeature
				.isReadOnly()
				&& mergedStructuralFeature.isReadOnly());
		}

		@Override
		protected void copyAttribute(EAttribute eAttribute, EObject eObject,
				EObject copyEObject) {

			if (eObject != copyEObject) {

				if (copyEObject == receivingPackage) {
					return;
				} else if (resultingToMergedEObjectMap.containsKey(copyEObject)) {

					if (eAttribute == UMLPackage.Literals.ASSOCIATION__IS_DERIVED) {
						mergeAssociation_IsDerived((Association) copyEObject,
							(Association) eObject);
					} else if (eAttribute == UMLPackage.Literals.CLASSIFIER__IS_ABSTRACT) {
						mergeClassifier_IsAbstract((Classifier) copyEObject,
							(Classifier) eObject);
					} else if (eAttribute == UMLPackage.Literals.LITERAL_INTEGER__VALUE
						&& copyEObject.eContainingFeature() == UMLPackage.Literals.MULTIPLICITY_ELEMENT__LOWER_VALUE) {

						mergeLiteralInteger_Value((LiteralInteger) copyEObject,
							(LiteralInteger) eObject);
					} else if (eAttribute == UMLPackage.Literals.LITERAL_UNLIMITED_NATURAL__VALUE
						&& copyEObject.eContainingFeature() == UMLPackage.Literals.MULTIPLICITY_ELEMENT__UPPER_VALUE) {

						mergeLiteralUnlimitedNatural_Value(
							(LiteralUnlimitedNatural) copyEObject,
							(LiteralUnlimitedNatural) eObject);
					} else if (eAttribute == UMLPackage.Literals.MULTIPLICITY_ELEMENT__IS_ORDERED) {
						mergeMultiplicityElement_IsOrdered(
							(MultiplicityElement) copyEObject,
							(MultiplicityElement) eObject);
					} else if (eAttribute == UMLPackage.Literals.MULTIPLICITY_ELEMENT__IS_UNIQUE) {
						mergeMultiplicityElement_IsUnique(
							(MultiplicityElement) copyEObject,
							(MultiplicityElement) eObject);
					} else if (eAttribute == UMLPackage.Literals.NAMED_ELEMENT__VISIBILITY) {
						mergeNamedElement_Visibility(
							(NamedElement) copyEObject, (NamedElement) eObject);
					} else if (eAttribute == UMLPackage.Literals.PROPERTY__IS_DERIVED) {
						mergeProperty_IsDerived((Property) copyEObject,
							(Property) eObject);
					} else if (eAttribute == UMLPackage.Literals.PROPERTY__IS_DERIVED_UNION) {
						mergeProperty_IsDerivedUnion((Property) copyEObject,
							(Property) eObject);
					} else if (eAttribute == UMLPackage.Literals.STRUCTURAL_FEATURE__IS_READ_ONLY) {
						mergeStructuralFeature_IsReadOnly(
							(StructuralFeature) copyEObject,
							(StructuralFeature) eObject);
					} else {
						super.copyAttribute(eAttribute, eObject, copyEObject);
					}
				} else {
					super.copyAttribute(eAttribute, eObject, copyEObject);
				}
			}
		}

		@Override
		protected void copyContainment(EReference eReference, EObject eObject,
				EObject copyEObject) {

			if (eObject != copyEObject) {

				if (eReference.isMany()) {
					@SuppressWarnings("unchecked")
					List<EObject> sourceList = (List<EObject>) eObject
						.eGet(eReference);
					@SuppressWarnings("unchecked")
					InternalEList<EObject> targetList = (InternalEList<EObject>) copyEObject
						.eGet(getTarget(eReference));

					for (EObject childEObject : sourceList) {
						EObject copyChildEObject = copy(childEObject);

						if (childEObject != copyChildEObject) {
							targetList.addUnique(copyChildEObject);
						}
					}
				} else {
					EObject childEObject = (EObject) eObject.eGet(eReference);
					EObject copyChildEObject = childEObject == null
						? null
						: copy(childEObject);

					if (childEObject != copyChildEObject) {
						copyEObject.eSet(getTarget(eReference),
							copyChildEObject);
					}
				}
			}
		}

		protected void mergeTypedElement_Type(
				TypedElement receivingTypedElement,
				TypedElement mergedTypedElement) {
			Type receivingType = receivingTypedElement.getType();
			Type mergedType = mergedTypedElement.getType();

			if (receivingType != null && mergedType instanceof Classifier) {
				EList<Classifier> allParents = ((Classifier) mergedType)
					.allParents();

				for (EObject mergedEObject : getMergedEObjects(receivingType)) {

					if (findEObject(allParents, new ResultingQNameMatcher(
						mergedEObject)) != null) {

						mergedType = (Type) mergedEObject;
					}
				}
			}

			Type resultingType = mergedType == null
				? null
				: (Type) get(mergedType);

			receivingTypedElement.setType(resultingType == null
				? mergedType
				: resultingType);
		}

		@Override
		protected void copyReference(EReference eReference, EObject eObject,
				EObject copyEObject) {

			if (eObject != copyEObject && eObject.eIsSet(eReference)) {

				if (eReference == UMLPackage.Literals.TYPED_ELEMENT__TYPE) {
					mergeTypedElement_Type((TypedElement) copyEObject,
						(TypedElement) eObject);
				} else if (eReference.isMany()) {
					@SuppressWarnings("unchecked")
					List<EObject> sourceList = (List<EObject>) eObject
						.eGet(eReference);
					@SuppressWarnings("unchecked")
					InternalEList<EObject> targetList = (InternalEList<EObject>) copyEObject
						.eGet(getTarget(eReference));

					boolean isBidirectional = eReference.getEOpposite() != null;
					int index = 0;

					for (EObject referencedEObject : sourceList) {
						EObject copyReferencedEObject = get(referencedEObject);

						if (copyReferencedEObject == null) {

							if (!isBidirectional) {

								if (!targetList.contains(referencedEObject)) {
									targetList.addUnique(index,
										referencedEObject);
								}

								index++;
							}
						} else {

							if (isBidirectional) {
								int position = targetList
									.indexOf(copyReferencedEObject);

								if (position == -1) {
									targetList.addUnique(index,
										copyReferencedEObject);
								} else if (index != position) {
									targetList.move(index,
										copyReferencedEObject);
								}
							} else if (!targetList
								.contains(copyReferencedEObject)) {

								targetList.addUnique(index,
									copyReferencedEObject);
							}

							index++;
						}
					}
				} else {
					super.copyReference(eReference, eObject, copyEObject);
				}
			}
		}

		@Override
		protected EObject createCopy(EObject eObject) {
			return new UMLSwitch<EObject>() {

				@Override
				public EObject caseAssociation(Association association) {
					Association matchingAssociation = findEObject(
						getMatchCandidates(association), new NameMatcher(
							association) {

							@Override
							public boolean matches(EObject otherEObject) {

								if (super.matches(otherEObject)) {
									otherEObject = getPreviouslyMergedEObject(otherEObject);

									List<Property> memberEnds = ((Association) eObject)
										.getMemberEnds();
									List<Property> otherMemberEnds = ((Association) otherEObject)
										.getMemberEnds();

									if (memberEnds.size() == otherMemberEnds
										.size()) {

										for (Property memberEnd : memberEnds) {

											if (findEObject(otherMemberEnds,
												new TypeMatcher(memberEnd)) == null) {

												return false;
											}
										}

										return true;
									}

								}

								return false;
							}
						});

					return matchingAssociation == null
						? super.caseAssociation(association)
						: matchingAssociation;
				}

				@Override
				public EObject caseClass(org.eclipse.uml2.uml.Class class_) {
					org.eclipse.uml2.uml.Class matchingClass = findEObject(
						getMatchCandidates(class_), new NameMatcher(class_));

					return matchingClass == null
						? super.caseClass(class_)
						: matchingClass;
				}

				@Override
				public EObject caseComment(Comment comment) {
					Comment matchingComment = findEObject(
						getMatchCandidates(comment), new BodyMatcher(comment));

					return matchingComment == null
						? super.caseComment(comment)
						: matchingComment;
				}

				@Override
				public EObject caseConstraint(Constraint constraint) {
					Constraint matchingConstraint = findEObject(
						getMatchCandidates(constraint), new NameMatcher(
							constraint));

					return matchingConstraint == null
						? super.caseConstraint(constraint)
						: matchingConstraint;
				}

				@Override
				public EObject caseDataType(DataType dataType) {
					DataType matchingDataType = findEObject(
						getMatchCandidates(dataType), new NameMatcher(dataType));

					return matchingDataType == null
						? super.caseDataType(dataType)
						: matchingDataType;
				}

				@Override
				public EObject caseDirectedRelationship(
						DirectedRelationship directedRelationship) {

					if (mergedPackages.containsAll(directedRelationship
						.getTargets())) {

						return directedRelationship;
					}

					DirectedRelationship matchingDirectedRelationship = findEObject(
						getMatchCandidates(directedRelationship),
						new EClassMatcher(directedRelationship) {

							@Override
							public boolean matches(EObject otherEObject) {

								if (super.matches(otherEObject)) {
									otherEObject = getPreviouslyMergedEObject(otherEObject);

									List<Element> targets = ((DirectedRelationship) eObject)
										.getTargets();
									List<Element> otherTargets = ((DirectedRelationship) otherEObject)
										.getTargets();

									if (targets.size() == otherTargets.size()) {

										for (Element target : targets) {

											if (findEObject(otherTargets,
												new ResultingQNameMatcher(
													target)) == null) {

												return false;
											}
										}

										return true;
									}
								}

								return false;
							}
						});

					return matchingDirectedRelationship == null
						? super.caseDirectedRelationship(directedRelationship)
						: matchingDirectedRelationship;
				}

				@Override
				public EObject caseEnumerationLiteral(
						EnumerationLiteral enumerationLiteral) {
					EnumerationLiteral matchingEnumerationLiteral = findEObject(
						getMatchCandidates(enumerationLiteral),
						new NameMatcher(enumerationLiteral));

					return matchingEnumerationLiteral == null
						? super.caseEnumerationLiteral(enumerationLiteral)
						: matchingEnumerationLiteral;
				}

				@Override
				public EObject caseOperation(Operation operation) {
					Operation matchingOperation = findEObject(
						getMatchCandidates(operation), new NameMatcher(
							operation) {

							@Override
							public boolean matches(EObject otherEObject) {

								if (super.matches(otherEObject)) {
									otherEObject = getPreviouslyMergedEObject(otherEObject);

									List<Parameter> ownedParameters = ((Operation) eObject)
										.getOwnedParameters();
									List<Parameter> otherOwnedParameters = ((Operation) otherEObject)
										.getOwnedParameters();

									if (ownedParameters.size() == otherOwnedParameters
										.size()) {

										for (int i = 0; i < ownedParameters
											.size(); i++) {

											if (!new TypeMatcher(
												ownedParameters.get(i))
												.matches(otherOwnedParameters
													.get(i))) {

												return false;
											}
										}

										return true;
									}
								}

								return false;
							}
						});

					return matchingOperation == null
						? super.caseOperation(operation)
						: matchingOperation;
				}

				@Override
				public EObject casePackage(org.eclipse.uml2.uml.Package package_) {
					org.eclipse.uml2.uml.Package matchingPackage = null;

					if (mergedPackages.contains(package_)) {
						matchingPackage = receivingPackage;
					} else {
						matchingPackage = findEObject(
							getMatchCandidates(package_), new NameMatcher(
								package_));
					}

					return matchingPackage == null
						? super.casePackage(package_)
						: matchingPackage;
				}

				@Override
				public EObject caseParameter(Parameter parameter) {
					Parameter matchingParameter = findEObject(
						getMatchCandidates(parameter), new NameMatcher(
							parameter));

					return matchingParameter == null
						? super.caseParameter(parameter)
						: matchingParameter;
				}

				@Override
				public EObject caseProperty(Property property) {
					Property matchingProperty = findEObject(
						getMatchCandidates(property), new NameMatcher(property));

					return matchingProperty == null
						? super.caseProperty(property)
						: matchingProperty;
				}

				@Override
				public EObject defaultCase(EObject eObject) {
					Element baseElement = getBaseElement(eObject);

					return baseElement == null
						? PackageMerger.super.createCopy(eObject)
						: applyStereotype((Element) get(baseElement),
							getTarget(eObject.eClass()));
				}

				@Override
				protected EObject doSwitch(EClass theEClass, EObject theEObject) {

					if (theEClass.eContainer() != modelPackage) {

						if (theEClass == EcorePackage.Literals.EANNOTATION) {
							EAnnotation matchingEAnnotation = findEObject(
								getMatchCandidates(theEObject),
								new SourceMatcher((EAnnotation) theEObject));

							if (matchingEAnnotation != null) {
								return matchingEAnnotation;
							}
						} else if (theEClass == EcorePackage.Literals.ESTRING_TO_STRING_MAP_ENTRY) {
							@SuppressWarnings("unchecked")
							BasicEMap.Entry<String, String> matchingEntry = findEObject(
								getMatchCandidates(theEObject),
								new KeyMatcher(
									(BasicEMap.Entry<String, String>) theEObject));

							if (matchingEntry != null) {
								return (EObject) matchingEntry;
							}
						} else if (getStereotype(theEClass) != null) {
							EObject matchingEObject = findEObject(
								getMatchCandidates(theEObject),
								new EClassMatcher(theEObject));

							if (matchingEObject != null) {
								return matchingEObject;
							}
						}
					}

					return super.doSwitch(theEClass, theEObject);
				}
			}.doSwitch(eObject);
		}

		@Override
		public EObject copy(EObject eObject) {
			EObject copyEObject = super.copy(eObject);

			if (eObject != copyEObject) {
				List<EObject> mergedEObjects = resultingToMergedEObjectMap
					.get(copyEObject);

				if (mergedEObjects == null) {
					resultingToMergedEObjectMap
						.put(
							copyEObject,
							mergedEObjects = new UniqueEList.FastCompare<EObject>(
								1));
				}

				mergedEObjects.add(eObject);
			}

			if (DEBUG) {
				System.out.println(getQualifiedText(eObject) + "->" //$NON-NLS-1$
					+ getQualifiedText(copyEObject));
			}

			return copyEObject;
		}

		@Override
		public <T> Collection<T> copyAll(Collection<? extends T> eObjects) {
			Collection<T> result = new ArrayList<T>(eObjects.size());

			for (Object object : eObjects) {
				@SuppressWarnings("unchecked")
				T copy = (T) copy((EObject) object);
				result.add(copy);

				for (TreeIterator<EObject> eAllContents = ((EObject) object)
					.eAllContents(); eAllContents.hasNext();) {

					EObject childEObject = eAllContents.next();

					if (childEObject instanceof Element) {
						@SuppressWarnings("unchecked")
						Collection<T> copies = (Collection<T>) super
							.copyAll(((Element) childEObject)
								.getStereotypeApplications());
						result.addAll(copies);
					}
				}
			}

			return result;
		}

		protected Collection<org.eclipse.uml2.uml.Package> getAllMergedPackages(
				org.eclipse.uml2.uml.Package package_) {
			return getAllMergedPackages(package_,
				new UniqueEList.FastCompare<org.eclipse.uml2.uml.Package>());
		}

		private Collection<org.eclipse.uml2.uml.Package> getAllMergedPackages(
				org.eclipse.uml2.uml.Package package_,
				Collection<org.eclipse.uml2.uml.Package> allMergedPackages) {

			for (PackageMerge packageMerge : package_.getPackageMerges()) {
				org.eclipse.uml2.uml.Package mergedPackage = packageMerge
					.getMergedPackage();

				if (mergedPackage != null) {
					getAllMergedPackages(mergedPackage, allMergedPackages);

					allMergedPackages.add(mergedPackage);
				}
			}

			return allMergedPackages;
		}

		protected void processDifferentPropertyStaticity(
				Map<String, String> options, DiagnosticChain diagnostics,
				Map<Object, Object> context) {

			for (Map.Entry<EObject, List<EObject>> entry : resultingToMergedEObjectMap
				.entrySet()) {
				EObject key = entry.getKey();

				if (key instanceof Property) {
					Property property = (Property) key;

					for (EObject mergedProperty : entry.getValue()) {

						if (OPTION__REPORT.equals(options
							.get(OPTION__DIFFERENT_PROPERTY_STATICITY))
							&& diagnostics != null) {

							if (property.isStatic() != ((Property) mergedProperty)
								.isStatic()) {

								diagnostics
									.add(new BasicDiagnostic(
										Diagnostic.ERROR,
										UMLValidator.DIAGNOSTIC_SOURCE,
										DIFFERENT_PROPERTY_STATICITY,
										UMLPlugin.INSTANCE
											.getString(
												"_UI_PackageMerger_ReportDifferentPropertyStaticity_diagnostic", //$NON-NLS-1$
												getMessageSubstitutions(
													context, property,
													mergedProperty)),
										new Object[]{property, mergedProperty}));
							}
						}
					}
				}
			}
		}

		protected void processDifferentPropertyUniqueness(
				Map<String, String> options, DiagnosticChain diagnostics,
				Map<Object, Object> context) {

			for (Map.Entry<EObject, List<EObject>> entry : resultingToMergedEObjectMap
				.entrySet()) {
				EObject key = entry.getKey();

				if (key instanceof Property) {
					Property property = (Property) key;

					for (EObject mergedProperty : entry.getValue()) {

						if (OPTION__REPORT.equals(options
							.get(OPTION__DIFFERENT_PROPERTY_UNIQUENESS))
							&& diagnostics != null) {

							if (property.isUnique() != ((Property) mergedProperty)
								.isUnique()) {

								diagnostics
									.add(new BasicDiagnostic(
										Diagnostic.ERROR,
										UMLValidator.DIAGNOSTIC_SOURCE,
										DIFFERENT_PROPERTY_UNIQUENESS,
										UMLPlugin.INSTANCE
											.getString(
												"_UI_PackageMerger_ReportDifferentPropertyUniqueness_diagnostic", //$NON-NLS-1$
												getMessageSubstitutions(
													context, property,
													mergedProperty)),
										new Object[]{property, mergedProperty}));
							}
						}
					}
				}
			}
		}

		protected void processImplicitRedefinitions(
				Map<String, String> options, DiagnosticChain diagnostics,
				Map<Object, Object> context) {

			for (EObject resultingEObject : resultingToMergedEObjectMap
				.keySet()) {

				if (resultingEObject instanceof Feature) {
					Feature redefiningFeature = (Feature) resultingEObject;
					EList<Feature> redefinedFeatures = getRedefinedFeatures(redefiningFeature);

					for (Feature validRedefinition : findValidRedefinitions(
						redefiningFeature, redefiningFeature.getName())) {

						if (!redefinedFeatures.contains(validRedefinition)) {

							if (OPTION__PROCESS.equals(options
								.get(OPTION__IMPLICIT_REDEFINITIONS))) {

								if (diagnostics != null) {
									diagnostics
										.add(new BasicDiagnostic(
											Diagnostic.INFO,
											UMLValidator.DIAGNOSTIC_SOURCE,
											IMPLICIT_REDEFINITION,
											UMLPlugin.INSTANCE
												.getString(
													"_UI_PackageMerger_ProcessImplicitFeatureRedefinition_diagnostic", //$NON-NLS-1$
													getMessageSubstitutions(
														context,
														redefiningFeature,
														validRedefinition)),
											new Object[]{redefiningFeature,
												validRedefinition}));
								}

								redefinedFeatures.add(validRedefinition);
							} else if (OPTION__REPORT.equals(options
								.get(OPTION__IMPLICIT_REDEFINITIONS))
								&& diagnostics != null) {

								diagnostics
									.add(new BasicDiagnostic(
										Diagnostic.WARNING,
										UMLValidator.DIAGNOSTIC_SOURCE,
										IMPLICIT_REDEFINITION,
										UMLPlugin.INSTANCE
											.getString(
												"_UI_PackageMerger_ReportImplicitFeatureRedefinition_diagnostic", //$NON-NLS-1$
												getMessageSubstitutions(
													context, redefiningFeature,
													validRedefinition)),
										new Object[]{redefiningFeature,
											validRedefinition}));
							}
						}
					}
				}
			}
		}

		protected void processInvalidRedefinitions(Map<String, String> options,
				DiagnosticChain diagnostics, Map<Object, Object> context) {

			for (EObject resultingEObject : resultingToMergedEObjectMap
				.keySet()) {

				if (resultingEObject instanceof Feature) {
					Feature redefiningFeature = (Feature) resultingEObject;
					EList<Feature> redefinedFeatures = getRedefinedFeatures(redefiningFeature);

					for (Feature redefinedFeature : new ArrayList<Feature>(
						redefinedFeatures)) {

						if (!UMLUtil.isRedefinitionValid(redefiningFeature,
							redefinedFeature)) {

							if (OPTION__PROCESS.equals(options
								.get(OPTION__INVALID_REDEFINITIONS))
								|| OPTION__DISCARD.equals(options
									.get(OPTION__INVALID_REDEFINITIONS))) {

								if (diagnostics != null) {
									diagnostics
										.add(new BasicDiagnostic(
											Diagnostic.INFO,
											UMLValidator.DIAGNOSTIC_SOURCE,
											INVALID_REDEFINITION,
											UMLPlugin.INSTANCE
												.getString(
													"_UI_PackageMerger_DiscardInvalidFeatureRedefinition_diagnostic", //$NON-NLS-1$
													getMessageSubstitutions(
														context,
														redefiningFeature,
														redefinedFeature)),
											new Object[]{redefiningFeature,
												redefinedFeature}));
								}

								redefinedFeatures.remove(redefinedFeature);
							} else if (OPTION__REPORT.equals(options
								.get(OPTION__INVALID_REDEFINITIONS))
								&& diagnostics != null) {

								diagnostics
									.add(new BasicDiagnostic(
										Diagnostic.WARNING,
										UMLValidator.DIAGNOSTIC_SOURCE,
										INVALID_REDEFINITION,
										UMLPlugin.INSTANCE
											.getString(
												"_UI_PackageMerger_ReportInvalidFeatureRedefinition_diagnostic", //$NON-NLS-1$
												getMessageSubstitutions(
													context, redefiningFeature,
													redefinedFeature)),
										new Object[]{redefiningFeature,
											redefinedFeature}));
							}
						}

						if (OPTION__PROCESS.equals(options
							.get(OPTION__INVALID_REDEFINITIONS))) {

							Collection<Feature> validRedefinitions = findValidRedefinitions(
								redefiningFeature, redefinedFeature.getName());

							if (!validRedefinitions.isEmpty()) {

								for (Feature validRedefinition : validRedefinitions) {

									if (!redefinedFeatures
										.contains(validRedefinition)) {

										if (diagnostics != null) {
											diagnostics
												.add(new BasicDiagnostic(
													Diagnostic.INFO,
													UMLValidator.DIAGNOSTIC_SOURCE,
													INVALID_REDEFINITION,
													UMLPlugin.INSTANCE
														.getString(
															"_UI_PackageMerger_ProcessInvalidRedefinition_diagnostic", //$NON-NLS-1$
															getMessageSubstitutions(
																context,
																redefiningFeature,
																redefinedFeature,
																validRedefinition)),
													new Object[]{
														redefiningFeature,
														validRedefinition}));
										}

										redefinedFeatures
											.add(validRedefinition);
									}
								}

								if (!validRedefinitions
									.contains(redefinedFeature)) {

									redefinedFeatures.remove(redefinedFeature);
								}
							}
						}
					}
				}
			}
		}

		protected void processInvalidSubsets(Map<String, String> options,
				DiagnosticChain diagnostics, Map<Object, Object> context) {

			for (EObject resultingEObject : resultingToMergedEObjectMap
				.keySet()) {

				if (resultingEObject instanceof Property) {
					Property subsettingProperty = (Property) resultingEObject;
					EList<Property> subsettedProperties = subsettingProperty
						.getSubsettedProperties();

					for (Property subsettedProperty : new ArrayList<Property>(
						subsettedProperties)) {

						if (!UMLUtil.isSubsetValid(subsettingProperty,
							subsettedProperty)) {

							if (OPTION__PROCESS.equals(options
								.get(OPTION__INVALID_SUBSETS))
								|| OPTION__DISCARD.equals(options
									.get(OPTION__INVALID_SUBSETS))) {

								if (diagnostics != null) {
									diagnostics
										.add(new BasicDiagnostic(
											Diagnostic.INFO,
											UMLValidator.DIAGNOSTIC_SOURCE,
											INVALID_SUBSET,
											UMLPlugin.INSTANCE
												.getString(
													"_UI_PackageMerger_DiscardInvalidSubset_diagnostic", //$NON-NLS-1$
													getMessageSubstitutions(
														context,
														subsettingProperty,
														subsettedProperty)),
											new Object[]{subsettingProperty,
												subsettedProperty}));
								}

								subsettedProperties.remove(subsettedProperty);
							} else if (OPTION__REPORT.equals(options
								.get(OPTION__INVALID_SUBSETS))
								&& diagnostics != null) {

								diagnostics
									.add(new BasicDiagnostic(
										Diagnostic.WARNING,
										UMLValidator.DIAGNOSTIC_SOURCE,
										INVALID_SUBSET,
										UMLPlugin.INSTANCE
											.getString(
												"_UI_PackageMerger_ReportInvalidSubset_diagnostic", //$NON-NLS-1$
												getMessageSubstitutions(
													context,
													subsettingProperty,
													subsettedProperty)),
										new Object[]{subsettingProperty,
											subsettedProperty}));
							}
						}

						if (OPTION__PROCESS.equals(options
							.get(OPTION__INVALID_SUBSETS))) {

							Collection<Property> validSubsets = findValidSubsets(
								subsettingProperty, subsettedProperty.getName());

							if (!validSubsets.isEmpty()) {

								for (Property validSubset : validSubsets) {

									if (!subsettedProperties
										.contains(validSubset)) {

										if (diagnostics != null) {
											diagnostics
												.add(new BasicDiagnostic(
													Diagnostic.INFO,
													UMLValidator.DIAGNOSTIC_SOURCE,
													INVALID_SUBSET,
													UMLPlugin.INSTANCE
														.getString(
															"_UI_PackageMerger_ProcessInvalidSubset_diagnostic", //$NON-NLS-1$
															getMessageSubstitutions(
																context,
																subsettingProperty,
																subsettedProperty,
																validSubset)),
													new Object[]{
														subsettingProperty,
														validSubset}));
										}

										subsettedProperties.add(validSubset);
									}
								}

								if (!validSubsets.contains(subsettedProperty)) {
									subsettedProperties
										.remove(subsettedProperty);
								}
							}
						}
					}
				}
			}
		}

		protected void processEmptyUnions(Map<String, String> options,
				DiagnosticChain diagnostics, Map<Object, Object> context) {
			Map<Property, EList<Property>> unionToSubsettingPropertyMap = new LinkedHashMap<Property, EList<Property>>();

			for (EObject resultingEObject : resultingToMergedEObjectMap
				.keySet()) {

				if (resultingEObject instanceof Property) {
					Property property = (Property) resultingEObject;

					if (property.isDerivedUnion()
						&& !unionToSubsettingPropertyMap.containsKey(property)) {

						unionToSubsettingPropertyMap.put(property,
							new UniqueEList.FastCompare<Property>());
					}

					for (Property subsettedProperty : property
						.getSubsettedProperties()) {

						if (subsettedProperty.isDerivedUnion()) {
							EList<Property> subsettingProperties = unionToSubsettingPropertyMap
								.get(subsettedProperty);

							if (subsettingProperties == null) {
								unionToSubsettingPropertyMap
									.put(
										subsettedProperty,
										subsettingProperties = new UniqueEList.FastCompare<Property>());
							}

							subsettingProperties.add(property);
						}
					}
				}
			}

			for (Map.Entry<Property, EList<Property>> entry : unionToSubsettingPropertyMap
				.entrySet()) {

				if (entry.getValue().isEmpty()) {
					Property unionProperty = entry.getKey();

					if (OPTION__PROCESS.equals(options
						.get(OPTION__EMPTY_UNIONS))) {

						if (diagnostics != null) {
							diagnostics
								.add(new BasicDiagnostic(
									Diagnostic.INFO,
									UMLValidator.DIAGNOSTIC_SOURCE,
									EMPTY_UNION,
									UMLPlugin.INSTANCE
										.getString(
											"_UI_PackageMerger_ProcessEmptyUnion_diagnostic", //$NON-NLS-1$
											getMessageSubstitutions(context,
												unionProperty)),
									new Object[]{unionProperty}));
						}

						unionProperty.setIsDerivedUnion(false);
					} else if (OPTION__REPORT.equals(options
						.get(OPTION__EMPTY_UNIONS))
						&& diagnostics != null) {

						diagnostics
							.add(new BasicDiagnostic(
								Diagnostic.WARNING,
								UMLValidator.DIAGNOSTIC_SOURCE,
								EMPTY_UNION,
								UMLPlugin.INSTANCE
									.getString(
										"_UI_PackageMerger_ReportEmptyUnion_diagnostic", //$NON-NLS-1$
										getMessageSubstitutions(context,
											unionProperty)),
								new Object[]{unionProperty}));
					}
				}
			}
		}

		protected void processRedundantGeneralizations(
				Map<String, String> options, DiagnosticChain diagnostics,
				Map<Object, Object> context) {

			for (EObject resultingEObject : resultingToMergedEObjectMap
				.keySet()) {

				if (resultingEObject instanceof Classifier) {
					Classifier classifier = (Classifier) resultingEObject;
					EList<Generalization> generalizations = classifier
						.getGeneralizations();

					for (Generalization generalization : new ArrayList<Generalization>(
						generalizations)) {
						Classifier general = generalization.getGeneral();

						if (general != null) {
							EList<Classifier> generalAllParents = general
								.allParents();

							for (Iterator<Generalization> g = generalizations
								.iterator(); g.hasNext();) {

								Generalization otherGeneralization = g.next();
								Classifier otherGeneral = otherGeneralization
									.getGeneral();

								if (general != otherGeneral
									&& generalAllParents.contains(otherGeneral)
									&& !otherGeneralization
										.hasKeyword("extend")) { //$NON-NLS-1$

									if (OPTION__DISCARD
										.equals(options
											.get(OPTION__REDUNDANT_GENERALIZATIONS))) {

										if (diagnostics != null) {
											diagnostics
												.add(new BasicDiagnostic(
													Diagnostic.INFO,
													UMLValidator.DIAGNOSTIC_SOURCE,
													REDUNDANT_GENERALIZATION,
													UMLPlugin.INSTANCE
														.getString(
															"_UI_PackageMerger_DiscardRedundantGeneralization_diagnostic", //$NON-NLS-1$
															getMessageSubstitutions(
																context,
																classifier,
																otherGeneral,
																general)),
													new Object[]{classifier,
														otherGeneral}));
										}

										g.remove();
									} else if (OPTION__REPORT
										.equals(options
											.get(OPTION__REDUNDANT_GENERALIZATIONS))
										&& diagnostics != null) {

										diagnostics
											.add(new BasicDiagnostic(
												Diagnostic.WARNING,
												UMLValidator.DIAGNOSTIC_SOURCE,
												REDUNDANT_GENERALIZATION,
												UMLPlugin.INSTANCE
													.getString(
														"_UI_PackageMerger_ReportRedundantGeneralization_diagnostic", //$NON-NLS-1$
														getMessageSubstitutions(
															context,
															classifier,
															otherGeneral,
															general)),
												new Object[]{classifier,
													otherGeneral}));
									}

									break;
								}
							}
						}
					}
				}
			}
		}

		protected void processAssociationSpecializations(
				Map<String, String> options, DiagnosticChain diagnostics,
				Map<Object, Object> context) {

			for (EObject resultingEObject : resultingToMergedEObjectMap
				.keySet()) {

				if (resultingEObject instanceof Association) {
					Association association = (Association) resultingEObject;

					EList<Association> generalAssociations = new UniqueEList.FastCompare<Association>();

					for (Property memberEnd : association.getMemberEnds()) {

						for (Property redefinedProperty : memberEnd
							.getRedefinedProperties()) {

							Association redefinedAssociation = redefinedProperty
								.getAssociation();

							if (redefinedAssociation != null) {
								generalAssociations.add(redefinedAssociation);
							}
						}

						for (Property subsettedProperty : memberEnd
							.getSubsettedProperties()) {

							Association subsettedAssociation = subsettedProperty
								.getAssociation();

							if (subsettedAssociation != null) {
								generalAssociations.add(subsettedAssociation);
							}
						}
					}

					for (Association generalAssociation : generalAssociations) {

						if (!association.allParents().contains(
							generalAssociation)) {

							if (OPTION__PROCESS.equals(options
								.get(OPTION__ASSOCIATION_SPECIALIZATIONS))) {

								if (diagnostics != null) {
									diagnostics
										.add(new BasicDiagnostic(
											Diagnostic.INFO,
											UMLValidator.DIAGNOSTIC_SOURCE,
											ASSOCIATION_SPECIALIZATION,
											UMLPlugin.INSTANCE
												.getString(
													"_UI_PackageMerger_ProcessAssociationSpecialization_diagnostic", //$NON-NLS-1$
													getMessageSubstitutions(
														context, association,
														generalAssociation)),
											new Object[]{association,
												generalAssociation}));
								}

								association
									.createGeneralization(generalAssociation);
							} else if (OPTION__REPORT.equals(options
								.get(OPTION__ASSOCIATION_SPECIALIZATIONS))
								&& diagnostics != null) {

								diagnostics
									.add(new BasicDiagnostic(
										Diagnostic.WARNING,
										UMLValidator.DIAGNOSTIC_SOURCE,
										ASSOCIATION_SPECIALIZATION,
										UMLPlugin.INSTANCE
											.getString(
												"_UI_PackageMerger_ReportAssociationSpecialization_diagnostic", //$NON-NLS-1$
												getMessageSubstitutions(
													context, association,
													generalAssociation)),
										new Object[]{association,
											generalAssociation}));
							}
						}
					}
				}
			}
		}

		protected void processCapabilities(Map<String, String> options,
				DiagnosticChain diagnostics, Map<Object, Object> context) {

			for (Map.Entry<EObject, List<EObject>> entry : resultingToMergedEObjectMap
				.entrySet()) {
				EObject resultingEObject = entry.getKey();

				if (resultingEObject instanceof RedefinableElement) {
					org.eclipse.uml2.uml.Package resultingPackage = ((RedefinableElement) resultingEObject)
						.getNearestPackage();

					for (EObject mergedEObject : entry.getValue()) {
						org.eclipse.uml2.uml.Package mergedPackage = ((Element) mergedEObject)
							.getNearestPackage();

						if (OPTION__PROCESS.equals(options
							.get(OPTION__CAPABILITIES))) {

							if (diagnostics != null) {
								diagnostics
									.add(new BasicDiagnostic(
										Diagnostic.INFO,
										UMLValidator.DIAGNOSTIC_SOURCE,
										CAPABILITY,
										UMLPlugin.INSTANCE
											.getString(
												"_UI_PackageMerger_ProcessCapability_diagnostic", //$NON-NLS-1$
												getMessageSubstitutions(
													context, resultingEObject,
													mergedPackage)),
										new Object[]{resultingEObject,
											mergedPackage}));
							}

							getEAnnotation(
								getEAnnotation(resultingPackage,
									UMLPackage.eNS_URI, true),
								mergedPackage.getQualifiedName(), true)
								.getReferences().add(resultingEObject);
						} else if (OPTION__REPORT.equals(options
							.get(OPTION__CAPABILITIES))
							&& diagnostics != null) {

							diagnostics
								.add(new BasicDiagnostic(
									Diagnostic.WARNING,
									UMLValidator.DIAGNOSTIC_SOURCE,
									CAPABILITY,
									UMLPlugin.INSTANCE
										.getString(
											"_UI_PackageMerger_ReportCapability_diagnostic", //$NON-NLS-1$
											getMessageSubstitutions(context,
												resultingEObject, mergedPackage)),
									new Object[]{resultingEObject,
										mergedPackage}));
						}
					}
				}
			}
		}

		protected void processOptions(Map<String, String> options,
				DiagnosticChain diagnostics, Map<Object, Object> context) {

			if (!OPTION__IGNORE.equals(options
				.get(OPTION__DIFFERENT_PROPERTY_STATICITY))) {

				processDifferentPropertyStaticity(options, diagnostics, context);
			}

			if (!OPTION__IGNORE.equals(options
				.get(OPTION__DIFFERENT_PROPERTY_UNIQUENESS))) {

				processDifferentPropertyUniqueness(options, diagnostics,
					context);
			}

			if (!OPTION__IGNORE.equals(options
				.get(OPTION__IMPLICIT_REDEFINITIONS))) {

				processImplicitRedefinitions(options, diagnostics, context);
			}

			if (!OPTION__IGNORE.equals(options
				.get(OPTION__INVALID_REDEFINITIONS))) {

				processInvalidRedefinitions(options, diagnostics, context);
			}

			if (!OPTION__IGNORE.equals(options.get(OPTION__INVALID_SUBSETS))) {
				processInvalidSubsets(options, diagnostics, context);
			}

			if (!OPTION__IGNORE.equals(options.get(OPTION__EMPTY_UNIONS))) {
				processEmptyUnions(options, diagnostics, context);
			}

			if (!OPTION__IGNORE.equals(options
				.get(OPTION__ASSOCIATION_SPECIALIZATIONS))) {

				processAssociationSpecializations(options, diagnostics, context);
			}

			if (!OPTION__IGNORE.equals(options
				.get(OPTION__REDUNDANT_GENERALIZATIONS))) {

				processRedundantGeneralizations(options, diagnostics, context);
			}

			if (!OPTION__IGNORE.equals(options.get(OPTION__CAPABILITIES))) {
				processCapabilities(options, diagnostics, context);
			}
		}

		/**
		 * Merges the contents of (all of) the packages merged by the specified
		 * package using the specified options, reporting problems to the
		 * specified diagnostics, within the specified context.
		 * 
		 * @param package_
		 *            The receiving package.
		 * @param options
		 *            The options to use.
		 * @param diagnostics
		 *            The chain of diagnostics to which problems are to be
		 *            appended.
		 * @param context
		 *            The cache of context-specific information.
		 */
		public void merge(org.eclipse.uml2.uml.Package package_,
				Map<String, String> options, DiagnosticChain diagnostics,
				Map<Object, Object> context) {
			receivingPackage = package_;

			mergedPackages = getAllMergedPackages(package_);

			copyAll(mergedPackages);
			copyReferences();

			receivingPackage.getPackageMerges().clear();

			if (options != null) {
				processOptions(options, diagnostics, context);
			}
		}
	}

	/**
	 * A converter that converts UML elements to representative Ecore model
	 * elements.
	 */
	public static class UML2EcoreConverter
			extends UMLSwitch<Object>
			implements Converter {

		protected class NameMatcher
				extends EStructuralFeatureMatcher {

			protected NameMatcher(ENamedElement eNamedElement) {
				super(eNamedElement, EcorePackage.Literals.ENAMED_ELEMENT__NAME);
			}
		}

		protected class ETypeMatcher
				extends NameMatcher {

			protected ETypeMatcher(ETypedElement eTypedElement) {
				super(eTypedElement);
			}

			@Override
			public boolean matches(EObject otherEObject) {
				return super.matches(otherEObject)
					&& safeEquals(((ETypedElement) eObject).getEType(),
						((ETypedElement) otherEObject).getEType());
			}
		}

		protected class SignatureMatcher
				extends ETypeMatcher {

			protected SignatureMatcher(EOperation eOperation) {
				super(eOperation);
			}

			@Override
			public boolean matches(EObject otherEObject) {

				if (super.matches(otherEObject)) {
					List<EParameter> eParameters = ((EOperation) eObject)
						.getEParameters();
					int eParametersSize = eParameters.size();
					List<EParameter> otherEParameters = ((EOperation) otherEObject)
						.getEParameters();

					if (eParametersSize == otherEParameters.size()) {

						for (int i = 0; i < eParametersSize; i++) {

							if (!new ETypeMatcher(eParameters.get(i))
								.matches(otherEParameters.get(i))) {

								return false;
							}
						}

						return true;
					}
				}

				return false;
			}
		}

		private static final boolean DEBUG = false;

		/**
		 * The option for handling cases where an Ecore tagged value is
		 * encountered. Supported choices are <code>OPTION__IGNORE</code>,
		 * <code>OPTION__REPORT</code>, and <code>OPTION__PROCESS</code>.
		 */
		public static final String OPTION__ECORE_TAGGED_VALUES = "ECORE_TAGGED_VALUES"; //$NON-NLS-1$

		/**
		 * The option for handling cases where a redefining operation is
		 * encountered. Supported choices are <code>OPTION__IGNORE</code>,
		 * <code>OPTION__REPORT</code>, and <code>OPTION__PROCESS</code>.
		 */
		public static final String OPTION__REDEFINING_OPERATIONS = "REDEFINING_OPERATIONS"; //$NON-NLS-1$

		/**
		 * The option for handling cases where a redefining property is
		 * encountered. Supported choices are <code>OPTION__IGNORE</code>,
		 * <code>OPTION__REPORT</code>, and <code>OPTION__PROCESS</code>.
		 */
		public static final String OPTION__REDEFINING_PROPERTIES = "REDEFINING_PROPERTIES"; //$NON-NLS-1$

		/**
		 * The option for handling cases where a subsetting property is
		 * encountered. Supported choices are <code>OPTION__IGNORE</code>,
		 * <code>OPTION__REPORT</code>, and <code>OPTION__PROCESS</code>.
		 */
		public static final String OPTION__SUBSETTING_PROPERTIES = "SUBSETTING_PROPERTIES"; //$NON-NLS-1$

		/**
		 * The option for handling cases where a derived union property is
		 * encountered. Supported choices are <code>OPTION__IGNORE</code>,
		 * <code>OPTION__REPORT</code>, and <code>OPTION__PROCESS</code>.
		 */
		public static final String OPTION__UNION_PROPERTIES = "UNION_PROPERTIES"; //$NON-NLS-1$

		/**
		 * The option for handling cases where a derived feature is encountered.
		 * Supported choices are <code>OPTION__IGNORE</code>,
		 * <code>OPTION__REPORT</code>, and <code>OPTION__PROCESS</code>.
		 */
		public static final String OPTION__DERIVED_FEATURES = "DERIVED_FEATURES"; //$NON-NLS-1$

		/**
		 * The option for handling cases where a duplicate operation is
		 * detected. Supported choices are <code>OPTION__IGNORE</code>,
		 * <code>OPTION__REPORT</code>, <code>OPTION__DISCARD</code>, and
		 * <code>OPTION__PROCESS</code>.
		 */
		public static final String OPTION__DUPLICATE_OPERATIONS = "DUPLICATE_OPERATIONS"; //$NON-NLS-1$

		/**
		 * The option for handling cases where an operation is inherited more
		 * than once. Supported choices are <code>OPTION__IGNORE</code>,
		 * <code>OPTION__REPORT</code>, <code>OPTION__DISCARD</code>, and
		 * <code>OPTION__PROCESS</code>.
		 */
		public static final String OPTION__DUPLICATE_OPERATION_INHERITANCE = "DUPLICATE_OPERATION_INHERITANCE"; //$NON-NLS-1$

		/**
		 * The option for handling cases where a duplicate feature is detected.
		 * Supported choices are <code>OPTION__IGNORE</code>,
		 * <code>OPTION__REPORT</code>, <code>OPTION__DISCARD</code>, and
		 * <code>OPTION__PROCESS</code>.
		 */
		public static final String OPTION__DUPLICATE_FEATURES = "DUPLICATE_FEATURES"; //$NON-NLS-1$

		/**
		 * The option for handling cases where a feature is inherited more than
		 * once. Supported choices are <code>OPTION__IGNORE</code>,
		 * <code>OPTION__REPORT</code>, <code>OPTION__DISCARD</code>, and
		 * <code>OPTION__PROCESS</code>.
		 */
		public static final String OPTION__DUPLICATE_FEATURE_INHERITANCE = "DUPLICATE_FEATURE_INHERITANCE"; //$NON-NLS-1$

		/**
		 * The option for handling cases where superclasses are not ordered.
		 * Supported choices are <code>OPTION__IGNORE</code>,
		 * <code>OPTION__REPORT</code>, and <code>OPTION__PROCESS</code>.
		 */
		public static final String OPTION__SUPER_CLASS_ORDER = "SUPER_CLASS_ORDER"; //$NON-NLS-1$

		/**
		 * The option for handling cases where annotation details are
		 * encountered. Supported choices are <code>OPTION__IGNORE</code>,
		 * <code>OPTION__REPORT</code>, and <code>OPTION__PROCESS</code>.
		 */
		public static final String OPTION__ANNOTATION_DETAILS = "ANNOTATION_DETAILS"; //$NON-NLS-1$

		private static final int DIAGNOSTIC_CODE_OFFSET = 2000;

		/**
		 * The diagnostic code for cases where an Ecore tagged value is
		 * encountered.
		 */
		public static final int ECORE_TAGGED_VALUE = DIAGNOSTIC_CODE_OFFSET + 1;

		/**
		 * The diagnostic code for cases where a redefining operation is
		 * encountered.
		 */
		public static final int REDEFINING_OPERATION = DIAGNOSTIC_CODE_OFFSET + 2;

		/**
		 * The diagnostic code for cases where a redefining property is
		 * encountered.
		 */
		public static final int REDEFINING_PROPERTY = DIAGNOSTIC_CODE_OFFSET + 3;

		/**
		 * The diagnostic code for cases where a subsetting property is
		 * encountered.
		 */
		public static final int SUBSETTING_PROPERTY = DIAGNOSTIC_CODE_OFFSET + 4;

		/**
		 * The diagnostic code for cases where a derived union property is
		 * encountered.
		 */
		public static final int UNION_PROPERTY = DIAGNOSTIC_CODE_OFFSET + 5;

		/**
		 * The diagnostic code for cases where a derived feature is encountered.
		 */
		public static final int DERIVED_FEATURE = DIAGNOSTIC_CODE_OFFSET + 6;

		/**
		 * The diagnostic code for cases where a duplicate operation is
		 * detected.
		 */
		public static final int DUPLICATE_OPERATION = DIAGNOSTIC_CODE_OFFSET + 7;

		/**
		 * The diagnostic code for cases where an operation is inherited more
		 * than once.
		 */
		public static final int DUPLICATE_OPERATION_INHERITANCE = DIAGNOSTIC_CODE_OFFSET + 8;

		/**
		 * The diagnostic code for cases where a duplicate feature is detected.
		 */
		public static final int DUPLICATE_FEATURE = DIAGNOSTIC_CODE_OFFSET + 9;

		/**
		 * The diagnostic code for cases where a feature is inherited more than
		 * once.
		 */
		public static final int DUPLICATE_FEATURE_INHERITANCE = DIAGNOSTIC_CODE_OFFSET + 10;

		/**
		 * The diagnostic code for cases where superclasses are not ordered.
		 */
		public static final int SUPER_CLASS_ORDER = DIAGNOSTIC_CODE_OFFSET + 11;

		/**
		 * The diagnostic code for cases where annotation details are
		 * encountered.
		 */
		public static final int ANNOTATION_DETAILS = DIAGNOSTIC_CODE_OFFSET + 12;

		protected final Map<Element, EModelElement> elementToEModelElementMap = new LinkedHashMap<Element, EModelElement>();

		protected Collection<org.eclipse.uml2.uml.Package> packages = null;

		protected void setName(ENamedElement eNamedElement, String name,
				boolean validate) {
			eNamedElement.setName(validate
				? getValidJavaIdentifier(name)
				: name);
		}

		protected void setName(ENamedElement eNamedElement,
				NamedElement namedElement) {
			setName(eNamedElement, namedElement.getName(), true);
		}

		protected EClassifier getEType(Type type) {
			EClassifier eType = null;

			if (type != null) {
				String qualifiedName = type.getQualifiedName();

				if (!isEmpty(qualifiedName) && type instanceof PrimitiveType) {

					if ("UMLPrimitiveTypes::Boolean".equals(qualifiedName)) { //$NON-NLS-1$
						eType = EcorePackage.Literals.EBOOLEAN;
					} else if ("UMLPrimitiveTypes::Integer".equals(qualifiedName)) { //$NON-NLS-1$
						eType = EcorePackage.Literals.EINT;
					} else if ("UMLPrimitiveTypes::String".equals(qualifiedName)) { //$NON-NLS-1$
						eType = EcorePackage.Literals.ESTRING;
					} else if ("UMLPrimitiveTypes::UnlimitedNatural".equals(qualifiedName)) { //$NON-NLS-1$
						eType = EcorePackage.Literals.EINT;
					} else if ("JavaPrimitiveTypes::boolean".equals(qualifiedName)) { //$NON-NLS-1$
						eType = EcorePackage.Literals.EBOOLEAN;
					} else if ("JavaPrimitiveTypes::byte".equals(qualifiedName)) { //$NON-NLS-1$
						eType = EcorePackage.Literals.EBYTE;
					} else if ("JavaPrimitiveTypes::char".equals(qualifiedName)) { //$NON-NLS-1$
						eType = EcorePackage.Literals.ECHAR;
					} else if ("JavaPrimitiveTypes::double".equals(qualifiedName)) { //$NON-NLS-1$
						eType = EcorePackage.Literals.EDOUBLE;
					} else if ("JavaPrimitiveTypes::float".equals(qualifiedName)) { //$NON-NLS-1$
						eType = EcorePackage.Literals.EFLOAT;
					} else if ("JavaPrimitiveTypes::int".equals(qualifiedName)) { //$NON-NLS-1$
						eType = EcorePackage.Literals.EINT;
					} else if ("JavaPrimitiveTypes::long".equals(qualifiedName)) { //$NON-NLS-1$
						eType = EcorePackage.Literals.ELONG;
					} else if ("JavaPrimitiveTypes::short".equals(qualifiedName)) { //$NON-NLS-1$
						eType = EcorePackage.Literals.ESHORT;
					} else if (qualifiedName
						.startsWith("EcorePrimitiveTypes::")) { //$NON-NLS-1$

						eType = EcorePackage.eINSTANCE.getEClassifier(type
							.getName());
					} else if (qualifiedName.startsWith("XMLPrimitiveTypes::")) { //$NON-NLS-1$
						eType = XMLTypePackage.eINSTANCE.getEClassifier(type
							.getName());
					}
				}

				if (eType == null) {
					Object eObject = doSwitch(type);

					if (eObject instanceof EClassifier) {
						eType = (EClassifier) eObject;
					}
				}
			}

			return eType;
		}

		protected EClassifier getEType(TypedElement typedElement) {
			return getEType(typedElement.getType());
		}

		protected Stereotype getAppliedEcoreStereotype(Element element,
				String name) {
			return element.getAppliedStereotype("Ecore" //$NON-NLS-1$
				+ NamedElement.SEPARATOR + name);
		}

		@Override
		public Object caseClass(org.eclipse.uml2.uml.Class class_) {
			org.eclipse.uml2.uml.Package package_ = class_.getNearestPackage();

			if (package_ != null) {
				EClass eClass = EcoreFactory.eINSTANCE.createEClass();
				elementToEModelElementMap.put(class_, eClass);

				EPackage ePackage = (EPackage) doSwitch(package_);
				ePackage.getEClassifiers().add(eClass);

				setName(eClass, class_);

				eClass.setAbstract(class_.isAbstract());

				defaultCase(class_);

				return eClass;
			}

			return super.caseClass(class_);
		}

		@Override
		public Object caseComment(Comment comment) {

			for (Element annotatedElement : comment.getAnnotatedElements()) {
				EModelElement eModelElement = (EModelElement) doSwitch(annotatedElement);

				if (eModelElement != null) {
					addDocumentation(eModelElement, comment.getBody());
				}
			}

			return super.caseComment(comment);
		}

		@Override
		public Object caseConstraint(Constraint constraint) {
			Namespace context = constraint.getContext();

			if (context != null) {
				EModelElement eModelElement = (EModelElement) doSwitch(context);

				if (eModelElement != null) {
					ValueSpecification specification = constraint
						.getSpecification();

					if (eModelElement instanceof EClassifier) {
						String name = constraint.getName();

						if (!isEmpty(name)) {

							if (eModelElement instanceof EClass) {
								EOperation eOperation = EcoreFactory.eINSTANCE
									.createEOperation();
								elementToEModelElementMap.put(constraint,
									eOperation);

								((EClass) eModelElement).getEOperations().add(
									eOperation);

								setName(eOperation, name, true);

								eOperation
									.setEType(EcorePackage.Literals.EBOOLEAN);

								EParameter eParameter = EcoreFactory.eINSTANCE
									.createEParameter();

								eOperation.getEParameters().add(eParameter);

								setName(eParameter, "diagnostics", false); //$NON-NLS-1$
								eParameter
									.setEType(EcorePackage.Literals.EDIAGNOSTIC_CHAIN);

								eParameter = EcoreFactory.eINSTANCE
									.createEParameter();

								eOperation.getEParameters().add(eParameter);

								setName(eParameter, "context", false); //$NON-NLS-1$

								EGenericType eGenericType = EcoreFactory.eINSTANCE
									.createEGenericType();
								eGenericType
									.setEClassifier(EcorePackage.Literals.EMAP);
								EGenericType eGenericKeyType = EcoreFactory.eINSTANCE
									.createEGenericType();
								eGenericKeyType
									.setEClassifier(EcorePackage.Literals.EJAVA_OBJECT);
								eGenericType.getETypeArguments().add(
									eGenericKeyType);
								EGenericType eGenericValueType = EcoreFactory.eINSTANCE
									.createEGenericType();
								eGenericValueType
									.setEClassifier(EcorePackage.Literals.EJAVA_OBJECT);
								eGenericType.getETypeArguments().add(
									eGenericValueType);

								eParameter.setEGenericType(eGenericType);

								defaultCase(constraint);

								eModelElement = eOperation;
							} else {

								if (addConstraint(eModelElement, name) && DEBUG) {
									System.out
										.println(getQualifiedText(eModelElement)
											+ " is constrained with '" //$NON-NLS-1$
											+ name + "'"); //$NON-NLS-1$
								}
							}
						}
					}

					if (specification != null) {
						addDocumentation(eModelElement, specification
							.stringValue());
					}

					return eModelElement;
				}
			}

			return super.caseConstraint(constraint);
		}

		@Override
		public Object caseEModelElement(EModelElement eModelElement) {
			return eModelElement;
		}

		@Override
		public Object caseEnumeration(Enumeration enumeration) {
			org.eclipse.uml2.uml.Package package_ = enumeration
				.getNearestPackage();

			if (package_ != null) {
				EEnum eEnum = EcoreFactory.eINSTANCE.createEEnum();
				elementToEModelElementMap.put(enumeration, eEnum);

				EPackage ePackage = (EPackage) doSwitch(package_);
				ePackage.getEClassifiers().add(eEnum);

				setName(eEnum, enumeration);

				defaultCase(enumeration);

				return eEnum;
			}

			return super.caseEnumeration(enumeration);
		}

		@Override
		public Object caseEnumerationLiteral(
				EnumerationLiteral enumerationLiteral) {
			Enumeration enumeration = enumerationLiteral.getEnumeration();

			if (enumeration != null) {
				EEnumLiteral eEnumLiteral = EcoreFactory.eINSTANCE
					.createEEnumLiteral();
				elementToEModelElementMap.put(enumerationLiteral, eEnumLiteral);

				EEnum eEnum = (EEnum) doSwitch(enumeration);
				eEnum.getELiterals().add(eEnumLiteral);

				setName(eEnumLiteral, enumerationLiteral);

				int value = enumeration.getOwnedLiterals().indexOf(
					enumerationLiteral);
				ValueSpecification specification = enumerationLiteral
					.getSpecification();

				if (specification != null) {

					try {
						value = specification.integerValue();
					} catch (Exception e) {
						// ignore
					}
				}

				eEnumLiteral.setValue(value);

				defaultCase(enumerationLiteral);

				return eEnumLiteral;
			}

			return super.caseEnumerationLiteral(enumerationLiteral);
		}

		@Override
		public Object caseGeneralization(Generalization generalization) {
			Classifier specific = generalization.getSpecific();

			if (specific != null) {
				EClassifier specificEClassifier = (EClassifier) doSwitch(specific);

				if (specificEClassifier instanceof EClass) {
					EClass specificEClass = (EClass) specificEClassifier;
					Classifier general = generalization.getGeneral();

					if (general != null) {
						EClassifier generalEClassifier = (EClassifier) doSwitch(general);

						if (generalEClassifier instanceof EClass) {
							EClass generalEClass = (EClass) generalEClassifier;

							if (!specificEClass.isSuperTypeOf(generalEClass)) {
								specificEClass.getESuperTypes().add(
									generalEClass);
							}
						}
					}
				} else if (specificEClassifier instanceof EDataType) {
					EDataType specificEDataType = (EDataType) specificEClassifier;
					Classifier general = generalization.getGeneral();

					if (general != null) {
						EClassifier generalEClassifier = (EClassifier) doSwitch(general);

						if (generalEClassifier instanceof EDataType) {
							ExtendedMetaData.INSTANCE.setBaseType(
								specificEDataType,
								(EDataType) generalEClassifier);
						}
					}
				}
			}

			return super.caseGeneralization(generalization);
		}

		@Override
		public Object caseInterfaceRealization(
				InterfaceRealization interfaceRealization) {
			BehavioredClassifier implementingClassifier = interfaceRealization
				.getImplementingClassifier();

			if (implementingClassifier != null) {
				EClassifier implementingEClassifier = (EClassifier) doSwitch(implementingClassifier);

				if (implementingEClassifier instanceof EClass) {
					EClass implementingEClass = (EClass) implementingEClassifier;
					Interface contract = interfaceRealization.getContract();

					if (contract != null) {
						EClass contractEClass = (EClass) doSwitch(contract);

						if (contractEClass != null) {
							implementingEClass.getESuperTypes().add(
								contractEClass);
						}
					}
				}
			}

			return super.caseInterfaceRealization(interfaceRealization);
		}

		@Override
		public Object caseInterface(Interface interface_) {
			org.eclipse.uml2.uml.Package package_ = interface_
				.getNearestPackage();

			if (package_ != null) {
				EClass eClass = EcoreFactory.eINSTANCE.createEClass();
				elementToEModelElementMap.put(interface_, eClass);

				EPackage ePackage = (EPackage) doSwitch(package_);
				ePackage.getEClassifiers().add(eClass);

				setName(eClass, interface_);

				eClass.setAbstract(true);
				eClass.setInterface(true);

				defaultCase(interface_);

				return eClass;
			}

			return super.caseInterface(interface_);
		}

		@Override
		public Object caseMultiplicityElement(
				MultiplicityElement multiplicityElement) {
			Object eModelElement = elementToEModelElementMap
				.get(multiplicityElement);

			if (eModelElement instanceof ETypedElement) {
				ETypedElement eTypedElement = (ETypedElement) eModelElement;

				int upper = multiplicityElement.getUpper();

				if (eTypedElement.getUpperBound() != upper) {
					eTypedElement.setUpperBound(upper);
				}

				int lower = multiplicityElement.getLower();

				if (eTypedElement.getLowerBound() != lower) {
					eTypedElement.setLowerBound(lower);
				}

				eTypedElement.setOrdered(multiplicityElement.isOrdered());
				eTypedElement.setUnique(multiplicityElement.isUnique());

				return eTypedElement;
			} else {
				return super.caseMultiplicityElement(multiplicityElement);
			}
		}

		@Override
		public Object caseOperation(Operation operation) {
			Namespace namespace = operation.getNamespace();

			if (namespace instanceof org.eclipse.uml2.uml.Class
				|| namespace instanceof Interface) {

				EOperation eOperation = EcoreFactory.eINSTANCE
					.createEOperation();
				elementToEModelElementMap.put(operation, eOperation);

				EClass eClass = (EClass) doSwitch(namespace);
				eClass.getEOperations().add(eOperation);

				setName(eOperation, operation);

				EList<EClassifier> eExceptions = eOperation.getEExceptions();

				for (Type raisedException : operation.getRaisedExceptions()) {
					EClassifier eType = getEType(raisedException);

					if (eType != null) {
						eExceptions.add(eType);
					}
				}

				eOperation.setEType(getEType(operation.getType()));

				int upper = operation.getUpper();

				if (eOperation.getUpperBound() != upper) {
					eOperation.setUpperBound(upper);
				}

				int lower = operation.getLower();

				if (eOperation.getLowerBound() != lower) {
					eOperation.setLowerBound(lower);
				}

				eOperation.setOrdered(operation.isOrdered());
				eOperation.setUnique(operation.isUnique());

				defaultCase(operation);

				return eOperation;
			}

			return super.caseOperation(operation);
		}

		@Override
		public Object casePackage(org.eclipse.uml2.uml.Package package_) {
			EPackage ePackage = EcoreFactory.eINSTANCE.createEPackage();
			elementToEModelElementMap.put(package_, ePackage);

			if (!packages.contains(package_)) {
				org.eclipse.uml2.uml.Package nestingPackage = package_
					.getNestingPackage();

				if (nestingPackage != null) {
					((EPackage) doSwitch(nestingPackage)).getESubpackages()
						.add(ePackage);
				}
			}

			setName(ePackage, package_);

			if (isEmpty(ePackage.getNsPrefix())) {
				EPackage eSuperPackage = ePackage.getESuperPackage();

				ePackage.setNsPrefix((eSuperPackage == null
					? EMPTY_STRING
					: eSuperPackage.getNsPrefix() + '.') + ePackage.getName());
			}

			if (isEmpty(ePackage.getNsURI())) {
				ePackage.setNsURI("http:///" //$NON-NLS-1$
					+ ePackage.getNsPrefix().replace('.', '/') + ".ecore"); //$NON-NLS-1$
			}

			defaultCase(package_);

			return ePackage;
		}

		@Override
		public Object caseParameter(Parameter parameter) {
			Operation operation = parameter.getOperation();

			if (operation != null
				&& parameter.getDirection() != ParameterDirectionKind.RETURN_LITERAL) {

				EParameter eParameter = EcoreFactory.eINSTANCE
					.createEParameter();
				elementToEModelElementMap.put(parameter, eParameter);

				EOperation eOperation = (EOperation) doSwitch(operation);
				eOperation.getEParameters().add(eParameter);

				setName(eParameter, parameter);

				caseTypedElement(parameter);
				caseMultiplicityElement(parameter);

				defaultCase(parameter);

				return eParameter;
			}

			return super.caseParameter(parameter);
		}

		@Override
		public Object casePrimitiveType(PrimitiveType primitiveType) {
			org.eclipse.uml2.uml.Package package_ = primitiveType
				.getNearestPackage();

			if (package_ != null) {
				EDataType eDataType = EcoreFactory.eINSTANCE.createEDataType();
				elementToEModelElementMap.put(primitiveType, eDataType);

				EPackage ePackage = (EPackage) doSwitch(package_);
				ePackage.getEClassifiers().add(eDataType);

				setName(eDataType, primitiveType);

				eDataType.setInstanceClassName(eDataType.getName());

				defaultCase(primitiveType);

				return eDataType;
			}

			return super.casePrimitiveType(primitiveType);
		}

		@Override
		public Object caseDataType(DataType dataType) {
			org.eclipse.uml2.uml.Package package_ = dataType
				.getNearestPackage();

			if (package_ != null) {
				EClass eClass = EcoreFactory.eINSTANCE.createEClass();
				elementToEModelElementMap.put(dataType, eClass);

				EPackage ePackage = (EPackage) doSwitch(package_);
				ePackage.getEClassifiers().add(eClass);

				setName(eClass, dataType);

				defaultCase(dataType);

				return eClass;
			}

			return super.caseDataType(dataType);
		}

		@Override
		public Object caseProperty(Property property) {
			Namespace namespace = property.getNamespace();

			if (namespace instanceof org.eclipse.uml2.uml.Class
				|| namespace instanceof DataType
				|| namespace instanceof Interface) {

				EStructuralFeature eStructuralFeature = null;

				if (property.getType() instanceof DataType) {
					EAttribute eAttribute = (EAttribute) (eStructuralFeature = EcoreFactory.eINSTANCE
						.createEAttribute());
					elementToEModelElementMap.put(property, eAttribute);

					String default_ = property.getDefault();

					if (default_ != null) {
						eAttribute.setDefaultValueLiteral(default_);
					}
				} else {
					EReference eReference = (EReference) (eStructuralFeature = EcoreFactory.eINSTANCE
						.createEReference());
					elementToEModelElementMap.put(property, eStructuralFeature);

					eReference.setContainment(property.isComposite());
				}

				EClass eClass = (EClass) doSwitch(namespace);
				eClass.getEStructuralFeatures().add(eStructuralFeature);

				setName(eStructuralFeature, property);

				eStructuralFeature.setChangeable(!property.isReadOnly());

				eStructuralFeature.setDerived(property.isDerived());

				Property opposite = property.getOpposite();

				if (opposite != null) {
					EReference eOpposite = (EReference) doSwitch(opposite);

					if (eOpposite != null) {

						if (property.isDerived() && !eOpposite.isDerived()) {
							eOpposite.setDerived(true);

							if (DEBUG) {
								System.out.println("Made opposite " //$NON-NLS-1$
									+ getQualifiedText(eOpposite) + " derived"); //$NON-NLS-1$
							}
						}

						((EReference) eStructuralFeature)
							.setEOpposite(eOpposite);
					}
				}

				caseTypedElement(property);
				caseMultiplicityElement(property);

				defaultCase(property);

				return eStructuralFeature;
			}

			return super.caseProperty(property);
		}

		@Override
		public Object caseTypedElement(TypedElement typedElement) {
			Object eModelElement = elementToEModelElementMap.get(typedElement);

			if (eModelElement instanceof ETypedElement) {
				ETypedElement eTypedElement = (ETypedElement) eModelElement;

				eTypedElement.setEType(getEType(typedElement));

				return eTypedElement;
			}

			return super.caseTypedElement(typedElement);
		}

		@Override
		public Object defaultCase(EObject eObject) {

			for (EObject eContent : eObject.eContents()) {
				doSwitch(eContent);
			}

			return super.defaultCase(eObject);
		}

		@Override
		public Object doSwitch(EObject eObject) {

			if (!elementToEModelElementMap.containsKey(eObject)) {
				super.doSwitch(eObject);
			}

			return elementToEModelElementMap.get(eObject);
		}

		protected void processEcoreTaggedValue(EModelElement eModelElement,
				EStructuralFeature eStructuralFeature, Element element,
				Stereotype stereotype, String propertyName,
				Map<String, String> options, DiagnosticChain diagnostics,
				Map<Object, Object> context) {

			if (element.hasValue(stereotype, propertyName)) {
				Object value = element.getValue(stereotype, propertyName);

				if (OPTION__PROCESS.equals(options
					.get(OPTION__ECORE_TAGGED_VALUES))) {

					if (diagnostics != null) {
						diagnostics
							.add(new BasicDiagnostic(
								Diagnostic.INFO,
								UMLValidator.DIAGNOSTIC_SOURCE,
								ECORE_TAGGED_VALUE,
								UMLPlugin.INSTANCE
									.getString(
										"_UI_UML2EcoreConverter_ProcessEcoreTaggedValue_diagnostic", //$NON-NLS-1$
										getMessageSubstitutions(context,
											eModelElement, getTagDefinition(
												stereotype, propertyName),
											value)),
								new Object[]{eModelElement}));
					}

					if (eStructuralFeature != null) {
						eModelElement
							.eSet(
								eStructuralFeature,
								eStructuralFeature == EcorePackage.Literals.ENAMED_ELEMENT__NAME
									? getValidJavaIdentifier((String) value)
									: value);
					} else {

						if (propertyName == TAG_DEFINITION__XML_CONTENT_KIND) {
							Enumeration contentKindEnumeration = ((EnumerationLiteral) value)
								.getEnumeration();

							if (value == contentKindEnumeration
								.getOwnedLiteral(ENUMERATION_LITERAL__EMPTY)) {

								ExtendedMetaData.INSTANCE.setContentKind(
									(EClass) eModelElement,
									ExtendedMetaData.EMPTY_CONTENT);
							} else if (value == contentKindEnumeration
								.getOwnedLiteral(ENUMERATION_LITERAL__SIMPLE)) {

								ExtendedMetaData.INSTANCE.setContentKind(
									(EClass) eModelElement,
									ExtendedMetaData.SIMPLE_CONTENT);
							} else if (value == contentKindEnumeration
								.getOwnedLiteral(ENUMERATION_LITERAL__MIXED)) {

								ExtendedMetaData.INSTANCE.setContentKind(
									(EClass) eModelElement,
									ExtendedMetaData.MIXED_CONTENT);
							} else if (value == contentKindEnumeration
								.getOwnedLiteral(ENUMERATION_LITERAL__ELEMENT_ONLY)) {

								ExtendedMetaData.INSTANCE.setContentKind(
									(EClass) eModelElement,
									ExtendedMetaData.ELEMENT_ONLY_CONTENT);
							}
						} else if (propertyName == TAG_DEFINITION__XML_FEATURE_KIND) {
							Enumeration featureKindEnumeration = ((EnumerationLiteral) value)
								.getEnumeration();

							if (value == featureKindEnumeration
								.getOwnedLiteral(ENUMERATION_LITERAL__SIMPLE)) {

								ExtendedMetaData.INSTANCE.setFeatureKind(
									(EStructuralFeature) eModelElement,
									ExtendedMetaData.SIMPLE_FEATURE);
							} else if (value == featureKindEnumeration
								.getOwnedLiteral(ENUMERATION_LITERAL__ATTRIBUTE)) {

								ExtendedMetaData.INSTANCE.setFeatureKind(
									(EStructuralFeature) eModelElement,
									ExtendedMetaData.ATTRIBUTE_FEATURE);
							} else if (value == featureKindEnumeration
								.getOwnedLiteral(ENUMERATION_LITERAL__ATTRIBUTE_WILDCARD)) {

								ExtendedMetaData.INSTANCE
									.setFeatureKind(
										(EStructuralFeature) eModelElement,
										ExtendedMetaData.ATTRIBUTE_WILDCARD_FEATURE);
							} else if (value == featureKindEnumeration
								.getOwnedLiteral(ENUMERATION_LITERAL__ELEMENT)) {

								ExtendedMetaData.INSTANCE.setFeatureKind(
									(EStructuralFeature) eModelElement,
									ExtendedMetaData.ELEMENT_FEATURE);
							} else if (value == featureKindEnumeration
								.getOwnedLiteral(ENUMERATION_LITERAL__ELEMENT_WILDCARD)) {

								ExtendedMetaData.INSTANCE.setFeatureKind(
									(EStructuralFeature) eModelElement,
									ExtendedMetaData.ELEMENT_WILDCARD_FEATURE);
							} else if (value == featureKindEnumeration
								.getOwnedLiteral(ENUMERATION_LITERAL__GROUP)) {

								ExtendedMetaData.INSTANCE.setFeatureKind(
									(EStructuralFeature) eModelElement,
									ExtendedMetaData.GROUP_FEATURE);
							}
						} else if (propertyName == TAG_DEFINITION__XML_NAME) {

							if (eModelElement instanceof EClassifier) {
								ExtendedMetaData.INSTANCE
									.setName((EClassifier) eModelElement,
										(String) value);
							} else if (eModelElement instanceof EStructuralFeature) {
								ExtendedMetaData.INSTANCE.setName(
									(EStructuralFeature) eModelElement,
									(String) value);
							}
						} else if (propertyName == TAG_DEFINITION__XML_NAMESPACE) {
							ExtendedMetaData.INSTANCE.setNamespace(
								(EStructuralFeature) eModelElement,
								(String) value);
						} else if (propertyName == TAG_DEFINITION__VISIBILITY) {
							eStructuralFeature = (EStructuralFeature) eModelElement;
							boolean isChangeable = eStructuralFeature
								.isChangeable();
							boolean isMany = eStructuralFeature.isMany();
							boolean isUnsettable = eStructuralFeature
								.isUnsettable();

							Enumeration visibilityKindEnumeration = ((EnumerationLiteral) value)
								.getEnumeration();

							if (value == visibilityKindEnumeration
								.getOwnedLiteral(ENUMERATION_LITERAL__NONE)) {

								EcoreUtil.setSuppressedVisibility(
									eStructuralFeature, EcoreUtil.GET, true);

								if (isChangeable && !isMany) {
									EcoreUtil
										.setSuppressedVisibility(
											eStructuralFeature, EcoreUtil.SET,
											true);
								}

								if (isUnsettable) {
									EcoreUtil.setSuppressedVisibility(
										eStructuralFeature, EcoreUtil.IS_SET,
										true);

									if (isChangeable) {
										EcoreUtil.setSuppressedVisibility(
											eStructuralFeature,
											EcoreUtil.UNSET, true);
									}
								}
							} else if (value == visibilityKindEnumeration
								.getOwnedLiteral(ENUMERATION_LITERAL__READ_ONLY)) {

								if (!isMany && isChangeable) {
									EcoreUtil
										.setSuppressedVisibility(
											eStructuralFeature, EcoreUtil.SET,
											true);
								}

								if (isUnsettable) {
									EcoreUtil.setSuppressedVisibility(
										eStructuralFeature, EcoreUtil.IS_SET,
										true);

									if (isChangeable) {
										EcoreUtil.setSuppressedVisibility(
											eStructuralFeature,
											EcoreUtil.UNSET, true);
									}
								}
							} else if (value == visibilityKindEnumeration
								.getOwnedLiteral(ENUMERATION_LITERAL__READ_WRITE)) {

								if (isUnsettable) {
									EcoreUtil.setSuppressedVisibility(
										eStructuralFeature, EcoreUtil.IS_SET,
										true);

									if (isChangeable) {
										EcoreUtil.setSuppressedVisibility(
											eStructuralFeature,
											EcoreUtil.UNSET, true);
									}
								}
							} else if (value == visibilityKindEnumeration
								.getOwnedLiteral(ENUMERATION_LITERAL__READ_ONLY_UNSETTABLE)) {

								if (!isMany && isChangeable) {
									EcoreUtil
										.setSuppressedVisibility(
											eStructuralFeature, EcoreUtil.SET,
											true);
								}

								if (isUnsettable && isChangeable) {
									EcoreUtil.setSuppressedVisibility(
										eStructuralFeature, EcoreUtil.UNSET,
										true);
								}
							}
						}
					}
				} else if (OPTION__REPORT.equals(options
					.get(OPTION__ECORE_TAGGED_VALUES))
					&& diagnostics != null) {

					diagnostics
						.add(new BasicDiagnostic(
							Diagnostic.WARNING,
							UMLValidator.DIAGNOSTIC_SOURCE,
							ECORE_TAGGED_VALUE,
							UMLPlugin.INSTANCE
								.getString(
									"_UI_UML2EcoreConverter_ReportEcoreTaggedValue_diagnostic", //$NON-NLS-1$
									getMessageSubstitutions(context,
										eModelElement, getTagDefinition(
											stereotype, propertyName), value)),
							new Object[]{eModelElement}));
				}
			}
		}

		protected void processEcoreTaggedValues(EClassifier eClassifier,
				final Element element, final Map<String, String> options,
				final DiagnosticChain diagnostics,
				final Map<Object, Object> context) {
			Stereotype eClassifierStereotype = new EcoreSwitch<Stereotype>() {

				@Override
				public Stereotype caseEClass(EClass eClass) {
					Stereotype eClassStereotype = getAppliedEcoreStereotype(
						element, STEREOTYPE__E_CLASS);

					if (eClassStereotype != null) {
						processEcoreTaggedValue(eClass,
							EcorePackage.Literals.ENAMED_ELEMENT__NAME,
							element, eClassStereotype,
							TAG_DEFINITION__CLASS_NAME, options, diagnostics,
							context);

						processEcoreTaggedValue(eClass, null, element,
							eClassStereotype, TAG_DEFINITION__XML_CONTENT_KIND,
							options, diagnostics, context);
					}

					return eClassStereotype;
				}

				@Override
				public Stereotype caseEDataType(EDataType eDataType) {
					Stereotype eDataTypeStereotype = getAppliedEcoreStereotype(
						element, STEREOTYPE__E_DATA_TYPE);

					if (eDataTypeStereotype != null) {
						processEcoreTaggedValue(eDataType,
							EcorePackage.Literals.ENAMED_ELEMENT__NAME,
							element, eDataTypeStereotype,
							TAG_DEFINITION__DATA_TYPE_NAME, options,
							diagnostics, context);
					}

					return eDataTypeStereotype;
				}
			}.doSwitch(eClassifier);

			if (eClassifierStereotype != null) {
				processEcoreTaggedValue(eClassifier, null, element,
					eClassifierStereotype, TAG_DEFINITION__XML_NAME, options,
					diagnostics, context);

				processEcoreTaggedValue(eClassifier,
					EcorePackage.Literals.ECLASSIFIER__INSTANCE_CLASS_NAME,
					element, eClassifierStereotype,
					TAG_DEFINITION__INSTANCE_CLASS_NAME, options, diagnostics,
					context);
			}
		}

		protected void processEcoreTaggedValues(EEnum eEnum, Element element,
				Map<String, String> options, DiagnosticChain diagnostics,
				Map<Object, Object> context) {
			Stereotype eEnumStereotype = getAppliedEcoreStereotype(element,
				STEREOTYPE__E_ENUM);

			if (eEnumStereotype != null) {
				processEcoreTaggedValue(eEnum,
					EcorePackage.Literals.ENAMED_ELEMENT__NAME, element,
					eEnumStereotype, TAG_DEFINITION__ENUM_NAME, options,
					diagnostics, context);

				processEcoreTaggedValue(eEnum, null, element, eEnumStereotype,
					TAG_DEFINITION__XML_NAME, options, diagnostics, context);
			}
		}

		protected void processEcoreTaggedValues(EEnumLiteral eEnumLiteral,
				Element element, Map<String, String> options,
				DiagnosticChain diagnostics, Map<Object, Object> context) {
			Stereotype eEnumLiteralStereotype = getAppliedEcoreStereotype(
				element, STEREOTYPE__E_ENUM_LITERAL);

			if (eEnumLiteralStereotype != null) {
				processEcoreTaggedValue(eEnumLiteral,
					EcorePackage.Literals.ENAMED_ELEMENT__NAME, element,
					eEnumLiteralStereotype, TAG_DEFINITION__ENUM_LITERAL_NAME,
					options, diagnostics, context);
			}
		}

		protected void processEcoreTaggedValues(EOperation eOperation,
				Element element, Map<String, String> options,
				DiagnosticChain diagnostics, Map<Object, Object> context) {
			Stereotype eOperationStereotype = getAppliedEcoreStereotype(
				element, STEREOTYPE__E_OPERATION);

			if (eOperationStereotype != null) {
				processEcoreTaggedValue(eOperation,
					EcorePackage.Literals.ENAMED_ELEMENT__NAME, element,
					eOperationStereotype, TAG_DEFINITION__OPERATION_NAME,
					options, diagnostics, context);
			}
		}

		protected void processEcoreTaggedValues(EPackage ePackage,
				Element element, Map<String, String> options,
				DiagnosticChain diagnostics, Map<Object, Object> context) {
			Stereotype ePackageStereotype = getAppliedEcoreStereotype(element,
				STEREOTYPE__E_PACKAGE);

			if (ePackageStereotype != null) {
				processEcoreTaggedValue(ePackage,
					EcorePackage.Literals.ENAMED_ELEMENT__NAME, element,
					ePackageStereotype, TAG_DEFINITION__PACKAGE_NAME, options,
					diagnostics, context);

				processEcoreTaggedValue(ePackage,
					EcorePackage.Literals.EPACKAGE__NS_PREFIX, element,
					ePackageStereotype, TAG_DEFINITION__NS_PREFIX, options,
					diagnostics, context);

				if (isEmpty(ePackage.getNsPrefix())) {
					processEcoreTaggedValue(ePackage,
						EcorePackage.Literals.EPACKAGE__NS_PREFIX, element,
						ePackageStereotype, TAG_DEFINITION__BASE_PACKAGE,
						options, diagnostics, context);

					String nsPrefix = ePackage.getNsPrefix();

					if (!isEmpty(nsPrefix)) {
						ePackage.setNsPrefix(nsPrefix + '.'
							+ ePackage.getName());
					}
				}

				processEcoreTaggedValue(ePackage,
					EcorePackage.Literals.EPACKAGE__NS_URI, element,
					ePackageStereotype, TAG_DEFINITION__NS_URI, options,
					diagnostics, context);
			}
		}

		protected void processEcoreTaggedValues(EParameter eParameter,
				Element element, Map<String, String> options,
				DiagnosticChain diagnostics, Map<Object, Object> context) {
			Stereotype eParameterStereotype = getAppliedEcoreStereotype(
				element, STEREOTYPE__E_PARAMETER);

			if (eParameterStereotype != null) {
				processEcoreTaggedValue(eParameter,
					EcorePackage.Literals.ENAMED_ELEMENT__NAME, element,
					eParameterStereotype, TAG_DEFINITION__PARAMETER_NAME,
					options, diagnostics, context);
			}
		}

		protected void processEcoreTaggedValues(
				EStructuralFeature eStructuralFeature, final Element element,
				final Map<String, String> options,
				final DiagnosticChain diagnostics,
				final Map<Object, Object> context) {
			Stereotype eStructuralFeatureStereotype = new EcoreSwitch<Stereotype>() {

				@Override
				public Stereotype caseEAttribute(EAttribute eAttribute) {
					Stereotype eAttributeStereotype = getAppliedEcoreStereotype(
						element, STEREOTYPE__E_ATTRIBUTE);

					if (eAttributeStereotype != null) {
						processEcoreTaggedValue(eAttribute,
							EcorePackage.Literals.ENAMED_ELEMENT__NAME,
							element, eAttributeStereotype,
							TAG_DEFINITION__ATTRIBUTE_NAME, options,
							diagnostics, context);

						processEcoreTaggedValue(eAttribute,
							EcorePackage.Literals.EATTRIBUTE__ID, element,
							eAttributeStereotype, TAG_DEFINITION__IS_ID,
							options, diagnostics, context);
					}

					return eAttributeStereotype;
				}

				@Override
				public Stereotype caseEReference(EReference eReference) {
					Stereotype eReferenceStereotype = getAppliedEcoreStereotype(
						element, STEREOTYPE__E_REFERENCE);

					if (eReferenceStereotype != null) {
						processEcoreTaggedValue(eReference,
							EcorePackage.Literals.ENAMED_ELEMENT__NAME,
							element, eReferenceStereotype,
							TAG_DEFINITION__REFERENCE_NAME, options,
							diagnostics, context);

						processEcoreTaggedValue(eReference,
							EcorePackage.Literals.EREFERENCE__RESOLVE_PROXIES,
							element, eReferenceStereotype,
							TAG_DEFINITION__IS_RESOLVE_PROXIES, options,
							diagnostics, context);
					}

					return eReferenceStereotype;
				}
			}.doSwitch(eStructuralFeature);

			if (eStructuralFeatureStereotype != null) {
				processEcoreTaggedValue(eStructuralFeature,
					EcorePackage.Literals.ESTRUCTURAL_FEATURE__TRANSIENT,
					element, eStructuralFeatureStereotype,
					TAG_DEFINITION__IS_TRANSIENT, options, diagnostics, context);

				processEcoreTaggedValue(eStructuralFeature,
					EcorePackage.Literals.ESTRUCTURAL_FEATURE__UNSETTABLE,
					element, eStructuralFeatureStereotype,
					TAG_DEFINITION__IS_UNSETTABLE, options, diagnostics,
					context);

				processEcoreTaggedValue(eStructuralFeature,
					EcorePackage.Literals.ESTRUCTURAL_FEATURE__TRANSIENT,
					element, eStructuralFeatureStereotype,
					TAG_DEFINITION__IS_VOLATILE, options, diagnostics, context);

				processEcoreTaggedValue(eStructuralFeature, null, element,
					eStructuralFeatureStereotype, TAG_DEFINITION__XML_NAME,
					options, diagnostics, context);

				processEcoreTaggedValue(eStructuralFeature, null, element,
					eStructuralFeatureStereotype,
					TAG_DEFINITION__XML_NAMESPACE, options, diagnostics,
					context);

				processEcoreTaggedValue(eStructuralFeature, null, element,
					eStructuralFeatureStereotype,
					TAG_DEFINITION__XML_FEATURE_KIND, options, diagnostics,
					context);

				processEcoreTaggedValue(eStructuralFeature, null, element,
					eStructuralFeatureStereotype, TAG_DEFINITION__VISIBILITY,
					options, diagnostics, context);
			}
		}

		protected void processEcoreTaggedValues(
				final Map<String, String> options,
				final DiagnosticChain diagnostics,
				final Map<Object, Object> context) {

			for (final Map.Entry<Element, EModelElement> entry : elementToEModelElementMap
				.entrySet()) {
				EModelElement eModelElement = entry.getValue();

				new EcoreSwitch<Object>() {

					@Override
					public Object caseEClassifier(EClassifier eClassifier) {
						processEcoreTaggedValues(eClassifier, entry.getKey(),
							options, diagnostics, context);

						return eClassifier;
					}

					@Override
					public Object caseEEnum(EEnum eEnum) {
						processEcoreTaggedValues(eEnum, entry.getKey(),
							options, diagnostics, context);

						return eEnum;
					}

					@Override
					public Object caseEEnumLiteral(EEnumLiteral eEnumLiteral) {
						processEcoreTaggedValues(eEnumLiteral, entry.getKey(),
							options, diagnostics, context);

						return eEnumLiteral;
					}

					@Override
					public Object caseEOperation(EOperation eOperation) {
						processEcoreTaggedValues(eOperation, entry.getKey(),
							options, diagnostics, context);

						return eOperation;
					}

					@Override
					public Object caseEPackage(EPackage ePackage) {
						processEcoreTaggedValues(

						ePackage, entry.getKey(), options, diagnostics, context);

						return ePackage;
					}

					@Override
					public Object caseEParameter(EParameter eParameter) {
						processEcoreTaggedValues(eParameter, entry.getKey(),
							options, diagnostics, context);

						return eParameter;
					}

					@Override
					public Object caseEStructuralFeature(
							EStructuralFeature eStructuralFeature) {
						processEcoreTaggedValues(eStructuralFeature, entry
							.getKey(), options, diagnostics, context);

						return eStructuralFeature;
					}

				}.doSwitch(eModelElement);
			}
		}

		protected void processRedefiningOperations(Map<String, String> options,
				DiagnosticChain diagnostics, Map<Object, Object> context) {

			for (Map.Entry<Element, EModelElement> entry : elementToEModelElementMap
				.entrySet()) {
				Element element = entry.getKey();
				EModelElement eModelElement = entry.getValue();

				if (eModelElement instanceof EOperation
					&& element instanceof Operation) {

					Operation operation = (Operation) element;

					for (Operation redefinedOperation : operation
						.getRedefinedOperations()) {

						EOperation eOperation = (EOperation) elementToEModelElementMap
							.get(redefinedOperation);

						if (DEBUG) {
							System.out.println(getQualifiedText(eModelElement)
								+ " redefines " + getQualifiedText(eOperation)); //$NON-NLS-1$
						}

						if (OPTION__PROCESS.equals(options
							.get(OPTION__REDEFINING_OPERATIONS))) {

							if (diagnostics != null) {
								diagnostics
									.add(new BasicDiagnostic(
										Diagnostic.INFO,
										UMLValidator.DIAGNOSTIC_SOURCE,
										REDEFINING_OPERATION,
										UMLPlugin.INSTANCE
											.getString(
												"_UI_UML2EcoreConverter_ProcessRedefiningOperation_diagnostic", //$NON-NLS-1$
												getMessageSubstitutions(
													context, eModelElement,
													eOperation)), new Object[]{
											eModelElement, eOperation}));
							}

							getEAnnotation(eModelElement,
								ANNOTATION__REDEFINES, true).getReferences()
								.add(eOperation);
						} else if (OPTION__REPORT.equals(options
							.get(OPTION__REDEFINING_OPERATIONS))
							&& diagnostics != null) {

							diagnostics
								.add(new BasicDiagnostic(
									Diagnostic.WARNING,
									UMLValidator.DIAGNOSTIC_SOURCE,
									REDEFINING_OPERATION,
									UMLPlugin.INSTANCE
										.getString(
											"_UI_UML2EcoreConverter_ReportRedefiningOperation_diagnostic", //$NON-NLS-1$
											getMessageSubstitutions(context,
												eModelElement, eOperation)),
									new Object[]{eModelElement, eOperation}));
						}
					}
				}
			}
		}

		protected void processRedefiningProperties(Map<String, String> options,
				DiagnosticChain diagnostics, Map<Object, Object> context) {

			for (Map.Entry<Element, EModelElement> entry : elementToEModelElementMap
				.entrySet()) {

				Element element = entry.getKey();
				EModelElement eModelElement = entry.getValue();

				if (eModelElement instanceof EStructuralFeature
					&& element instanceof Property) {

					Property property = (Property) element;

					for (Property redefinedProperty : property
						.getRedefinedProperties()) {

						if (redefinedProperty.getOwningAssociation() == null) {
							EStructuralFeature eStructuralFeature = (EStructuralFeature) elementToEModelElementMap
								.get(redefinedProperty);

							if (DEBUG) {
								System.out
									.println(getQualifiedText(eModelElement)
										+ " redefines " //$NON-NLS-1$
										+ getQualifiedText(eStructuralFeature));
							}

							if (OPTION__PROCESS.equals(options
								.get(OPTION__REDEFINING_PROPERTIES))) {

								if (diagnostics != null) {
									diagnostics
										.add(new BasicDiagnostic(
											Diagnostic.INFO,
											UMLValidator.DIAGNOSTIC_SOURCE,
											REDEFINING_PROPERTY,
											UMLPlugin.INSTANCE
												.getString(
													"_UI_UML2EcoreConverter_ProcessRedefiningProperty_diagnostic", //$NON-NLS-1$
													getMessageSubstitutions(
														context, eModelElement,
														eStructuralFeature)),
											new Object[]{eModelElement,
												eStructuralFeature}));
								}

								getEAnnotation(eModelElement,
									ANNOTATION__REDEFINES, true)
									.getReferences().add(eStructuralFeature);
							} else if (OPTION__REPORT.equals(options
								.get(OPTION__REDEFINING_PROPERTIES))
								&& diagnostics != null) {

								diagnostics
									.add(new BasicDiagnostic(
										Diagnostic.WARNING,
										UMLValidator.DIAGNOSTIC_SOURCE,
										REDEFINING_PROPERTY,
										UMLPlugin.INSTANCE
											.getString(
												"_UI_UML2EcoreConverter_ReportRedefiningProperty_diagnostic", //$NON-NLS-1$
												getMessageSubstitutions(
													context, eModelElement,
													eStructuralFeature)),
										new Object[]{eModelElement,
											eStructuralFeature}));
							}
						}
					}
				}
			}
		}

		protected boolean isCompositeSubset(Property property) {

			for (Property subsettedProperty : property.getSubsettedProperties()) {

				if (subsettedProperty.isComposite()
					|| isCompositeSubset(subsettedProperty)) {

					return true;
				}
			}

			return false;
		}

		protected void processSubsettingProperties(Map<String, String> options,
				DiagnosticChain diagnostics, Map<Object, Object> context) {

			for (Map.Entry<Element, EModelElement> entry : elementToEModelElementMap
				.entrySet()) {
				Element element = entry.getKey();
				EModelElement eModelElement = entry.getValue();

				if (eModelElement instanceof EStructuralFeature
					&& element instanceof Property) {

					Property property = (Property) element;

					for (Property subsettedProperty : property
						.getSubsettedProperties()) {

						if (subsettedProperty.getOwningAssociation() == null) {
							EStructuralFeature subsettedEStructuralFeature = (EStructuralFeature) elementToEModelElementMap
								.get(subsettedProperty);

							if (DEBUG) {
								System.out
									.println(getQualifiedText(eModelElement)
										+ " subsets " //$NON-NLS-1$
										+ getQualifiedText(subsettedEStructuralFeature));
							}

							if (OPTION__PROCESS.equals(options
								.get(OPTION__SUBSETTING_PROPERTIES))) {

								if (diagnostics != null) {
									diagnostics
										.add(new BasicDiagnostic(
											Diagnostic.INFO,
											UMLValidator.DIAGNOSTIC_SOURCE,
											SUBSETTING_PROPERTY,
											UMLPlugin.INSTANCE
												.getString(
													"_UI_UML2EcoreConverter_ProcessSubsettingProperty_diagnostic", //$NON-NLS-1$
													getMessageSubstitutions(
														context, eModelElement,
														subsettedEStructuralFeature)),
											new Object[]{eModelElement,
												subsettedEStructuralFeature}));
								}

								if (!subsettedEStructuralFeature.isDerived()
									&& subsettedEStructuralFeature instanceof EReference) {

									EReference subsettedEReference = (EReference) subsettedEStructuralFeature;
									EReference eReference = (EReference) eModelElement;

									if (subsettedEReference.isContainment()
										|| isCompositeSubset(subsettedProperty)) {

										eReference.setContainment(false);
									}

									if (!eReference.isContainment()) {
										eReference
											.setResolveProxies(subsettedEReference
												.isResolveProxies());
									}
								}

								getEAnnotation(eModelElement,
									ANNOTATION__SUBSETS, true).getReferences()
									.add(
										elementToEModelElementMap
											.get(subsettedProperty));
							} else if (OPTION__REPORT.equals(options
								.get(OPTION__SUBSETTING_PROPERTIES))
								&& diagnostics != null) {

								diagnostics
									.add(new BasicDiagnostic(
										Diagnostic.WARNING,
										UMLValidator.DIAGNOSTIC_SOURCE,
										SUBSETTING_PROPERTY,
										UMLPlugin.INSTANCE
											.getString(
												"_UI_UML2EcoreConverter_ReportSubsettingProperty_diagnostic", //$NON-NLS-1$
												getMessageSubstitutions(
													context, eModelElement,
													subsettedEStructuralFeature)),
										new Object[]{eModelElement,
											subsettedEStructuralFeature}));
							}
						}
					}
				}
			}
		}

		protected void processUnionProperties(Map<String, String> options,
				DiagnosticChain diagnostics, Map<Object, Object> context) {

			for (Map.Entry<Element, EModelElement> entry : elementToEModelElementMap
				.entrySet()) {
				Element element = entry.getKey();
				EModelElement eModelElement = entry.getValue();

				if (eModelElement instanceof EStructuralFeature
					&& element instanceof Property
					&& ((Property) element).isDerivedUnion()) {

					EStructuralFeature eStructuralFeature = (EStructuralFeature) eModelElement;

					if (DEBUG) {
						System.out.println(getQualifiedText(eStructuralFeature)
							+ " is a union"); //$NON-NLS-1$
					}

					if (OPTION__PROCESS.equals(options
						.get(OPTION__UNION_PROPERTIES))) {

						if (diagnostics != null) {
							diagnostics
								.add(new BasicDiagnostic(
									Diagnostic.INFO,
									UMLValidator.DIAGNOSTIC_SOURCE,
									UNION_PROPERTY,
									UMLPlugin.INSTANCE
										.getString(
											"_UI_UML2EcoreConverter_ProcessUnionProperty_diagnostic", //$NON-NLS-1$
											getMessageSubstitutions(context,
												eStructuralFeature)),
									new Object[]{eStructuralFeature}));
						}

						getEAnnotation(eStructuralFeature, ANNOTATION__UNION,
							true);

						eStructuralFeature.setChangeable(false);
						eStructuralFeature.setVolatile(true);
					} else if (OPTION__REPORT.equals(options
						.get(OPTION__UNION_PROPERTIES))
						&& diagnostics != null) {

						diagnostics
							.add(new BasicDiagnostic(
								Diagnostic.WARNING,
								UMLValidator.DIAGNOSTIC_SOURCE,
								UNION_PROPERTY,
								UMLPlugin.INSTANCE
									.getString(
										"_UI_UML2EcoreConverter_ReportUnionProperty_diagnostic", //$NON-NLS-1$
										getMessageSubstitutions(context,
											eModelElement)),
								new Object[]{eModelElement}));
					}
				}
			}
		}

		protected void processDerivedFeatures(Map<String, String> options,
				DiagnosticChain diagnostics, Map<Object, Object> context) {

			for (EModelElement eModelElement : elementToEModelElementMap
				.values()) {

				if (eModelElement instanceof EStructuralFeature) {
					EStructuralFeature.Internal eStructuralFeature = (EStructuralFeature.Internal) eModelElement;

					if (eStructuralFeature.isDerived()
						&& (eStructuralFeature.isContainment() || !eStructuralFeature
							.isVolatile())) {

						if (OPTION__PROCESS.equals(options
							.get(OPTION__DERIVED_FEATURES))) {

							if (diagnostics != null) {
								diagnostics
									.add(new BasicDiagnostic(
										Diagnostic.INFO,
										UMLValidator.DIAGNOSTIC_SOURCE,
										DERIVED_FEATURE,
										UMLPlugin.INSTANCE
											.getString(
												"_UI_UML2EcoreConverter_ProcessDerivedFeature_diagnostic", //$NON-NLS-1$
												getMessageSubstitutions(
													context, eStructuralFeature)),
										new Object[]{eStructuralFeature}));
							}

							if (eStructuralFeature instanceof EReference) {
								((EReference) eStructuralFeature)
									.setContainment(false);
							}

							eStructuralFeature.setVolatile(true);
						} else if (OPTION__REPORT.equals(options
							.get(OPTION__DERIVED_FEATURES))
							&& diagnostics != null) {

							diagnostics
								.add(new BasicDiagnostic(
									Diagnostic.WARNING,
									UMLValidator.DIAGNOSTIC_SOURCE,
									DERIVED_FEATURE,
									UMLPlugin.INSTANCE
										.getString(
											"_UI_UML2EcoreConverter_ReportDerivedFeature_diagnostic", //$NON-NLS-1$
											getMessageSubstitutions(context,
												eStructuralFeature)),
									new Object[]{eStructuralFeature}));
						}
					}
				}
			}
		}

		protected void ensureConformity(ETypedElement eTypedElement,
				ETypedElement otherETypedElement) {

			if (eTypedElement.isRequired() != otherETypedElement.isRequired()) {
				int lowerBound = eTypedElement.getLowerBound();
				int otherLowerBound = otherETypedElement.getLowerBound();

				int lesserLowerBound = getLesserLowerBound(otherLowerBound,
					lowerBound);

				if (lesserLowerBound != otherLowerBound) {

					if (DEBUG) {
						System.err.println("Changed lower bound of " //$NON-NLS-1$
							+ getQualifiedText(otherETypedElement) + " from " //$NON-NLS-1$
							+ otherLowerBound + " to " //$NON-NLS-1$
							+ lesserLowerBound);
					}

					otherETypedElement.setLowerBound(lesserLowerBound);
				}

				if (lesserLowerBound != lowerBound) {

					if (DEBUG) {
						System.out.println("Changed lower bound of " //$NON-NLS-1$
							+ getQualifiedText(eTypedElement) + " from " //$NON-NLS-1$
							+ lowerBound + " to " //$NON-NLS-1$
							+ lesserLowerBound);
					}

					eTypedElement.setLowerBound(lesserLowerBound);
				}
			}

			boolean isMany = eTypedElement.isMany();
			boolean otherIsMany = otherETypedElement.isMany();

			if (isMany != otherIsMany) {
				int upperBound = eTypedElement.getUpperBound();
				int otherUpperBound = otherETypedElement.getUpperBound();

				int greaterUpperBound = getGreaterUpperBound(otherUpperBound,
					upperBound);

				if (greaterUpperBound != otherUpperBound) {

					if (DEBUG) {
						System.err.println("Changed upper bound of " //$NON-NLS-1$
							+ getQualifiedText(otherETypedElement) + " from " //$NON-NLS-1$
							+ otherUpperBound + " to " //$NON-NLS-1$
							+ greaterUpperBound);
					}

					otherETypedElement.setUpperBound(greaterUpperBound);
				}

				if (greaterUpperBound != upperBound) {

					if (DEBUG) {
						System.out.println("Changed upper bound of " //$NON-NLS-1$
							+ getQualifiedText(eTypedElement) + " from " //$NON-NLS-1$
							+ upperBound + " to " //$NON-NLS-1$
							+ greaterUpperBound);
					}

					eTypedElement.setUpperBound(greaterUpperBound);
				}
			}

			if (!isMany && !otherIsMany) {
				EClassifier eType = eTypedElement.getEType();
				EClassifier otherEType = otherETypedElement.getEType();

				EClassifier commonEType = getCommonEType(otherEType, eType);

				if (commonEType != otherEType) {

					if (DEBUG) {
						System.err.println("Changed type of " //$NON-NLS-1$
							+ getQualifiedText(otherETypedElement)
							+ " from " //$NON-NLS-1$
							+ getQualifiedText(otherEType)
							+ " to " + getQualifiedText(commonEType)); //$NON-NLS-1$
					}

					otherETypedElement.setEType(commonEType);
				}

				if (commonEType != eType) {

					if (DEBUG) {
						System.out.println("Changed type of " //$NON-NLS-1$
							+ getQualifiedText(eTypedElement)
							+ " from " //$NON-NLS-1$
							+ getQualifiedText(eType)
							+ " to " + getQualifiedText(commonEType)); //$NON-NLS-1$
					}

					eTypedElement.setEType(commonEType);
				}
			}

			eTypedElement.setOrdered(otherETypedElement.isOrdered());

			eTypedElement.setUnique(otherETypedElement.isUnique());
		}

		protected void qualifyName(ENamedElement eNamedElement) {
			EObject eContainer = eNamedElement.eContainer();

			if (eContainer instanceof ENamedElement) {
				String qualifiedName = ((ENamedElement) eContainer).getName()
					+ '_' + eNamedElement.getName();

				if (DEBUG) {
					System.err.println("Qualified " //$NON-NLS-1$
						+ getQualifiedText(eNamedElement) + " as " //$NON-NLS-1$
						+ qualifiedName);
				}

				eNamedElement.setName(qualifiedName);
			}
		}

		protected void processDuplicateOperations(Map<String, String> options,
				DiagnosticChain diagnostics, Map<Object, Object> context) {
			List<EOperation> operationsToDuplicate = new UniqueEList.FastCompare<EOperation>();

			for (EModelElement eModelElement : elementToEModelElementMap
				.values()) {

				if (eModelElement instanceof EClass) {
					EClass eClass = (EClass) eModelElement;

					for (Iterator<EOperation> eOperations = eClass
						.getEOperations().iterator(); eOperations.hasNext();) {
						EOperation eOperation = eOperations.next();

						for (EOperation otherEOperation : eClass
							.getEAllOperations()) {

							if (otherEOperation == eOperation) {
								break;
							} else if (new SignatureMatcher(eOperation)
								.matches(otherEOperation)) {

								if (OPTION__PROCESS.equals(options
									.get(OPTION__DUPLICATE_OPERATIONS))) {

									if (diagnostics != null) {
										diagnostics
											.add(new BasicDiagnostic(
												Diagnostic.INFO,
												UMLValidator.DIAGNOSTIC_SOURCE,
												DUPLICATE_OPERATION,
												UMLPlugin.INSTANCE
													.getString(
														"_UI_UML2EcoreConverter_ProcessDuplicateOperation_diagnostic", //$NON-NLS-1$
														getMessageSubstitutions(
															context,
															eOperation,
															otherEOperation)),
												new Object[]{eClass,
													otherEOperation}));
									}

									operationsToDuplicate.add(eOperation);

									ensureConformity(eOperation,
										otherEOperation);

									List<EObject> redefinedOperations = getEAnnotation(
										eOperation, ANNOTATION__REDEFINES, true)
										.getReferences();

									if (!redefinedOperations
										.contains(otherEOperation)) {

										redefinedOperations
											.add(otherEOperation);
									}
								} else if (OPTION__DISCARD.equals(options
									.get(OPTION__DUPLICATE_OPERATIONS))) {

									if (diagnostics != null) {
										diagnostics
											.add(new BasicDiagnostic(
												Diagnostic.WARNING,
												UMLValidator.DIAGNOSTIC_SOURCE,
												DUPLICATE_OPERATION,
												UMLPlugin.INSTANCE
													.getString(
														"_UI_UML2EcoreConverter_DiscardDuplicateOperation_diagnostic", //$NON-NLS-1$
														getMessageSubstitutions(
															context,
															eOperation,
															otherEOperation)),
												new Object[]{eClass,
													otherEOperation}));
									}

									eOperations.remove();
									break;
								} else if (OPTION__REPORT.equals(options
									.get(OPTION__DUPLICATE_OPERATIONS))
									&& diagnostics != null) {

									diagnostics
										.add(new BasicDiagnostic(
											Diagnostic.ERROR,
											UMLValidator.DIAGNOSTIC_SOURCE,
											DUPLICATE_OPERATION,
											UMLPlugin.INSTANCE
												.getString(
													"_UI_UML2EcoreConverter_ReportDuplicateOperation_diagnostic", //$NON-NLS-1$
													getMessageSubstitutions(
														context, eOperation,
														otherEOperation)),
											new Object[]{eOperation,
												otherEOperation}));
								}
							}
						}
					}
				}
			}

			for (EOperation eOperation : operationsToDuplicate) {
				getEAnnotation(eOperation.getEContainingClass(),
					ANNOTATION__DUPLICATES, true).getContents().add(eOperation);
			}
		}

		protected void processDuplicateOperationInheritance(
				Map<String, String> options, DiagnosticChain diagnostics,
				Map<Object, Object> context) {

			for (EModelElement eModelElement : elementToEModelElementMap
				.values()) {

				if (eModelElement instanceof EClass) {
					EClass eClass = (EClass) eModelElement;

					if (eClass.getESuperTypes().size() > 1) {
						Iterator<EClass> eSuperTypes = eClass.getESuperTypes()
							.iterator();
						eSuperTypes.next();

						while (eSuperTypes.hasNext()) {
							EClass mixinEClass = eSuperTypes.next();

							mixinEOperationLoop : for (EOperation mixinEOperation : mixinEClass
								.getEAllOperations()) {

								for (EOperation eOperation : eClass
									.getEAllOperations()) {

									if (eOperation == mixinEOperation) {
										break;
									} else if (new SignatureMatcher(
										mixinEOperation).matches(eOperation)) {

										if (OPTION__PROCESS
											.equals(options
												.get(OPTION__DUPLICATE_OPERATION_INHERITANCE))) {

											if (diagnostics != null) {
												diagnostics
													.add(new BasicDiagnostic(
														Diagnostic.INFO,
														UMLValidator.DIAGNOSTIC_SOURCE,
														DUPLICATE_OPERATION_INHERITANCE,
														UMLPlugin.INSTANCE
															.getString(
																"_UI_UML2EcoreConverter_ProcessDuplicateOperationInheritance_diagnostic", //$NON-NLS-1$
																getMessageSubstitutions(
																	context,
																	eClass,
																	eOperation,
																	mixinEOperation)),
														new Object[]{eClass,
															eOperation,
															mixinEOperation}));
											}

											qualifyName(mixinEOperation);

											List<EObject> redefinedOperations = getEAnnotation(
												mixinEOperation,
												ANNOTATION__REDEFINES, true)
												.getReferences();

											if (!redefinedOperations
												.contains(eOperation)) {

												redefinedOperations
													.add(eOperation);
											}
										} else if (OPTION__DISCARD
											.equals(options
												.get(OPTION__DUPLICATE_OPERATION_INHERITANCE))) {

											if (diagnostics != null) {
												diagnostics
													.add(new BasicDiagnostic(
														Diagnostic.WARNING,
														UMLValidator.DIAGNOSTIC_SOURCE,
														DUPLICATE_OPERATION_INHERITANCE,
														UMLPlugin.INSTANCE
															.getString(
																"_UI_UML2EcoreConverter_DiscardDuplicateOperationInheritance_diagnostic", //$NON-NLS-1$
																getMessageSubstitutions(
																	context,
																	eClass,
																	eOperation,
																	mixinEOperation)),
														new Object[]{eClass,
															eOperation,
															mixinEOperation}));
											}

											eSuperTypes.remove();
											break mixinEOperationLoop;
										} else if (OPTION__REPORT
											.equals(options
												.get(OPTION__DUPLICATE_OPERATION_INHERITANCE))
											&& diagnostics != null) {

											diagnostics
												.add(new BasicDiagnostic(
													Diagnostic.ERROR,
													UMLValidator.DIAGNOSTIC_SOURCE,
													DUPLICATE_OPERATION_INHERITANCE,
													UMLPlugin.INSTANCE
														.getString(
															"_UI_UML2EcoreConverter_ReportDuplicateOperationInheritance_diagnostic", //$NON-NLS-1$
															getMessageSubstitutions(
																context,
																eClass,
																eOperation,
																mixinEOperation)),
													new Object[]{eClass,
														eOperation,
														mixinEOperation}));
										}
									}
								}
							}
						}
					}
				}
			}
		}

		protected void processDuplicateFeatures(Map<String, String> options,
				DiagnosticChain diagnostics, Map<Object, Object> context) {
			EList<EStructuralFeature.Internal> featuresToDuplicate = new UniqueEList.FastCompare<EStructuralFeature.Internal>();
			EList<EStructuralFeature> featuresToRemove = new UniqueEList.FastCompare<EStructuralFeature>();

			for (EModelElement eModelElement : elementToEModelElementMap
				.values()) {

				if (eModelElement instanceof EClass) {
					EClass eClass = (EClass) eModelElement;

					for (Iterator<EStructuralFeature> eStructuralFeatures = eClass
						.getEStructuralFeatures().iterator(); eStructuralFeatures
						.hasNext();) {

						EStructuralFeature.Internal eStructuralFeature = (EStructuralFeature.Internal) eStructuralFeatures
							.next();

						for (EStructuralFeature otherEStructuralFeature : eClass
							.getEAllStructuralFeatures()) {

							if (otherEStructuralFeature == eStructuralFeature) {
								break;
							} else if (new NameMatcher(eStructuralFeature)
								.matches(otherEStructuralFeature)) {

								if (OPTION__PROCESS.equals(options
									.get(OPTION__DUPLICATE_FEATURES))) {

									if (diagnostics != null) {
										diagnostics
											.add(new BasicDiagnostic(
												Diagnostic.INFO,
												UMLValidator.DIAGNOSTIC_SOURCE,
												DUPLICATE_FEATURE,
												UMLPlugin.INSTANCE
													.getString(
														"_UI_UML2EcoreConverter_ProcessDuplicateFeature_diagnostic", //$NON-NLS-1$
														getMessageSubstitutions(
															context,
															eStructuralFeature,
															otherEStructuralFeature)),
												new Object[]{
													eStructuralFeature,
													otherEStructuralFeature}));
									}

									if (!featuresToDuplicate
										.contains(eStructuralFeature)) {

										EStructuralFeature.Internal duplicateEStructuralFeature = otherEStructuralFeature
											.isDerived()
											&& !eStructuralFeature.isDerived()
											? (EStructuralFeature.Internal) otherEStructuralFeature
											: eStructuralFeature;

										if (DEBUG
											&& duplicateEStructuralFeature == otherEStructuralFeature) {

											System.err
												.println("Non-derived feature " //$NON-NLS-1$
													+ getQualifiedText(eStructuralFeature)
													+ " is a duplicate of derived feature " //$NON-NLS-1$
													+ getQualifiedText(otherEStructuralFeature));
										}

										featuresToDuplicate
											.add(duplicateEStructuralFeature);

										ensureConformity(eStructuralFeature,
											otherEStructuralFeature);
									}

									EList<EObject> redefinedFeatures = getEAnnotation(
										eStructuralFeature,
										ANNOTATION__REDEFINES, true)
										.getReferences();

									if (!redefinedFeatures
										.contains(otherEStructuralFeature)) {

										redefinedFeatures
											.add(otherEStructuralFeature);
									}
								} else if (OPTION__DISCARD.equals(options
									.get(OPTION__DUPLICATE_FEATURES))) {

									if (diagnostics != null) {
										diagnostics
											.add(new BasicDiagnostic(
												Diagnostic.WARNING,
												UMLValidator.DIAGNOSTIC_SOURCE,
												DUPLICATE_FEATURE,
												UMLPlugin.INSTANCE
													.getString(
														"_UI_UML2EcoreConverter_DiscardDuplicateFeature_diagnostic", //$NON-NLS-1$
														getMessageSubstitutions(
															context,
															eStructuralFeature,
															otherEStructuralFeature)),
												new Object[]{eClass,
													otherEStructuralFeature}));
									}

									EReference eOpposite = eStructuralFeature
										.getEOpposite();

									if (eOpposite != null) {
										featuresToRemove.add(eOpposite);
									}

									eStructuralFeatures.remove();
									break;
								} else if (OPTION__REPORT.equals(options
									.get(OPTION__DUPLICATE_FEATURES))
									&& diagnostics != null) {

									diagnostics
										.add(new BasicDiagnostic(
											Diagnostic.ERROR,
											UMLValidator.DIAGNOSTIC_SOURCE,
											DUPLICATE_FEATURE,
											UMLPlugin.INSTANCE
												.getString(
													"_UI_UML2EcoreConverter_ReportDuplicateFeature_diagnostic", //$NON-NLS-1$
													getMessageSubstitutions(
														context,
														eStructuralFeature,
														otherEStructuralFeature)),
											new Object[]{eStructuralFeature,
												otherEStructuralFeature}));
								}
							}
						}
					}
				}
			}

			for (EStructuralFeature.Internal eStructuralFeature : featuresToDuplicate) {
				getEAnnotation(eStructuralFeature.getEContainingClass(),
					ANNOTATION__DUPLICATES, true).getContents().add(
					eStructuralFeature);

				EReference eOpposite = eStructuralFeature.getEOpposite();

				if (eOpposite != null
					&& !featuresToDuplicate.contains(eOpposite)) {

					eOpposite.setEOpposite(null);

					if (eStructuralFeature.isContainment()) {
						eOpposite.setChangeable(false);
						eOpposite.setTransient(true);
					}

					eOpposite.setVolatile(true);
				}
			}

			for (EStructuralFeature eStructuralFeature : featuresToRemove) {
				EClass eContainingClass = eStructuralFeature
					.getEContainingClass();

				if (eContainingClass != null) {
					eContainingClass.getEStructuralFeatures().remove(
						eStructuralFeature);
				}
			}
		}

		protected void processDuplicateFeatureInheritance(
				Map<String, String> options, DiagnosticChain diagnostics,
				Map<Object, Object> context) {

			for (EModelElement eModelElement : elementToEModelElementMap
				.values()) {

				if (eModelElement instanceof EClass) {
					EClass eClass = (EClass) eModelElement;

					if (eClass.getESuperTypes().size() > 1) {
						Iterator<EClass> eSuperTypes = eClass.getESuperTypes()
							.iterator();
						eSuperTypes.next();

						while (eSuperTypes.hasNext()) {
							EClass mixinEClass = eSuperTypes.next();

							mixinEStructuralFeatureLoop : for (EStructuralFeature mixinEStructuralFeature : mixinEClass
								.getEAllStructuralFeatures()) {

								for (EStructuralFeature eStructuralFeature : eClass
									.getEAllStructuralFeatures()) {

									if (eStructuralFeature == mixinEStructuralFeature) {
										break;
									} else if (new NameMatcher(
										mixinEStructuralFeature)
										.matches(eStructuralFeature)) {

										if (OPTION__PROCESS
											.equals(options
												.get(OPTION__DUPLICATE_FEATURE_INHERITANCE))) {

											if (diagnostics != null) {
												diagnostics
													.add(new BasicDiagnostic(
														Diagnostic.INFO,
														UMLValidator.DIAGNOSTIC_SOURCE,
														DUPLICATE_FEATURE_INHERITANCE,
														UMLPlugin.INSTANCE
															.getString(
																"_UI_UML2EcoreConverter_ProcessDuplicateFeatureInheritance_diagnostic", //$NON-NLS-1$
																getMessageSubstitutions(
																	context,
																	eClass,
																	eStructuralFeature,
																	mixinEStructuralFeature)),
														new Object[]{eClass,
															eStructuralFeature,
															mixinEStructuralFeature}));
											}

											qualifyName(mixinEStructuralFeature);

											EList<EObject> redefinedFeatures = getEAnnotation(
												mixinEStructuralFeature,
												ANNOTATION__REDEFINES, true)
												.getReferences();

											if (!redefinedFeatures
												.contains(eStructuralFeature)) {

												redefinedFeatures
													.add(eStructuralFeature);
											}
										} else if (OPTION__DISCARD
											.equals(options
												.get(OPTION__DUPLICATE_FEATURE_INHERITANCE))) {

											if (diagnostics != null) {
												diagnostics
													.add(new BasicDiagnostic(
														Diagnostic.WARNING,
														UMLValidator.DIAGNOSTIC_SOURCE,
														DUPLICATE_FEATURE_INHERITANCE,
														UMLPlugin.INSTANCE
															.getString(
																"_UI_UML2EcoreConverter_DiscardDuplicateFeatureInheritance_diagnostic", //$NON-NLS-1$
																getMessageSubstitutions(
																	context,
																	eClass,
																	eStructuralFeature,
																	mixinEStructuralFeature)),
														new Object[]{eClass,
															eStructuralFeature,
															mixinEStructuralFeature}));
											}

											eSuperTypes.remove();
											break mixinEStructuralFeatureLoop;
										} else if (OPTION__REPORT
											.equals(options
												.get(OPTION__DUPLICATE_FEATURE_INHERITANCE))
											&& diagnostics != null) {

											diagnostics
												.add(new BasicDiagnostic(
													Diagnostic.ERROR,
													UMLValidator.DIAGNOSTIC_SOURCE,
													DUPLICATE_FEATURE_INHERITANCE,
													UMLPlugin.INSTANCE
														.getString(
															"_UI_UML2EcoreConverter_ReportDuplicateFeatureInheritance_diagnostic", //$NON-NLS-1$
															getMessageSubstitutions(
																context,
																eClass,
																eStructuralFeature,
																mixinEStructuralFeature)),
													new Object[]{eClass,
														eStructuralFeature,
														mixinEStructuralFeature}));
										}
									}
								}
							}
						}
					}
				}
			}
		}

		protected void processSuperClassOrder(Map<String, String> options,
				DiagnosticChain diagnostics, Map<Object, Object> context) {
			Comparator<EClass> eClassComparator = new Comparator<EClass>() {

				public int compare(EClass eClass, EClass otherEClass) {
					int eAllStructuralFeaturesSize = eClass
						.getEAllStructuralFeatures().size();
					int otherEAllStructuralFeaturesSize = otherEClass
						.getEAllStructuralFeatures().size();

					return eAllStructuralFeaturesSize < otherEAllStructuralFeaturesSize
						? 1
						: (otherEAllStructuralFeaturesSize < eAllStructuralFeaturesSize
							? -1
							: eClass.getName().compareTo(otherEClass.getName()));
				}
			};

			for (Map.Entry<Element, EModelElement> entry : elementToEModelElementMap
				.entrySet()) {
				Element key = entry.getKey();
				EModelElement value = entry.getValue();

				if (key instanceof Classifier && value instanceof EClass) {
					EClass eClass = (EClass) value;
					EList<EClass> eSuperTypes = eClass.getESuperTypes();

					List<EClass> extendSuperClasses = new ArrayList<EClass>();
					List<EClass> unspecifiedSuperClasses = new ArrayList<EClass>();
					List<EClass> mixinSuperClasses = new ArrayList<EClass>();

					for (Generalization generalization : ((Classifier) key)
						.getGeneralizations()) {
						Classifier general = generalization.getGeneral();

						if (general != null) {
							EModelElement eModelElement = elementToEModelElementMap
								.get(general);

							if (eSuperTypes.contains(eModelElement)) {

								if (generalization.hasKeyword("extend")) { //$NON-NLS-1$
									extendSuperClasses
										.add((EClass) eModelElement);
								} else if (generalization.hasKeyword("mixin")) { //$NON-NLS-1$
									mixinSuperClasses
										.add((EClass) eModelElement);
								} else {
									unspecifiedSuperClasses
										.add((EClass) eModelElement);
								}
							}
						}

					}

					Collections.sort(extendSuperClasses, eClassComparator);
					Collections.sort(unspecifiedSuperClasses, eClassComparator);
					Collections.sort(mixinSuperClasses, eClassComparator);

					List<EClass> superClasses = new UniqueEList.FastCompare<EClass>(
						extendSuperClasses);
					superClasses.addAll(unspecifiedSuperClasses);
					superClasses.addAll(mixinSuperClasses);

					if (!superClasses.equals(eSuperTypes)) {

						if (OPTION__PROCESS.equals(options
							.get(OPTION__SUPER_CLASS_ORDER))) {

							if (diagnostics != null) {
								diagnostics
									.add(new BasicDiagnostic(
										Diagnostic.INFO,
										UMLValidator.DIAGNOSTIC_SOURCE,
										SUPER_CLASS_ORDER,
										UMLPlugin.INSTANCE
											.getString(
												"_UI_UML2EcoreConverter_ProcessSuperClassOrder_diagnostic", //$NON-NLS-1$
												getMessageSubstitutions(
													context, eClass)),
										new Object[]{eClass}));
							}

							for (ListIterator<EClass> sc = superClasses
								.listIterator(); sc.hasNext();) {

								EClass superClass = sc.next();
								eSuperTypes
									.move(sc.previousIndex(), superClass);
							}
						}
						if (OPTION__REPORT.equals(options
							.get(OPTION__SUPER_CLASS_ORDER))
							&& diagnostics != null) {

							diagnostics
								.add(new BasicDiagnostic(
									Diagnostic.WARNING,
									UMLValidator.DIAGNOSTIC_SOURCE,
									SUPER_CLASS_ORDER,
									UMLPlugin.INSTANCE
										.getString(
											"_UI_UML2EcoreConverter_ReportSuperClassOrder_diagnostic", //$NON-NLS-1$
											getMessageSubstitutions(context,
												eClass)), new Object[]{eClass}));
						}
					}
				}
			}
		}

		protected void processAnnotationDetails(
				final Map<String, String> options,
				final DiagnosticChain diagnostics,
				final Map<Object, Object> context) {

			for (final Map.Entry<Element, EModelElement> entry : elementToEModelElementMap
				.entrySet()) {
				EModelElement eModelElement = entry.getValue();

				if (eModelElement != null) {
					Element element = entry.getKey();

					for (EAnnotation eAnnotation : element.getEAnnotations()) {
						EMap<String, String> details = eAnnotation.getDetails();

						if (!details.isEmpty()) {

							if (OPTION__PROCESS.equals(options
								.get(OPTION__ANNOTATION_DETAILS))) {

								if (diagnostics != null) {
									diagnostics
										.add(new BasicDiagnostic(
											Diagnostic.INFO,
											UMLValidator.DIAGNOSTIC_SOURCE,
											ANNOTATION_DETAILS,
											UMLPlugin.INSTANCE
												.getString(
													"_UI_UML2EcoreConverter_ProcessAnnotationDetails_diagnostic", //$NON-NLS-1$
													getMessageSubstitutions(
														context, eModelElement,
														eAnnotation.getSource())),
											new Object[]{eModelElement}));
								}

								getEAnnotation(eModelElement,
									eAnnotation.getSource(), true).getDetails()
									.putAll(details.map());
							} else if (OPTION__REPORT.equals(options
								.get(OPTION__ANNOTATION_DETAILS))
								&& diagnostics != null) {

								diagnostics
									.add(new BasicDiagnostic(
										Diagnostic.WARNING,
										UMLValidator.DIAGNOSTIC_SOURCE,
										ANNOTATION_DETAILS,
										UMLPlugin.INSTANCE
											.getString(
												"_UI_UML2EcoreConverter_ReportAnnotationDetails_diagnostic", //$NON-NLS-1$
												getMessageSubstitutions(
													context, eModelElement,
													eAnnotation.getSource())),
										new Object[]{eModelElement}));
							}
						}
					}
				}
			}
		}

		protected void processOptions(Map<String, String> options,
				DiagnosticChain diagnostics, Map<Object, Object> context) {

			if (!OPTION__IGNORE
				.equals(options.get(OPTION__ECORE_TAGGED_VALUES))) {

				processEcoreTaggedValues(options, diagnostics, context);
			}

			if (!OPTION__IGNORE.equals(options
				.get(OPTION__REDEFINING_OPERATIONS))) {

				processRedefiningOperations(options, diagnostics, context);
			}

			if (!OPTION__IGNORE.equals(options
				.get(OPTION__REDEFINING_PROPERTIES))) {

				processRedefiningProperties(options, diagnostics, context);
			}

			if (!OPTION__IGNORE.equals(options
				.get(OPTION__SUBSETTING_PROPERTIES))) {

				processSubsettingProperties(options, diagnostics, context);
			}

			if (!OPTION__IGNORE.equals(options.get(OPTION__DERIVED_FEATURES))) {
				processDerivedFeatures(options, diagnostics, context);
			}

			if (!OPTION__IGNORE.equals(options.get(OPTION__UNION_PROPERTIES))) {
				processUnionProperties(options, diagnostics, context);
			}

			if (!OPTION__IGNORE.equals(options
				.get(OPTION__DUPLICATE_OPERATIONS))) {

				processDuplicateOperations(options, diagnostics, context);
			}

			if (!OPTION__IGNORE.equals(options
				.get(OPTION__DUPLICATE_OPERATION_INHERITANCE))) {

				processDuplicateOperationInheritance(options, diagnostics,
					context);
			}

			if (!OPTION__IGNORE.equals(options.get(OPTION__DUPLICATE_FEATURES))) {
				processDuplicateFeatures(options, diagnostics, context);
			}

			if (!OPTION__IGNORE.equals(options
				.get(OPTION__DUPLICATE_FEATURE_INHERITANCE))) {

				processDuplicateFeatureInheritance(options, diagnostics,
					context);
			}

			if (!OPTION__IGNORE.equals(options.get(OPTION__SUPER_CLASS_ORDER))) {
				processSuperClassOrder(options, diagnostics, context);
			}

			if (!OPTION__IGNORE.equals(options.get(OPTION__ANNOTATION_DETAILS))) {
				processAnnotationDetails(options, diagnostics, context);
			}
		}

		public Collection<? extends EObject> convert(
				Collection<? extends EObject> eObjects,
				Map<String, String> options, DiagnosticChain diagnostics,
				Map<Object, Object> context) {
			packages = EcoreUtil.getObjectsByType(eObjects,
				UMLPackage.Literals.PACKAGE);

			for (org.eclipse.uml2.uml.Package package_ : packages) {
				doSwitch(package_);
			}

			if (options != null) {
				processOptions(options, diagnostics, context);
			}

			return getRootContainers(EcoreUtil.<EObject> getObjectsByType(
				elementToEModelElementMap.values(),
				EcorePackage.Literals.EPACKAGE));
		}

	}

	/**
	 * A converter that converts UML profiles to representative Ecore packages.
	 */
	public static class Profile2EPackageConverter
			extends UML2EcoreConverter {

		@Override
		public Object casePackage(org.eclipse.uml2.uml.Package package_) {

			if (packages.contains(package_)) {
				return super.casePackage(package_);
			} else {
				EPackage ePackage = (EPackage) doSwitch(packages.iterator()
					.next());
				elementToEModelElementMap.put(package_, ePackage);
				return ePackage;
			}
		}

		@Override
		public Object caseProfile(Profile profile) {
			EPackage ePackage = (EPackage) casePackage(profile);

			if (packages.contains(profile)) {
				String profileName = ePackage.getName();

				ePackage.setNsPrefix(profileName);

				org.eclipse.uml2.uml.Package nestingPackage = profile
					.getNestingPackage();
				String profileParentQualifiedName = nestingPackage == null
					? EMPTY_STRING
					: getQualifiedName(nestingPackage, "."); //$NON-NLS-1$

				String version = String.valueOf(0);
				EPackage definition = profile.getDefinition();

				if (definition != null) {

					try {
						String nsURI = definition.getNsURI();
						int lastIndex = nsURI.lastIndexOf('/');

						if (lastIndex > 7) { // 2.0 format
							version = String.valueOf(Integer.parseInt(nsURI
								.substring(lastIndex + 1)) + 1);
						} else { // 1.x format
							String nsPrefix = definition.getNsPrefix();
							version = String.valueOf(Integer.parseInt(nsPrefix
								.substring(nsPrefix.lastIndexOf('_') + 1)) + 1);
						}
					} catch (Exception e) {
						// ignore
					}
				}

				StringBuffer nsURI = new StringBuffer("http://"); //$NON-NLS-1$
				nsURI.append(profileParentQualifiedName);
				nsURI.append("/schemas/"); //$NON-NLS-1$
				nsURI.append(profileName);
				nsURI.append('/');
				// ensure profiles with same name have different namespace URIs
				nsURI.append(EcoreUtil.generateUUID());
				nsURI.append('/');
				nsURI.append(version);

				ePackage.setNsURI(nsURI.toString());
			}

			return ePackage;
		}

		@Override
		protected EClassifier getEType(Type type) {

			if (type instanceof org.eclipse.uml2.uml.Class) {
				org.eclipse.uml2.uml.Class class_ = (org.eclipse.uml2.uml.Class) type;

				if (class_.isMetaclass()) {
					EClassifier eType = getEClassifier(class_);

					if (eType != null) {
						return eType;
					}
				}
			}

			return super.getEType(type);
		}

		@Override
		protected void setName(final ENamedElement eNamedElement,
				NamedElement namedElement) {

			new UMLSwitch<Object>() {

				@Override
				public Object caseClassifier(Classifier classifier) {
					setName(eNamedElement, packages.contains(classifier
						.getPackage())
						? classifier.getName()
						: getQualifiedName(classifier, "_"), true); //$NON-NLS-1$
					return classifier;
				}

				@Override
				public Object caseEnumerationLiteral(
						EnumerationLiteral enumerationLiteral) {
					setName(eNamedElement, enumerationLiteral.getName(), false);
					return enumerationLiteral;
				}

				@Override
				public Object caseNamedElement(NamedElement namedElement) {
					setName(eNamedElement, namedElement.getName(), true);
					return namedElement;
				}

			}.doSwitch(namedElement);
		}

		@Override
		public Object doSwitch(EObject eObject) {
			EObject eModelElement = (EObject) super.doSwitch(eObject);

			if (eModelElement instanceof EClassifier) {
				EList<EObject> references = getEAnnotation(
					(EClassifier) eModelElement, UMLPackage.eNS_URI, true)
					.getReferences();

				if (references.isEmpty()) {
					references.add(eObject);
				}
			}

			return eModelElement;
		}
	}

	/**
	 * A converter that converts Ecore model elements to representative UML
	 * elements.
	 */
	public static class Ecore2UMLConverter
			extends EcoreSwitch<Object>
			implements Converter {

		/**
		 * The option for handling cases where an Ecore tagged value is
		 * encountered. Supported choices are <code>OPTION__IGNORE</code>,
		 * <code>OPTION__REPORT</code>, and <code>OPTION__PROCESS</code>.
		 */
		public static final String OPTION__ECORE_TAGGED_VALUES = "ECORE_TAGGED_VALUES"; //$NON-NLS-1$

		/**
		 * The option for handling cases where a <code>redefines</code>
		 * annotation is encountered. Supported choices are
		 * <code>OPTION__IGNORE</code>, <code>OPTION__REPORT</code>, and
		 * <code>OPTION__PROCESS</code>.
		 */
		public static final String OPTION__REDEFINES_ANNOTATIONS = "REDEFINES_ANNOTATIONS"; //$NON-NLS-1$

		/**
		 * The option for handling cases where a <code>subsets</code>
		 * annotation is encountered. Supported choices are
		 * <code>OPTION__IGNORE</code>, <code>OPTION__REPORT</code>, and
		 * <code>OPTION__PROCESS</code>.
		 */
		public static final String OPTION__SUBSETS_ANNOTATIONS = "SUBSETS_ANNOTATIONS"; //$NON-NLS-1$

		/**
		 * The option for handling cases where a <code>union</code> annotation
		 * is encountered. Supported choices are <code>OPTION__IGNORE</code>,
		 * <code>OPTION__REPORT</code>, and <code>OPTION__PROCESS</code>.
		 */
		public static final String OPTION__UNION_ANNOTATIONS = "UNION_ANNOTATIONS"; //$NON-NLS-1$

		/**
		 * The option for handling cases where annotation details are
		 * encountered. Supported choices are <code>OPTION__IGNORE</code>,
		 * <code>OPTION__REPORT</code>, and <code>OPTION__PROCESS</code>.
		 */
		public static final String OPTION__ANNOTATION_DETAILS = "ANNOTATION_DETAILS"; //$NON-NLS-1$

		private static final int DIAGNOSTIC_CODE_OFFSET = 3000;

		/**
		 * The diagnostic code for cases where an Ecore tagged value is
		 * encountered.
		 */
		public static final int ECORE_TAGGED_VALUE = DIAGNOSTIC_CODE_OFFSET + 1;

		/**
		 * The diagnostic code for cases where a <code>redefines</code>
		 * annotation is encountered.
		 */
		public static final int REDEFINES_ANNOTATION = DIAGNOSTIC_CODE_OFFSET + 2;

		/**
		 * The diagnostic code for cases where a <code>subsets</code>
		 * annotation is encountered.
		 */
		public static final int SUBSETS_ANNOTATION = DIAGNOSTIC_CODE_OFFSET + 3;

		/**
		 * The diagnostic code for cases where a <code>union</code> annotation
		 * is encountered.
		 */
		public static final int UNION_ANNOTATION = DIAGNOSTIC_CODE_OFFSET + 4;

		/**
		 * The diagnostic code for cases where annotation details are
		 * encountered.
		 */
		public static final int ANNOTATION_DETAILS = DIAGNOSTIC_CODE_OFFSET + 5;

		protected final Map<EModelElement, Element> eModelElementToElementMap = new LinkedHashMap<EModelElement, Element>();

		protected Collection<EPackage> ePackages = null;

		protected Model getEcorePrimitiveTypesLibrary(
				EModelElement eModelElement) {
			Resource eResource = eModelElement.eResource();

			if (eResource != null) {
				ResourceSet resourceSet = eResource.getResourceSet();

				if (resourceSet != null) {
					return load(
						resourceSet,
						URI
							.createURI(UMLResource.ECORE_PRIMITIVE_TYPES_LIBRARY_URI),
						UMLPackage.Literals.MODEL);
				}
			}

			return null;
		}

		protected Model getXMLPrimitiveTypesLibrary(EModelElement eModelElement) {
			Resource eResource = eModelElement.eResource();

			if (eResource != null) {
				ResourceSet resourceSet = eResource.getResourceSet();

				if (resourceSet != null) {
					return load(
						resourceSet,
						URI
							.createURI(UMLResource.XML_PRIMITIVE_TYPES_LIBRARY_URI),
						UMLPackage.Literals.MODEL);
				}
			}

			return null;
		}

		protected PrimitiveType getEcorePrimitiveType(
				EModelElement eModelElement, String name) {
			Model ecorePrimitiveTypesLibrary = getEcorePrimitiveTypesLibrary(eModelElement);

			return ecorePrimitiveTypesLibrary != null
				? (PrimitiveType) ecorePrimitiveTypesLibrary.getOwnedType(name)
				: null;
		}

		protected PrimitiveType getXMLPrimitiveType(
				EModelElement eModelElement, String name) {
			Model xmlPrimitiveTypesLibrary = getXMLPrimitiveTypesLibrary(eModelElement);

			return xmlPrimitiveTypesLibrary != null
				? (PrimitiveType) xmlPrimitiveTypesLibrary.getOwnedType(name)
				: null;
		}

		protected Type getType(EModelElement eModelElement, EClassifier eType) {
			Type type = null;

			if (eType != null) {
				String name = eType.getName();

				if (!isEmpty(name) && eType instanceof EDataType) {
					EPackage ePackage = eType.getEPackage();

					if (ePackage != null) {
						String nsURI = ePackage.getNsURI();

						if (XMLTypePackage.eNS_URI.equals(nsURI)) {
							type = getXMLPrimitiveType(eModelElement, name);
						} else if (EcorePackage.eNS_URI.equals(nsURI)) {
							type = getEcorePrimitiveType(eModelElement, name);
						}
					}
				}

				if (type == null) {
					type = (Type) doSwitch(eType);
				}
			}

			return type;
		}

		protected Type getType(ETypedElement eTypedElement) {
			return getType(eTypedElement, eTypedElement.getEType());
		}

		@Override
		public Object caseEAttribute(EAttribute eAttribute) {
			EClass eContainingClass = eAttribute.getEContainingClass();

			if (eContainingClass != null) {
				Property property = UMLFactory.eINSTANCE.createProperty();
				eModelElementToElementMap.put(eAttribute, property);

				Classifier classifier = (Classifier) doSwitch(eContainingClass);
				getOwnedAttributes(classifier).add(property);

				property.setName(eAttribute.getName());
				property.setIsReadOnly(!eAttribute.isChangeable());
				property.setIsDerived(eAttribute.isDerived());
				property.setVisibility(VisibilityKind.PUBLIC_LITERAL);

				caseETypedElement(eAttribute);

				defaultCase(eAttribute);

				return property;
			}

			return super.caseEAttribute(eAttribute);
		}

		@Override
		public Object caseEClass(EClass eClass) {
			EPackage ePackage = eClass.getEPackage();

			if (ePackage != null) {
				Classifier classifier = eClass.isInterface()
					? (Classifier) UMLFactory.eINSTANCE.createInterface()
					: (ExtendedMetaData.INSTANCE.getSimpleFeature(eClass) == null
						? (Classifier) UMLFactory.eINSTANCE.createClass()
						: (Classifier) UMLFactory.eINSTANCE.createDataType());
				eModelElementToElementMap.put(eClass, classifier);

				org.eclipse.uml2.uml.Package package_ = (org.eclipse.uml2.uml.Package) doSwitch(ePackage);
				package_.getOwnedTypes().add(classifier);

				classifier.setName(eClass.getName());

				if (!eClass.isInterface()) {
					classifier.setIsAbstract(eClass.isAbstract());
				}

				for (EClass eSuperType : eClass.getESuperTypes()) {

					if (eSuperType.isInterface()) {
						((BehavioredClassifier) classifier)
							.createInterfaceRealization(null,
								(Interface) doSwitch(eSuperType));
					} else {
						Classifier generalClassifier = (Classifier) doSwitch(eSuperType);

						if (!classifier.allParents()
							.contains(generalClassifier)) {

							classifier.createGeneralization(generalClassifier);
						}
					}
				}

				defaultCase(eClass);

				return classifier;
			}

			return super.caseEClass(eClass);
		}

		@Override
		public Object caseEDataType(EDataType eDataType) {
			EPackage ePackage = eDataType.getEPackage();

			if (ePackage != null) {
				PrimitiveType primitiveType = UMLFactory.eINSTANCE
					.createPrimitiveType();
				eModelElementToElementMap.put(eDataType, primitiveType);

				org.eclipse.uml2.uml.Package package_ = (org.eclipse.uml2.uml.Package) doSwitch(ePackage);
				package_.getOwnedTypes().add(primitiveType);

				primitiveType.setName(eDataType.getName());

				EDataType baseType = ExtendedMetaData.INSTANCE
					.getBaseType(eDataType);

				if (baseType != null) {
					Classifier generalClassifier = (Classifier) doSwitch(baseType);

					if (!primitiveType.allParents().contains(generalClassifier)) {
						primitiveType.createGeneralization(generalClassifier);
					}
				}

				defaultCase(eDataType);

				return primitiveType;
			}

			return super.caseEDataType(eDataType);
		}

		@Override
		public Object caseEEnum(EEnum eEnum) {
			EPackage ePackage = eEnum.getEPackage();

			if (ePackage != null) {
				Enumeration enumeration = UMLFactory.eINSTANCE
					.createEnumeration();
				eModelElementToElementMap.put(eEnum, enumeration);

				org.eclipse.uml2.uml.Package package_ = (org.eclipse.uml2.uml.Package) doSwitch(ePackage);
				package_.getOwnedTypes().add(enumeration);

				enumeration.setName(eEnum.getName());

				defaultCase(eEnum);

				return enumeration;
			}

			return super.caseEEnum(eEnum);
		}

		@Override
		public Object caseEEnumLiteral(EEnumLiteral eEnumLiteral) {
			EEnum eEnum = eEnumLiteral.getEEnum();

			if (eEnum != null) {
				EnumerationLiteral enumerationLiteral = UMLFactory.eINSTANCE
					.createEnumerationLiteral();
				eModelElementToElementMap.put(eEnumLiteral, enumerationLiteral);

				Enumeration enumeration = (Enumeration) doSwitch(eEnum);
				enumeration.getOwnedLiterals().add(enumerationLiteral);

				enumerationLiteral.setName(eEnumLiteral.getName());

				int value = eEnumLiteral.getValue();

				if (value != eEnum.getELiterals().indexOf(eEnumLiteral)) {
					((LiteralInteger) enumerationLiteral.createSpecification(
						null, null, UMLPackage.Literals.LITERAL_INTEGER))
						.setValue(value);
				}

				defaultCase(eEnumLiteral);

				return enumerationLiteral;
			}

			return super.caseEEnumLiteral(eEnumLiteral);
		}

		@Override
		public Object caseEModelElement(EModelElement eModelElement) {
			return eModelElement;
		}

		@Override
		public Object caseEOperation(EOperation eOperation) {
			EClass eContainingClass = eOperation.getEContainingClass();

			if (eContainingClass != null) {
				Operation operation = UMLFactory.eINSTANCE.createOperation();
				eModelElementToElementMap.put(eOperation, operation);

				Classifier classifier = (Classifier) doSwitch(eContainingClass);
				getOwnedOperations(classifier).add(operation);

				operation.setName(eOperation.getName());

				EClassifier eType = eOperation.getEType();

				if (eType != null) {
					operation.createReturnResult(null, getType(eOperation,
						eType));
				}

				EList<Type> raisedExceptions = operation.getRaisedExceptions();

				for (EClassifier eException : eOperation.getEExceptions()) {
					Type type = getType(eOperation, eException);

					if (type != null) {
						raisedExceptions.add(type);
					}
				}

				operation.setVisibility(VisibilityKind.PUBLIC_LITERAL);

				int upperBound = eOperation.getUpperBound();

				if (upperBound != ETypedElement.UNSPECIFIED_MULTIPLICITY
					&& upperBound != operation.getUpper()) {

					operation.setUpper(upperBound);
				}

				int lowerBound = eOperation.getLowerBound();

				if (lowerBound != operation.getLower()) {
					operation.setLower(lowerBound);
				}

				operation.setIsOrdered(eOperation.isOrdered());
				operation.setIsUnique(eOperation.isUnique());

				defaultCase(eOperation);

				return operation;
			}

			return super.caseEOperation(eOperation);
		}

		@Override
		public Object caseEPackage(EPackage ePackage) {
			org.eclipse.uml2.uml.Package package_ = ePackage.getESuperPackage() == null
				? UMLFactory.eINSTANCE.createModel()
				: UMLFactory.eINSTANCE.createPackage();
			eModelElementToElementMap.put(ePackage, package_);

			if (!ePackages.contains(ePackage)) {
				EPackage eSuperPackage = ePackage.getESuperPackage();

				if (eSuperPackage != null) {
					((org.eclipse.uml2.uml.Package) doSwitch(eSuperPackage))
						.getNestedPackages().add(package_);
				}
			}

			package_.setName(ePackage.getName());

			defaultCase(ePackage);

			return package_;
		}

		@Override
		public Object caseEParameter(EParameter eParameter) {
			EOperation eOperation = eParameter.getEOperation();

			if (eOperation != null) {
				Parameter parameter = UMLFactory.eINSTANCE.createParameter();
				eModelElementToElementMap.put(eParameter, parameter);

				Operation operation = (Operation) doSwitch(eOperation);
				operation.getOwnedParameters().add(parameter);

				parameter.setName(eParameter.getName());

				caseETypedElement(eParameter);

				defaultCase(eParameter);

				return parameter;
			}

			return super.caseEParameter(eParameter);
		}

		@Override
		public Object caseEReference(EReference eReference) {
			EClass eContainingClass = eReference.getEContainingClass();

			if (eContainingClass != null) {
				Property property = UMLFactory.eINSTANCE.createProperty();
				eModelElementToElementMap.put(eReference, property);

				Classifier classifier = (Classifier) doSwitch(eContainingClass);
				getOwnedAttributes(classifier).add(property);

				property.setName(eReference.getName());
				property.setAggregation(eReference.isContainment()
					? AggregationKind.COMPOSITE_LITERAL
					: AggregationKind.NONE_LITERAL);
				property.setIsDerived(eReference.isDerived());
				property.setIsReadOnly(!eReference.isChangeable());

				caseETypedElement(eReference);

				EReference eOpposite = eReference.getEOpposite();

				if (eOpposite == null) {
					Association association = (Association) ((org.eclipse.uml2.uml.Package) doSwitch(eContainingClass
						.getEPackage())).createOwnedType(null,
						UMLPackage.Literals.ASSOCIATION);

					property.setAssociation(association);

					association.createOwnedEnd(null, classifier);
				} else {
					Property opposite = (Property) doSwitch(eOpposite);

					if (opposite != null) {
						Association association = opposite.getAssociation();

						if (association == null) {

							if (eReference.isContainer()) {
								opposite
									.setAssociation(association = (Association) ((org.eclipse.uml2.uml.Package) doSwitch(eOpposite
										.getEContainingClass().getEPackage()))
										.createOwnedType(null,
											UMLPackage.Literals.ASSOCIATION));

								property.setAssociation(association);
							} else {
								property
									.setAssociation(association = (Association) ((org.eclipse.uml2.uml.Package) doSwitch(eContainingClass
										.getEPackage())).createOwnedType(null,
										UMLPackage.Literals.ASSOCIATION));

								opposite.setAssociation(association);
							}
						} else {
							property.setAssociation(association);
						}
					}
				}

				defaultCase(eReference);

				return property;
			}

			return super.caseEReference(eReference);
		}

		@Override
		public Object caseETypedElement(ETypedElement eTypedElement) {
			Object element = eModelElementToElementMap.get(eTypedElement);

			if (element != null) {

				if (element instanceof TypedElement) {
					((TypedElement) element).setType(getType(eTypedElement));
				}

				if (element instanceof MultiplicityElement) {
					MultiplicityElement multiplicityElement = (MultiplicityElement) element;

					int upperBound = eTypedElement.getUpperBound();

					if (upperBound != ETypedElement.UNSPECIFIED_MULTIPLICITY
						&& upperBound != multiplicityElement.getUpper()) {

						multiplicityElement.setUpper(upperBound);
					}

					int lowerBound = eTypedElement.getLowerBound();

					if (lowerBound != multiplicityElement.getLower()) {
						multiplicityElement.setLower(lowerBound);
					}

					multiplicityElement.setIsOrdered(eTypedElement.isOrdered());
					multiplicityElement.setIsUnique(eTypedElement.isUnique());
				}

				return element;
			}

			return super.caseETypedElement(eTypedElement);
		}

		@Override
		public Object defaultCase(EObject eObject) {

			for (EObject eContent : eObject.eContents()) {
				doSwitch(eContent);
			}

			return super.defaultCase(eObject);
		}

		@Override
		public Object doSwitch(EObject eObject) {

			if (!eModelElementToElementMap.containsKey(eObject)) {
				super.doSwitch(eObject);
			}

			return eModelElementToElementMap.get(eObject);
		}

		protected Profile getEcoreProfile(EModelElement eModelElement) {
			Resource eResource = eModelElement.eResource();

			if (eResource != null) {
				ResourceSet resourceSet = eResource.getResourceSet();

				if (resourceSet != null) {
					return load(resourceSet, URI
						.createURI(UMLResource.ECORE_PROFILE_URI),
						UMLPackage.Literals.PROFILE);
				}
			}

			return null;
		}

		protected Stereotype getEcoreStereotype(EModelElement eModelElement,
				String name) {
			Profile ecoreProfile = getEcoreProfile(eModelElement);

			return ecoreProfile != null
				? ecoreProfile.getOwnedStereotype(name)
				: null;
		}

		protected void processEcoreTaggedValue(Element element,
				Stereotype stereotype, String propertyName,
				EModelElement eModelElement,
				EStructuralFeature eStructuralFeature,
				Map<String, String> options, DiagnosticChain diagnostics,
				Map<Object, Object> context) {
			Object value = null;

			if (eStructuralFeature != null) {
				value = eModelElement.eGet(eStructuralFeature);

				if (safeEquals(value, eStructuralFeature.getDefaultValue())) {
					return;
				}
			} else {

				if (propertyName == TAG_DEFINITION__XML_CONTENT_KIND) {
					Enumeration contentKindEnumeration = (Enumeration) getEcoreProfile(
						eModelElement).getOwnedType(ENUMERATION__CONTENT_KIND);

					if (contentKindEnumeration != null) {

						switch (ExtendedMetaData.INSTANCE
							.getContentKind((EClass) eModelElement)) {

							case ExtendedMetaData.EMPTY_CONTENT :
								value = contentKindEnumeration
									.getOwnedLiteral(ENUMERATION_LITERAL__EMPTY);
								break;
							case ExtendedMetaData.SIMPLE_CONTENT :
								value = contentKindEnumeration
									.getOwnedLiteral(ENUMERATION_LITERAL__SIMPLE);
								break;
							case ExtendedMetaData.MIXED_CONTENT :
								value = contentKindEnumeration
									.getOwnedLiteral(ENUMERATION_LITERAL__MIXED);
								break;
							case ExtendedMetaData.ELEMENT_ONLY_CONTENT :
								value = contentKindEnumeration
									.getOwnedLiteral(ENUMERATION_LITERAL__ELEMENT_ONLY);
								break;
						}
					}

					if (value == null) {
						return;
					}
				} else if (propertyName == TAG_DEFINITION__XML_FEATURE_KIND) {
					Enumeration featureKindEnumeration = (Enumeration) getEcoreProfile(
						eModelElement).getOwnedType(ENUMERATION__FEATURE_KIND);

					if (featureKindEnumeration != null) {

						switch (ExtendedMetaData.INSTANCE
							.getFeatureKind((EStructuralFeature) eModelElement)) {

							case ExtendedMetaData.SIMPLE_FEATURE :
								value = featureKindEnumeration
									.getOwnedLiteral(ENUMERATION_LITERAL__SIMPLE);
								break;
							case ExtendedMetaData.ATTRIBUTE_FEATURE :
								value = featureKindEnumeration
									.getOwnedLiteral(ENUMERATION_LITERAL__ATTRIBUTE);
								break;
							case ExtendedMetaData.ATTRIBUTE_WILDCARD_FEATURE :
								value = featureKindEnumeration
									.getOwnedLiteral(ENUMERATION_LITERAL__ATTRIBUTE_WILDCARD);
								break;
							case ExtendedMetaData.ELEMENT_FEATURE :
								value = featureKindEnumeration
									.getOwnedLiteral(ENUMERATION_LITERAL__ELEMENT);
								break;
							case ExtendedMetaData.ELEMENT_WILDCARD_FEATURE :
								value = featureKindEnumeration
									.getOwnedLiteral(ENUMERATION_LITERAL__ELEMENT_WILDCARD);
								break;
							case ExtendedMetaData.GROUP_FEATURE :
								value = featureKindEnumeration
									.getOwnedLiteral(ENUMERATION_LITERAL__GROUP);
								break;
						}
					}

					if (value == null) {
						return;
					}
				} else if (propertyName == TAG_DEFINITION__XML_NAME) {

					if (eModelElement instanceof EClassifier) {
						value = ExtendedMetaData.INSTANCE
							.getName((EClassifier) eModelElement);
					} else if (eModelElement instanceof EStructuralFeature) {
						value = ExtendedMetaData.INSTANCE
							.getName((EStructuralFeature) eModelElement);
					}

					if (safeEquals(value, ((ENamedElement) eModelElement)
						.getName())) {
						return;
					}
				} else if (propertyName == TAG_DEFINITION__XML_NAMESPACE) {
					value = ExtendedMetaData.INSTANCE
						.getNamespace((EStructuralFeature) eModelElement);

					if (value == null) {
						return;
					}
				} else if (propertyName == TAG_DEFINITION__VISIBILITY) {
					Enumeration visibilityKindEnumeration = (Enumeration) getEcoreProfile(
						eModelElement).getOwnedType(
						ENUMERATION__VISIBILITY_KIND);

					if (visibilityKindEnumeration != null) {
						eStructuralFeature = (EStructuralFeature) eModelElement;

						if (EcoreUtil.isSuppressedVisibility(
							eStructuralFeature, EcoreUtil.GET)) {

							value = visibilityKindEnumeration
								.getOwnedLiteral(ENUMERATION_LITERAL__NONE);
						} else {

							if (EcoreUtil.isSuppressedVisibility(
								eStructuralFeature, EcoreUtil.SET)) {

								if (EcoreUtil.isSuppressedVisibility(
									eStructuralFeature, EcoreUtil.IS_SET)) {

									value = visibilityKindEnumeration
										.getOwnedLiteral(ENUMERATION_LITERAL__READ_ONLY);
								} else {
									value = visibilityKindEnumeration
										.getOwnedLiteral(ENUMERATION_LITERAL__READ_ONLY_UNSETTABLE);
								}
							} else {

								if (EcoreUtil.isSuppressedVisibility(
									eStructuralFeature, EcoreUtil.UNSET)) {

									value = visibilityKindEnumeration
										.getOwnedLiteral(ENUMERATION_LITERAL__READ_WRITE);
								}
							}
						}
					}

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

			if (OPTION__PROCESS
				.equals(options.get(OPTION__ECORE_TAGGED_VALUES))) {

				if (diagnostics != null) {
					diagnostics
						.add(new BasicDiagnostic(
							Diagnostic.INFO,
							UMLValidator.DIAGNOSTIC_SOURCE,
							ECORE_TAGGED_VALUE,
							UMLPlugin.INSTANCE
								.getString(
									"_UI_Ecore2UMLConverter_ProcessEcoreTaggedValue_diagnostic", //$NON-NLS-1$
									getMessageSubstitutions(context, element,
										getTagDefinition(stereotype,
											propertyName), value)),
							new Object[]{element}));
				}

				setTaggedValue(element, stereotype, propertyName, value);
			} else if (OPTION__REPORT.equals(options
				.get(OPTION__ECORE_TAGGED_VALUES))
				&& diagnostics != null) {

				diagnostics
					.add(new BasicDiagnostic(
						Diagnostic.WARNING,
						UMLValidator.DIAGNOSTIC_SOURCE,
						ECORE_TAGGED_VALUE,
						UMLPlugin.INSTANCE
							.getString(
								"_UI_Ecore2UMLConverter_ReportEcoreTaggedValue_diagnostic", //$NON-NLS-1$
								getMessageSubstitutions(context, element,
									getTagDefinition(stereotype, propertyName),
									value)), new Object[]{element}));
			}
		}

		protected void processEcoreTaggedValues(Element element,
				EPackage ePackage, Map<String, String> options,
				DiagnosticChain diagnostics, Map<Object, Object> context) {
			Stereotype ePackageStereotype = getEcoreStereotype(ePackage,
				STEREOTYPE__E_PACKAGE);

			if (ePackageStereotype != null) {
				safeApplyStereotype(element, ePackageStereotype);

				processEcoreTaggedValue(element, ePackageStereotype,
					TAG_DEFINITION__NS_PREFIX, ePackage,
					EcorePackage.Literals.EPACKAGE__NS_PREFIX, options,
					diagnostics, context);

				processEcoreTaggedValue(element, ePackageStereotype,
					TAG_DEFINITION__NS_URI, ePackage,
					EcorePackage.Literals.EPACKAGE__NS_URI, options,
					diagnostics, context);
			}
		}

		protected void processEcoreTaggedValues(Element element,
				final EClassifier eClassifier,
				final Map<String, String> options,
				final DiagnosticChain diagnostics,
				final Map<Object, Object> context) {
			Stereotype eClassifierStereotype = new UMLSwitch<Stereotype>() {

				@Override
				public Stereotype caseClass(org.eclipse.uml2.uml.Class class_) {
					Stereotype eClassStereotype = getEcoreStereotype(
						eClassifier, STEREOTYPE__E_CLASS);

					if (eClassStereotype != null) {
						safeApplyStereotype(class_, eClassStereotype);

						processEcoreTaggedValue(class_, eClassStereotype,
							TAG_DEFINITION__XML_CONTENT_KIND, eClassifier,
							null, options, diagnostics, context);
					}

					return eClassStereotype;
				}

				@Override
				public Stereotype caseDataType(DataType dataType) {
					Stereotype eClassStereotype = getEcoreStereotype(
						eClassifier, STEREOTYPE__E_CLASS);

					if (eClassStereotype != null) {
						safeApplyStereotype(dataType, eClassStereotype);

						processEcoreTaggedValue(dataType, eClassStereotype,
							TAG_DEFINITION__XML_CONTENT_KIND, eClassifier,
							null, options, diagnostics, context);
					}

					return eClassStereotype;
				}

				@Override
				public Stereotype caseInterface(Interface interface_) {
					Stereotype eClassStereotype = getEcoreStereotype(
						eClassifier, STEREOTYPE__E_CLASS);

					if (eClassStereotype != null) {
						safeApplyStereotype(interface_, eClassStereotype);

						processEcoreTaggedValue(interface_, eClassStereotype,
							TAG_DEFINITION__XML_CONTENT_KIND, eClassifier,
							null, options, diagnostics, context);
					}

					return eClassStereotype;
				}

				@Override
				public Stereotype casePrimitiveType(PrimitiveType primitiveType) {
					Stereotype eDataTypeStereotype = getEcoreStereotype(
						eClassifier, STEREOTYPE__E_DATA_TYPE);

					if (eDataTypeStereotype != null) {
						safeApplyStereotype(primitiveType, eDataTypeStereotype);
					}

					return eDataTypeStereotype;
				}
			}.doSwitch(element);

			if (eClassifierStereotype != null) {
				processEcoreTaggedValue(element, eClassifierStereotype,
					TAG_DEFINITION__XML_NAME, eClassifier, null, options,
					diagnostics, context);

				processEcoreTaggedValue(element, eClassifierStereotype,
					TAG_DEFINITION__INSTANCE_CLASS_NAME, eClassifier,
					EcorePackage.Literals.ECLASSIFIER__INSTANCE_CLASS_NAME,
					options, diagnostics, context);
			}
		}

		protected void processEcoreTaggedValues(final Element element,
				EStructuralFeature eStructuralFeature,
				final Map<String, String> options,
				final DiagnosticChain diagnostics,
				final Map<Object, Object> context) {
			Stereotype eStructuralFeatureStereotype = new EcoreSwitch<Stereotype>() {

				@Override
				public Stereotype caseEAttribute(EAttribute eAttribute) {
					Stereotype eAttributeStereotype = getEcoreStereotype(
						eAttribute, STEREOTYPE__E_ATTRIBUTE);

					if (eAttributeStereotype != null) {
						safeApplyStereotype(element, eAttributeStereotype);

						processEcoreTaggedValue(element, eAttributeStereotype,
							TAG_DEFINITION__IS_ID, eAttribute,
							EcorePackage.Literals.EATTRIBUTE__ID, options,
							diagnostics, context);
					}

					return eAttributeStereotype;
				}

				@Override
				public Stereotype caseEReference(EReference eReference) {
					Stereotype eReferenceStereotype = getEcoreStereotype(
						eReference, STEREOTYPE__E_REFERENCE);

					if (eReferenceStereotype != null) {
						safeApplyStereotype(element, eReferenceStereotype);

						processEcoreTaggedValue(element, eReferenceStereotype,
							TAG_DEFINITION__IS_RESOLVE_PROXIES, eReference,
							EcorePackage.Literals.EREFERENCE__RESOLVE_PROXIES,
							options, diagnostics, context);
					}

					return eReferenceStereotype;
				}
			}.doSwitch(eStructuralFeature);

			if (eStructuralFeatureStereotype != null) {
				processEcoreTaggedValue(element, eStructuralFeatureStereotype,
					TAG_DEFINITION__IS_TRANSIENT, eStructuralFeature,
					EcorePackage.Literals.ESTRUCTURAL_FEATURE__TRANSIENT,
					options, diagnostics, context);

				processEcoreTaggedValue(element, eStructuralFeatureStereotype,
					TAG_DEFINITION__IS_UNSETTABLE, eStructuralFeature,
					EcorePackage.Literals.ESTRUCTURAL_FEATURE__UNSETTABLE,
					options, diagnostics, context);

				processEcoreTaggedValue(element, eStructuralFeatureStereotype,
					TAG_DEFINITION__IS_VOLATILE, eStructuralFeature,
					EcorePackage.Literals.ESTRUCTURAL_FEATURE__VOLATILE,
					options, diagnostics, context);

				processEcoreTaggedValue(element, eStructuralFeatureStereotype,
					TAG_DEFINITION__XML_FEATURE_KIND, eStructuralFeature, null,
					options, diagnostics, context);

				processEcoreTaggedValue(element, eStructuralFeatureStereotype,
					TAG_DEFINITION__XML_NAME, eStructuralFeature, null,
					options, diagnostics, context);

				processEcoreTaggedValue(element, eStructuralFeatureStereotype,
					TAG_DEFINITION__XML_NAMESPACE, eStructuralFeature, null,
					options, diagnostics, context);

				processEcoreTaggedValue(element, eStructuralFeatureStereotype,
					TAG_DEFINITION__VISIBILITY, eStructuralFeature, null,
					options, diagnostics, context);
			}
		}

		protected void processEcoreTaggedValues(
				final Map<String, String> options,
				final DiagnosticChain diagnostics,
				final Map<Object, Object> context) {

			for (Map.Entry<EModelElement, Element> entry : eModelElementToElementMap
				.entrySet()) {

				EModelElement eModelElement = entry.getKey();
				final Element element = entry.getValue();

				new EcoreSwitch<Object>() {

					@Override
					public Object caseEClassifier(EClassifier eClassifier) {
						processEcoreTaggedValues(element, eClassifier, options,
							diagnostics, context);

						return eClassifier;
					}

					@Override
					public Object caseEDataType(EDataType eDataType) {
						processEcoreTaggedValues(element, eDataType, options,
							diagnostics, context);

						return eDataType;
					}

					@Override
					public Object caseEEnum(EEnum eEnum) {
						Stereotype eEnumStereotype = getEcoreStereotype(eEnum,
							STEREOTYPE__E_ENUM);

						if (eEnumStereotype != null) {
							safeApplyStereotype(element, eEnumStereotype);
						}

						return eEnum;
					}

					@Override
					public Object caseEEnumLiteral(EEnumLiteral eEnumLiteral) {
						Stereotype eEnumLiteralStereotype = getEcoreStereotype(
							eEnumLiteral, STEREOTYPE__E_ENUM_LITERAL);

						if (eEnumLiteralStereotype != null) {
							safeApplyStereotype(element, eEnumLiteralStereotype);
						}

						return eEnumLiteral;
					}

					@Override
					public Object caseEOperation(EOperation eOperation) {
						Stereotype eOperationStereotype = getEcoreStereotype(
							eOperation, STEREOTYPE__E_OPERATION);

						if (eOperationStereotype != null) {
							safeApplyStereotype(element, eOperationStereotype);
						}

						return eOperation;
					}

					@Override
					public Object caseEPackage(EPackage ePackage) {
						processEcoreTaggedValues(element, ePackage, options,
							diagnostics, context);

						return ePackage;
					}

					@Override
					public Object caseEParameter(EParameter eParameter) {
						Stereotype eParameterStereotype = getEcoreStereotype(
							eParameter, STEREOTYPE__E_PARAMETER);

						if (eParameterStereotype != null) {
							safeApplyStereotype(element, eParameterStereotype);
						}

						return eParameter;
					}

					@Override
					public Object caseEStructuralFeature(
							EStructuralFeature eStructuralFeature) {
						processEcoreTaggedValues(element, eStructuralFeature,
							options, diagnostics, context);

						return eStructuralFeature;
					}

				}.doSwitch(eModelElement);
			}
		}

		protected void processRedefinesAnnotations(
				final Map<String, String> options,
				final DiagnosticChain diagnostics,
				final Map<Object, Object> context) {

			for (Map.Entry<EModelElement, Element> entry : eModelElementToElementMap
				.entrySet()) {
				EModelElement eModelElement = entry.getKey();

				if (eModelElement instanceof ETypedElement) {
					EAnnotation redefinesEAnnotation = getEAnnotation(
						eModelElement, ANNOTATION__REDEFINES, false);

					if (redefinesEAnnotation != null) {
						Feature feature = (Feature) entry.getValue();

						for (EObject reference : redefinesEAnnotation
							.getReferences()) {

							Feature redefinedFeature = (Feature) eModelElementToElementMap
								.get(reference);

							if (redefinedFeature != null
								&& findValidRedefinitions(feature,
									redefinedFeature.getName()).contains(
									redefinedFeature)) {

								if (OPTION__PROCESS.equals(options
									.get(OPTION__REDEFINES_ANNOTATIONS))) {

									if (diagnostics != null) {
										diagnostics
											.add(new BasicDiagnostic(
												Diagnostic.INFO,
												UMLValidator.DIAGNOSTIC_SOURCE,
												REDEFINES_ANNOTATION,
												UMLPlugin.INSTANCE
													.getString(
														"_UI_Ecore2UMLConverter_ProcessRedefinesAnnotation_diagnostic", //$NON-NLS-1$
														getMessageSubstitutions(
															context, feature,
															redefinedFeature)),
												new Object[]{feature,
													redefinedFeature}));
									}

									getRedefinedFeatures(feature).add(
										redefinedFeature);
								} else if (OPTION__REPORT.equals(options
									.get(OPTION__REDEFINES_ANNOTATIONS))
									&& diagnostics != null) {

									diagnostics
										.add(new BasicDiagnostic(
											Diagnostic.WARNING,
											UMLValidator.DIAGNOSTIC_SOURCE,
											REDEFINES_ANNOTATION,
											UMLPlugin.INSTANCE
												.getString(
													"_UI_Ecore2UMLConverter_ReportRedefinesAnnotation_diagnostic", //$NON-NLS-1$
													getMessageSubstitutions(
														context, feature,
														redefinedFeature)),
											new Object[]{feature,
												redefinedFeature}));
								}
							}
						}
					}
				}
			}
		}

		protected void processSubsetsAnnotations(
				final Map<String, String> options,
				final DiagnosticChain diagnostics,
				final Map<Object, Object> context) {

			for (Map.Entry<EModelElement, Element> entry : eModelElementToElementMap
				.entrySet()) {
				EModelElement eModelElement = entry.getKey();

				if (eModelElement instanceof EStructuralFeature) {
					EAnnotation subsetsEAnnotation = getEAnnotation(
						eModelElement, ANNOTATION__SUBSETS, false);

					if (subsetsEAnnotation != null) {
						Property property = (Property) entry.getValue();

						for (EObject reference : subsetsEAnnotation
							.getReferences()) {

							Property subsettedProperty = (Property) eModelElementToElementMap
								.get(reference);

							if (subsettedProperty != null
								&& findValidSubsets(property,
									subsettedProperty.getName()).contains(
									subsettedProperty)) {

								if (OPTION__PROCESS.equals(options
									.get(OPTION__SUBSETS_ANNOTATIONS))) {

									if (diagnostics != null) {
										diagnostics
											.add(new BasicDiagnostic(
												Diagnostic.INFO,
												UMLValidator.DIAGNOSTIC_SOURCE,
												SUBSETS_ANNOTATION,
												UMLPlugin.INSTANCE
													.getString(
														"_UI_Ecore2UMLConverter_ProcessSubsetsAnnotation_diagnostic", //$NON-NLS-1$
														getMessageSubstitutions(
															context, property,
															subsettedProperty)),
												new Object[]{property,
													subsettedProperty}));
									}

									property.getSubsettedProperties().add(
										subsettedProperty);
								} else if (OPTION__REPORT.equals(options
									.get(OPTION__SUBSETS_ANNOTATIONS))
									&& diagnostics != null) {

									diagnostics
										.add(new BasicDiagnostic(
											Diagnostic.WARNING,
											UMLValidator.DIAGNOSTIC_SOURCE,
											SUBSETS_ANNOTATION,
											UMLPlugin.INSTANCE
												.getString(
													"_UI_Ecore2UMLConverter_ReportSubsetsAnnotation_diagnostic", //$NON-NLS-1$
													getMessageSubstitutions(
														context, property,
														subsettedProperty)),
											new Object[]{property,
												subsettedProperty}));
								}
							}
						}
					}
				}
			}
		}

		protected void processUnionAnnotations(
				final Map<String, String> options,
				final DiagnosticChain diagnostics,
				final Map<Object, Object> context) {

			for (Map.Entry<EModelElement, Element> entry : eModelElementToElementMap
				.entrySet()) {
				EModelElement eModelElement = entry.getKey();

				if (eModelElement instanceof EStructuralFeature) {
					EAnnotation unionEAnnotation = getEAnnotation(
						eModelElement, ANNOTATION__UNION, false);

					if (unionEAnnotation != null) {
						Property property = (Property) entry.getValue();

						if (OPTION__PROCESS.equals(options
							.get(OPTION__UNION_ANNOTATIONS))) {

							if (diagnostics != null) {
								diagnostics
									.add(new BasicDiagnostic(
										Diagnostic.INFO,
										UMLValidator.DIAGNOSTIC_SOURCE,
										UNION_ANNOTATION,
										UMLPlugin.INSTANCE
											.getString(
												"_UI_Ecore2UMLConverter_ProcessUnionAnnotation_diagnostic", //$NON-NLS-1$
												getMessageSubstitutions(
													context, property)),
										new Object[]{property}));
							}

							property.setIsDerivedUnion(true);
						} else if (OPTION__REPORT.equals(options
							.get(OPTION__UNION_ANNOTATIONS))
							&& diagnostics != null) {

							diagnostics
								.add(new BasicDiagnostic(
									Diagnostic.WARNING,
									UMLValidator.DIAGNOSTIC_SOURCE,
									UNION_ANNOTATION,
									UMLPlugin.INSTANCE
										.getString(
											"_UI_Ecore2UMLConverter_ReportUnionAnnotation_diagnostic", //$NON-NLS-1$
											getMessageSubstitutions(context,
												property)),
									new Object[]{property}));
						}
					}
				}
			}
		}

		protected void processAnnotationDetails(
				final Map<String, String> options,
				final DiagnosticChain diagnostics,
				final Map<Object, Object> context) {

			for (final Map.Entry<EModelElement, Element> entry : eModelElementToElementMap
				.entrySet()) {
				Element element = entry.getValue();

				if (element != null) {
					EModelElement eModelElement = entry.getKey();

					for (EAnnotation eAnnotation : eModelElement
						.getEAnnotations()) {

						EMap<String, String> details = eAnnotation.getDetails();

						if (!details.isEmpty()) {

							if (OPTION__PROCESS.equals(options
								.get(OPTION__ANNOTATION_DETAILS))) {

								if (diagnostics != null) {
									diagnostics
										.add(new BasicDiagnostic(
											Diagnostic.INFO,
											UMLValidator.DIAGNOSTIC_SOURCE,
											ANNOTATION_DETAILS,
											UMLPlugin.INSTANCE
												.getString(
													"_UI_Ecore2UMLConverter_ProcessAnnotationDetails_diagnostic", //$NON-NLS-1$
													getMessageSubstitutions(
														context, element,
														eAnnotation.getSource())),
											new Object[]{element}));
								}

								getEAnnotation(element,
									eAnnotation.getSource(), true).getDetails()
									.putAll(details.map());
							} else if (OPTION__REPORT.equals(options
								.get(OPTION__ANNOTATION_DETAILS))
								&& diagnostics != null) {

								diagnostics
									.add(new BasicDiagnostic(
										Diagnostic.WARNING,
										UMLValidator.DIAGNOSTIC_SOURCE,
										ANNOTATION_DETAILS,
										UMLPlugin.INSTANCE
											.getString(
												"_UI_Ecore2UMLConverter_ReportAnnotationDetails_diagnostic", //$NON-NLS-1$
												getMessageSubstitutions(
													context, element,
													eAnnotation.getSource())),
										new Object[]{element}));
							}
						}
					}
				}
			}
		}

		protected void processOptions(Map<String, String> options,
				DiagnosticChain diagnostics, Map<Object, Object> context) {

			if (!OPTION__IGNORE
				.equals(options.get(OPTION__ECORE_TAGGED_VALUES))) {

				processEcoreTaggedValues(options, diagnostics, context);
			}

			if (!OPTION__IGNORE.equals(options
				.get(OPTION__REDEFINES_ANNOTATIONS))) {

				processRedefinesAnnotations(options, diagnostics, context);
			}

			if (!OPTION__IGNORE
				.equals(options.get(OPTION__SUBSETS_ANNOTATIONS))) {

				processSubsetsAnnotations(options, diagnostics, context);
			}

			if (!OPTION__IGNORE.equals(options.get(OPTION__UNION_ANNOTATIONS))) {
				processUnionAnnotations(options, diagnostics, context);
			}

			if (!OPTION__IGNORE.equals(options.get(OPTION__ANNOTATION_DETAILS))) {
				processAnnotationDetails(options, diagnostics, context);
			}
		}

		public Collection<? extends EObject> convert(
				Collection<? extends EObject> eObjects,
				Map<String, String> options, DiagnosticChain diagnostics,
				Map<Object, Object> context) {
			ePackages = EcoreUtil.getObjectsByType(eObjects,
				EcorePackage.Literals.EPACKAGE);

			for (EPackage ePackage : ePackages) {
				doSwitch(ePackage);
			}

			if (options != null) {
				processOptions(options, diagnostics, context);
			}

			return getRootContainers(EcoreUtil
				.<EObject> getObjectsByType(eModelElementToElementMap.values(),
					UMLPackage.Literals.PACKAGE));
		}
	}

	/**
	 * Represents an option choice of 'discard'.
	 */
	public static final String OPTION__DISCARD = "DISCARD"; //$NON-NLS-1$

	/**
	 * Represents an option choice of 'ignore'.
	 */
	public static final String OPTION__IGNORE = "IGNORE"; //$NON-NLS-1$

	/**
	 * Represents an option choice of 'process'.
	 */
	public static final String OPTION__PROCESS = "PROCESS"; //$NON-NLS-1$

	/**
	 * Represents an option choice of 'report'.
	 */
	public static final String OPTION__REPORT = "REPORT"; //$NON-NLS-1$

	protected static final String ANNOTATION__DUPLICATES = "duplicates"; //$NON-NLS-1$

	protected static final String ANNOTATION__REDEFINES = "redefines"; //$NON-NLS-1$

	protected static final String ANNOTATION__SUBSETS = "subsets"; //$NON-NLS-1$

	protected static final String ANNOTATION__UNION = "union"; //$NON-NLS-1$

	protected static final String ENUMERATION_LITERAL__ATTRIBUTE = "Attribute"; //$NON-NLS-1$

	protected static final String ENUMERATION_LITERAL__ATTRIBUTE_WILDCARD = "AttributeWilcard"; //$NON-NLS-1$

	protected static final String ENUMERATION_LITERAL__ELEMENT = "Element"; //$NON-NLS-1$

	protected static final String ENUMERATION_LITERAL__ELEMENT_ONLY = "ElementOnly"; //$NON-NLS-1$

	protected static final String ENUMERATION_LITERAL__ELEMENT_WILDCARD = "ElementWildcard"; //$NON-NLS-1$

	protected static final String ENUMERATION_LITERAL__EMPTY = "Empty"; //$NON-NLS-1$

	protected static final String ENUMERATION_LITERAL__GROUP = "Group"; //$NON-NLS-1$

	protected static final String ENUMERATION_LITERAL__MIXED = "Mixed"; //$NON-NLS-1$

	protected static final String ENUMERATION_LITERAL__NONE = "None"; //$NON-NLS-1$

	protected static final String ENUMERATION_LITERAL__SIMPLE = "Simple"; //$NON-NLS-1$

	protected static final String ENUMERATION_LITERAL__READ_ONLY = "ReadOnly"; //$NON-NLS-1$

	protected static final String ENUMERATION_LITERAL__READ_ONLY_UNSETTABLE = "ReadOnlyUnsettable"; //$NON-NLS-1$

	protected static final String ENUMERATION_LITERAL__READ_WRITE = "ReadWrite"; //$NON-NLS-1$

	protected static final String ENUMERATION_LITERAL__READ_WRITE_UNSETTABLE = "ReadWriteUnsettable"; //$NON-NLS-1$

	protected static final String ENUMERATION_LITERAL__UNSPECIFIED = "Unspecified"; //$NON-NLS-1$

	protected static final String ENUMERATION__CONTENT_KIND = "ContentKind"; //$NON-NLS-1$

	protected static final String ENUMERATION__FEATURE_KIND = "FeatureKind"; //$NON-NLS-1$

	protected static final String ENUMERATION__VISIBILITY_KIND = "VisibilityKind"; //$NON-NLS-1$

	/**
	 * The name of the 'EAttribute' stereotype.
	 */
	public static final String STEREOTYPE__E_ATTRIBUTE = "EAttribute"; //$NON-NLS-1$

	/**
	 * The name of the 'EClass' stereotype.
	 */
	public static final String STEREOTYPE__E_CLASS = "EClass"; //$NON-NLS-1$

	/**
	 * The name of the 'EDataType' stereotype.
	 */
	public static final String STEREOTYPE__E_DATA_TYPE = "EDataType"; //$NON-NLS-1$

	/**
	 * The name of the 'EEnum' stereotype.
	 */
	public static final String STEREOTYPE__E_ENUM = "EEnum"; //$NON-NLS-1$

	/**
	 * The name of the 'EEnumLiteral' stereotype.
	 */
	public static final String STEREOTYPE__E_ENUM_LITERAL = "EEnumLiteral"; //$NON-NLS-1$

	/**
	 * The name of the 'EOperation' stereotype.
	 */
	public static final String STEREOTYPE__E_OPERATION = "EOperation"; //$NON-NLS-1$

	/**
	 * The name of the 'EPackage' stereotype.
	 */
	public static final String STEREOTYPE__E_PACKAGE = "EPackage"; //$NON-NLS-1$

	/**
	 * The name of the 'EParameter' stereotype.
	 */
	public static final String STEREOTYPE__E_PARAMETER = "EParameter"; //$NON-NLS-1$

	/**
	 * The name of the 'EReference' stereotype.
	 */
	public static final String STEREOTYPE__E_REFERENCE = "EReference"; //$NON-NLS-1$

	/**
	 * The name of the 'attributeName' stereotype property.
	 */
	public static final String TAG_DEFINITION__ATTRIBUTE_NAME = "attributeName"; //$NON-NLS-1$

	/**
	 * The name of the 'basePackage' stereotype property.
	 */
	public static final String TAG_DEFINITION__BASE_PACKAGE = "basePackage"; //$NON-NLS-1$

	/**
	 * The name of the 'className' stereotype property.
	 */
	public static final String TAG_DEFINITION__CLASS_NAME = "className"; //$NON-NLS-1$

	/**
	 * The name of the 'dataTypeName' stereotype property.
	 */
	public static final String TAG_DEFINITION__DATA_TYPE_NAME = "dataTypeName"; //$NON-NLS-1$

	/**
	 * The name of the 'enumName' stereotype property.
	 */
	public static final String TAG_DEFINITION__ENUM_NAME = "enumName"; //$NON-NLS-1$

	/**
	 * The name of the 'enumLiteralName' stereotype property.
	 */
	public static final String TAG_DEFINITION__ENUM_LITERAL_NAME = "enumLiteralName"; //$NON-NLS-1$

	/**
	 * The name of the 'instanceClassName' stereotype property.
	 */
	public static final String TAG_DEFINITION__INSTANCE_CLASS_NAME = "instanceClassName"; //$NON-NLS-1$

	/**
	 * The name of the 'isID' stereotype property.
	 */
	public static final String TAG_DEFINITION__IS_ID = "isID"; //$NON-NLS-1$

	/**
	 * The name of the 'isResolveProxies' stereotype property.
	 */
	public static final String TAG_DEFINITION__IS_RESOLVE_PROXIES = "isResolveProxies"; //$NON-NLS-1$

	/**
	 * The name of the 'isTransient' stereotype property.
	 */
	public static final String TAG_DEFINITION__IS_TRANSIENT = "isTransient"; //$NON-NLS-1$

	/**
	 * The name of the 'isUnsettable' stereotype property.
	 */
	public static final String TAG_DEFINITION__IS_UNSETTABLE = "isUnsettable"; //$NON-NLS-1$

	/**
	 * The name of the 'isVolatile' stereotype property.
	 */
	public static final String TAG_DEFINITION__IS_VOLATILE = "isVolatile"; //$NON-NLS-1$

	/**
	 * The name of the 'nsPrefix' stereotype property.
	 */
	public static final String TAG_DEFINITION__NS_PREFIX = "nsPrefix"; //$NON-NLS-1$

	/**
	 * The name of the 'nsURI' stereotype property.
	 */
	public static final String TAG_DEFINITION__NS_URI = "nsURI"; //$NON-NLS-1$

	/**
	 * The name of the 'operationName' stereotype property.
	 */
	public static final String TAG_DEFINITION__OPERATION_NAME = "operationName"; //$NON-NLS-1$

	/**
	 * The name of the 'packageName' stereotype property.
	 */
	public static final String TAG_DEFINITION__PACKAGE_NAME = "packageName"; //$NON-NLS-1$

	/**
	 * The name of the 'parameterName' stereotype property.
	 */
	public static final String TAG_DEFINITION__PARAMETER_NAME = "parameterName"; //$NON-NLS-1$

	/**
	 * The name of the 'prefix' stereotype property.
	 */
	public static final String TAG_DEFINITION__PREFIX = "prefix"; //$NON-NLS-1$

	/**
	 * The name of the 'referenceName' stereotype property.
	 */
	public static final String TAG_DEFINITION__REFERENCE_NAME = "referenceName"; //$NON-NLS-1$

	/**
	 * The name of the 'visibility' stereotype property.
	 */
	public static final String TAG_DEFINITION__VISIBILITY = "visibility"; //$NON-NLS-1$

	/**
	 * The name of the 'xmlContentKind' stereotype property.
	 */
	public static final String TAG_DEFINITION__XML_CONTENT_KIND = "xmlContentKind"; //$NON-NLS-1$

	/**
	 * The name of the 'xmlFeatureKind' stereotype property.
	 */
	public static final String TAG_DEFINITION__XML_FEATURE_KIND = "xmlFeatureKind"; //$NON-NLS-1$

	/**
	 * The name of the 'xmlName' stereotype property.
	 */
	public static final String TAG_DEFINITION__XML_NAME = "xmlName"; //$NON-NLS-1$

	/**
	 * The name of the 'xmlNamespace' stereotype property.
	 */
	public static final String TAG_DEFINITION__XML_NAMESPACE = "xmlNamespace"; //$NON-NLS-1$

	/**
	 * Retrieves a qualified textual representation of the specified object
	 * using the default qualified text provider.
	 * 
	 * @param eObject
	 *            The object for which to retrieve qualified text.
	 * @return A qualified textual representation of the object.
	 */
	public static String getQualifiedText(EObject eObject) {
		return getQualifiedText(eObject, QualifiedTextProvider.DEFAULT);
	}

	protected static String getQualifiedName(NamedElement namedElement,
			String separator) {
		String name = namedElement.getName();

		if (isEmpty(name)) {
			return null;
		}

		StringBuffer qualifiedName = new StringBuffer(name);

		for (Namespace namespace : namedElement.allNamespaces()) {
			String namespaceName = namespace.getName();

			if (isEmpty(namespaceName)) {
				return null;
			} else {
				qualifiedName.insert(0, separator);
				qualifiedName.insert(0, namespaceName);
			}
		}

		return qualifiedName.toString();
	}

	/**
	 * Retrieves the named element(s) with the specified qualified name from the
	 * specified resource set.
	 * 
	 * @param resourceSet
	 *            The resource set in which to search.
	 * @param qualifiedName
	 *            The qualified name of the element(s) to be found.
	 * @return The named element(s).
	 */
	public static <NE extends NamedElement> Collection<NE> findNamedElements(
			ResourceSet resourceSet, String qualifiedName) {
		return findNamedElements(resourceSet, qualifiedName, false);
	}

	/**
	 * Retrieves the named element(s) with the specified qualified name from the
	 * specified resource set, optionally ignoring case when doing name
	 * comparisons.
	 * 
	 * @param resourceSet
	 *            The resource set in which to search.
	 * @param qualifiedName
	 *            The qualified name of the element(s) to be found.
	 * @param ignoreCase
	 *            Whether to ignore case when doing name comparisons.
	 * @return The named element(s).
	 */
	public static <NE extends NamedElement> Collection<NE> findNamedElements(
			ResourceSet resourceSet, String qualifiedName, boolean ignoreCase) {
		return findNamedElements(resourceSet, qualifiedName, ignoreCase,
			UMLPackage.Literals.NAMED_ELEMENT);
	}

	/**
	 * Retrieves the named element(s) of the specified type with the specified
	 * qualified name from the specified resource set, optionally ignoring case
	 * when doing name comparisons.
	 * 
	 * @param resourceSet
	 *            The resource set in which to search.
	 * @param qualifiedName
	 *            The qualified name of the element(s) to be found.
	 * @param ignoreCase
	 *            Whether to ignore case when doing name comparisons.
	 * @param eClass
	 *            The type of the element(s) to be found.
	 * @return The named element(s).
	 */
	public static <NE extends NamedElement> Collection<NE> findNamedElements(
			ResourceSet resourceSet, String qualifiedName, boolean ignoreCase,
			EClass eClass) {

		if (!isEmpty(qualifiedName)
			&& UMLPackage.Literals.NAMED_ELEMENT.isSuperTypeOf(eClass)) {

			EList<Resource> resources = resourceSet.getResources();
			int size = resources.size();

			if (size > 0) {
				EList<NE> namedElements = new UniqueEList.FastCompare<NE>();

				for (int i = 0; i < size; i++) {
					findNamedElements(resources.get(i).getContents(),
						qualifiedName, ignoreCase, eClass, namedElements);
				}

				return ECollections.unmodifiableEList(namedElements);
			}
		}

		return ECollections.<NE> emptyEList();
	}

	/**
	 * Retrieves the named element(s) with the specified qualified name from the
	 * specified resource.
	 * 
	 * @param resource
	 *            The resource in which to search.
	 * @param qualifiedName
	 *            The qualified name of the element(s) to be found.
	 * @return The named element(s).
	 */
	public static <NE extends NamedElement> Collection<NE> findNamedElements(
			Resource resource, String qualifiedName) {
		return findNamedElements(resource, qualifiedName, false);
	}

	/**
	 * Retrieves the named element(s) with the specified qualified name from the
	 * specified resource, optionally ignoring case when doing name comparisons.
	 * 
	 * @param resource
	 *            The resource in which to search.
	 * @param qualifiedName
	 *            The qualified name of the element(s) to be found.
	 * @param ignoreCase
	 *            Whether to ignore case when doing name comparisons.
	 * @return The named element(s).
	 */
	public static <NE extends NamedElement> Collection<NE> findNamedElements(
			Resource resource, String qualifiedName, boolean ignoreCase) {
		return findNamedElements(resource, qualifiedName, ignoreCase,
			UMLPackage.Literals.NAMED_ELEMENT);
	}

	/**
	 * Retrieves the named element(s) of the specified type with the specified
	 * qualified name from the specified resource, optionally ignoring case when
	 * doing name comparisons.
	 * 
	 * @param resource
	 *            The resource in which to search.
	 * @param qualifiedName
	 *            The qualified name of the element(s) to be found.
	 * @param ignoreCase
	 *            Whether to ignore case when doing name comparisons.
	 * @param eClass
	 *            The type of the element(s) to be found.
	 * @return The named element(s).
	 */
	public static <NE extends NamedElement> Collection<NE> findNamedElements(
			Resource resource, String qualifiedName, boolean ignoreCase,
			EClass eClass) {

		if (!isEmpty(qualifiedName)
			&& UMLPackage.Literals.NAMED_ELEMENT.isSuperTypeOf(eClass)) {

			EList<EObject> contents = resource.getContents();

			if (!contents.isEmpty()) {
				EList<NE> namedElements = new UniqueEList.FastCompare<NE>();

				findNamedElements(contents, qualifiedName, ignoreCase, eClass,
					namedElements);

				return ECollections.unmodifiableEList(namedElements);
			}
		}

		return ECollections.<NE> emptyEList();
	}

	protected static <NE extends NamedElement> Collection<NE> findNamedElements(
			Collection<? extends EObject> eObjects, String qualifiedName,
			boolean ignoreCase, EClass eClass, Collection<NE> namedElements) {
		int index = qualifiedName.indexOf(NamedElement.SEPARATOR);

		if (index == -1) {

			for (NE member : EcoreUtil.<NE> getObjectsByType(eObjects, eClass)) {

				if (ignoreCase
					? qualifiedName.equalsIgnoreCase(member.getName())
					: qualifiedName.equals(member.getName())) {

					namedElements.add(member);
				}
			}
		} else {
			String name = qualifiedName.substring(0, index);
			qualifiedName = qualifiedName.substring(index
				+ NamedElement.SEPARATOR.length());

			for (Namespace namespace : EcoreUtil.<Namespace> getObjectsByType(
				eObjects, UMLPackage.Literals.NAMESPACE)) {

				if (ignoreCase
					? name.equalsIgnoreCase(namespace.getName())
					: name.equals(namespace.getName())) {

					findNamedElements(namespace.getMembers(), qualifiedName,
						ignoreCase, eClass, namedElements);
				}
			}
		}

		return namedElements;
	}

	/**
	 * Retrieves the profile for which the specified package represents a
	 * definition.
	 * 
	 * @param definition
	 *            The package.
	 * @return The profile.
	 */
	public static Profile getProfile(EPackage definition) {
		EObject eContainer = definition.eContainer();

		if (eContainer instanceof EAnnotation) {
			EAnnotation eAnnotation = (EAnnotation) eContainer;

			if (safeEquals(eAnnotation.getSource(), UMLPackage.eNS_URI)) {
				eContainer = eAnnotation.eContainer();

				if (eContainer instanceof Profile) {
					return (Profile) eContainer;
				}
			}
		}

		return null;
	}

	protected static EClassifier getEClassifier(
			org.eclipse.uml2.uml.Class metaclass) {
		Resource eResource = metaclass.eResource();

		if (eResource == null
			|| !UMLResource.UML_METAMODEL_URI.equals(eResource.getURI())) {

			Model model = metaclass.getModel();

			if (model != null) {
				EPackage ePackage = EPackage.Registry.INSTANCE
					.getEPackage((String) getTaggedValue(model, "Ecore" //$NON-NLS-1$
						+ NamedElement.SEPARATOR + STEREOTYPE__E_PACKAGE,
						TAG_DEFINITION__NS_URI));

				if (ePackage != null) {
					return ePackage.getEClassifier(metaclass.getName());
				}
			}
		}

		return UMLPackage.eINSTANCE.getEClassifier(metaclass.getName());
	}

	protected static NamedElement getNamedElement(ENamedElement definition) {

		if (definition instanceof EClassifier) {
			EAnnotation eAnnotation = definition
				.getEAnnotation(UMLPackage.eNS_URI);

			if (eAnnotation != null) {
				EList<EObject> references = eAnnotation.getReferences();

				if (!references.isEmpty()) {
					EObject reference = references.get(0);

					if (reference instanceof Classifier) {
						return (NamedElement) reference;
					}
				}
			}

			return null;
		} else if (definition instanceof EStructuralFeature) {
			org.eclipse.uml2.uml.Class class_ = (org.eclipse.uml2.uml.Class) getNamedElement(((EStructuralFeature) definition)
				.getEContainingClass());

			if (class_ != null) {
				String name = definition.getName();

				for (Property ownedAttribute : class_.getOwnedAttributes()) {

					if (safeEquals(getValidJavaIdentifier(ownedAttribute
						.getName()), name)) {

						return ownedAttribute;
					}
				}
			}

			return null;
		} else if (definition instanceof EEnumLiteral) {
			Enumeration enumeration = (Enumeration) getNamedElement(((EEnumLiteral) definition)
				.getEEnum());
			return enumeration == null
				? null
				: enumeration.getOwnedLiteral(definition.getName());
		} else if (definition instanceof EPackage) {
			return getProfile((EPackage) definition);
		} else {
			return null;
		}
	}

	protected static Stereotype getStereotype(EClass definition) {
		NamedElement namedElement = getNamedElement(definition);
		return namedElement instanceof Stereotype
			? (Stereotype) namedElement
			: null;
	}

	/**
	 * Retrieves the stereotype for which the specified object represents an
	 * application.
	 * 
	 * @param stereotypeApplication
	 *            The object.
	 * @return The stereotype.
	 */
	public static Stereotype getStereotype(EObject stereotypeApplication) {
		return stereotypeApplication == null
			? null
			: getStereotype(stereotypeApplication.eClass());
	}

	/**
	 * Retrieves the base element for the specified stereotype application, i.e.
	 * the element to which the stereotype is applied.
	 * 
	 * @param stereotypeApplication
	 *            The stereotype application.
	 * @return The base element.
	 */
	public static Element getBaseElement(EObject stereotypeApplication) {

		if (stereotypeApplication != null) {
			EClass eClass = stereotypeApplication.eClass();

			if (getStereotype(eClass) != null) {

				for (EStructuralFeature eStructuralFeature : eClass
					.getEAllStructuralFeatures()) {

					if (eStructuralFeature.getName().startsWith(
						Extension.METACLASS_ROLE_PREFIX)) {

						Object value = stereotypeApplication
							.eGet(eStructuralFeature);

						if (value instanceof Element) {
							return (Element) value;
						}
					}
				}
			}
		}

		return null;
	}

	/**
	 * Sets the base element for the specified stereotype application to the
	 * specified element.
	 * 
	 * @param stereotypeApplication
	 *            The stereotype application.
	 * @param element
	 *            The new base element.
	 */
	public static void setBaseElement(EObject stereotypeApplication,
			Element element) {

		if (stereotypeApplication != null) {
			EClass eClass = stereotypeApplication.eClass();

			if (getStereotype(eClass) != null) {

				for (EStructuralFeature eStructuralFeature : eClass
					.getEAllStructuralFeatures()) {

					if (eStructuralFeature.getName().startsWith(
						Extension.METACLASS_ROLE_PREFIX)
						&& (element == null || eStructuralFeature.getEType()
							.isInstance(element))) {

						stereotypeApplication.eSet(eStructuralFeature, element);
					}
				}
			}
		}
	}

	protected static EObject applyStereotype(Element element, EClass definition) {
		EObject stereotypeApplication = EcoreUtil.create(definition);

		CacheAdapter.INSTANCE.adapt(stereotypeApplication);

		Resource eResource = element.eResource();

		if (eResource != null) {
			eResource.getContents().add(stereotypeApplication);
		}

		setBaseElement(stereotypeApplication, element);

		return stereotypeApplication;
	}

	/**
	 * Safely applies the specified stereotype to the specified element, i.e.
	 * applies the profile if not already applied.
	 * 
	 * @param element
	 *            The element to which to apply the stereotype.
	 * @param stereotype
	 *            The stereotype to apply.
	 * @return The stereotype application.
	 */
	public static EObject safeApplyStereotype(Element element,
			Stereotype stereotype) {

		if (stereotype != null) {
			EObject stereotypeApplication = element
				.getStereotypeApplication(stereotype);

			if (stereotypeApplication == null) {
				org.eclipse.uml2.uml.Package nearestPackage = element
					.getNearestPackage();

				if (nearestPackage != null) {
					Profile profile = stereotype.getProfile();

					if (!nearestPackage.getAllAppliedProfiles().contains(
						profile)) {

						EList<org.eclipse.uml2.uml.Package> allOwningPackages = nearestPackage
							.allOwningPackages();
						int size = allOwningPackages.size();

						(size > 0
							? allOwningPackages.get(size - 1)
							: nearestPackage).applyProfile(profile);
					}

					stereotypeApplication = element.applyStereotype(stereotype);
				}
			}

			return stereotypeApplication;
		}

		return null;
	}

	protected static Property getTagDefinition(Stereotype stereotype,
			final String propertyName) {

		return findEObject(stereotype.getAllAttributes(), new EObjectMatcher() {

			public boolean matches(EObject eObject) {
				return safeEquals(((Property) eObject).getName(), propertyName);
			}
		});
	}

	protected static Object getTaggedValue(Element element,
			String qualifiedStereotypeName, String propertyName) {
		Stereotype stereotype = element
			.getAppliedStereotype(qualifiedStereotypeName);

		return stereotype == null
			? null
			: element.getValue(stereotype, propertyName);
	}

	/**
	 * Sets the value of the specified property of the specified stereotype
	 * application on the specified element.
	 * 
	 * @param element
	 *            The element to which the stereotype is applied.
	 * @param stereotype
	 *            The stereotype.
	 * @param propertyName
	 *            The name of the stereotype property.
	 * @param value
	 *            The new value.
	 * @return <code>true</code> if the value was successfully set;
	 *         <code>false</code> otherwise.
	 */
	public static boolean setTaggedValue(Element element,
			Stereotype stereotype, String propertyName, Object value) {

		if (safeApplyStereotype(element, stereotype) != null) {
			element.setValue(stereotype, propertyName, value);
			return true;
		}

		return false;
	}

	protected static EList<Property> getOwnedAttributes(Type type) {
		@SuppressWarnings("unchecked")
		EList<Property> ownedAttributes = (EList<Property>) new UMLSwitch() {

			@Override
			public Object caseArtifact(Artifact artifact) {
				return artifact.getOwnedAttributes();
			}

			@Override
			public Object caseDataType(DataType dataType) {
				return dataType.getOwnedAttributes();
			}

			@Override
			public Object caseInterface(Interface interface_) {
				return interface_.getOwnedAttributes();
			}

			@Override
			public Object caseSignal(Signal signal) {
				return signal.getOwnedAttributes();
			}

			@Override
			public Object caseStructuredClassifier(
					StructuredClassifier structuredClassifier) {
				return structuredClassifier.getOwnedAttributes();
			}

			@Override
			public Object doSwitch(EObject eObject) {
				return eObject == null
					? null
					: super.doSwitch(eObject);
			}
		}.doSwitch(type);

		return ownedAttributes;
	}

	protected static EList<Operation> getOwnedOperations(Type type) {
		@SuppressWarnings("unchecked")
		EList<Operation> ownedOperations = (EList<Operation>) new UMLSwitch() {

			@Override
			public Object caseArtifact(Artifact artifact) {
				return artifact.getOwnedOperations();
			}

			@Override
			public Object caseClass(org.eclipse.uml2.uml.Class class_) {
				return class_.getOwnedOperations();
			}

			@Override
			public Object caseDataType(DataType dataType) {
				return dataType.getOwnedOperations();
			}

			@Override
			public Object caseInterface(Interface interface_) {
				return interface_.getOwnedOperations();
			}

			@Override
			public Object doSwitch(EObject eObject) {
				return eObject == null
					? null
					: super.doSwitch(eObject);
			}
		}.doSwitch(type);

		return ownedOperations;
	}

	protected static EList<Feature> getRedefinedFeatures(Feature feature) {
		@SuppressWarnings("unchecked")
		EList<Feature> redefinedFeatures = (EList<Feature>) new UMLSwitch() {

			@Override
			public Object caseOperation(Operation operation) {
				return operation.getRedefinedOperations();
			}

			@Override
			public Object caseProperty(Property property) {
				return property.getRedefinedProperties();
			}

			@Override
			public Object defaultCase(EObject eObject) {
				return ECollections.<Feature> emptyEList();
			}
		}.doSwitch(feature);

		return redefinedFeatures;
	}

	protected static boolean isRedefinitionValid(Feature redefiningFeature,
			Feature redefinedFeature) {
		return redefinedFeature.isConsistentWith(redefiningFeature);
	}

	protected static <F extends Feature> Collection<F> findValidRedefinitions(
			F redefiningFeature, String name) {
		Collection<F> redefinedFeatures = new UniqueEList.FastCompare<F>();

		for (Classifier redefinitionContext : redefiningFeature
			.getRedefinitionContexts()) {

			findValidRedefinitions(redefinedFeatures, redefiningFeature, name,
				redefinitionContext);
		}

		return redefinedFeatures;
	}

	protected static <F extends Feature> Collection<F> findValidRedefinitions(
			Collection<F> redefinedFeatures, F redefiningFeature,
			final String name, Classifier redefinitionContext) {
		F redefinedFeature = findEObject(redefinitionContext.getFeatures(),
			new EClassMatcher(redefiningFeature) {

				@Override
				public boolean matches(EObject otherEObject) {

					if (super.matches(otherEObject)) {
						Feature otherFeature = (Feature) otherEObject;

						return eObject != otherFeature
							&& safeEquals(otherFeature.getName(), name)
							&& isRedefinitionValid((Feature) eObject,
								otherFeature);
					}

					return false;
				}
			});

		if (redefinedFeature == null) {

			for (Classifier general : redefinitionContext.getGenerals()) {
				findValidRedefinitions(redefinedFeatures, redefiningFeature,
					name, general);
			}
		} else {
			redefinedFeatures.add(redefinedFeature);
		}

		return redefinedFeatures;
	}

	protected static boolean isSubsetValid(Property subsettingProperty,
			Property subsettedProperty) {

		for (Type subsettingContext : subsettingProperty.subsettingContext()) {

			for (Type subsettedContext : subsettedProperty.subsettingContext()) {

				if (!subsettingContext.conformsTo(subsettedContext)) {
					return false;
				}
			}
		}

		return true;
	}

	protected static Collection<Property> findValidSubsets(
			Property subsettingProperty, String name) {
		Collection<Property> subsettedProperties = new UniqueEList.FastCompare<Property>();

		for (Type subsettingContext : subsettingProperty.subsettingContext()) {

			findValidSubsets(subsettedProperties, subsettingProperty, name,
				(Classifier) subsettingContext);
		}

		return subsettedProperties;
	}

	protected static Collection<Property> findValidSubsets(
			Collection<Property> subsettedProperties,
			Property subsettingProperty, final String name,
			Classifier subsettingContext) {
		Property subsettedProperty = findEObject(subsettingContext
			.getAttributes(), new EClassMatcher(subsettingProperty) {

			@Override
			public boolean matches(EObject otherEObject) {

				if (super.matches(otherEObject)) {
					Property otherProperty = (Property) otherEObject;

					return eObject != otherProperty
						&& safeEquals(otherProperty.getName(), name)
						&& isSubsetValid((Property) eObject, otherProperty);
				}

				return false;
			}
		});

		if (subsettedProperty == null) {

			for (Classifier general : subsettingContext.getGenerals()) {
				findValidSubsets(subsettedProperties, subsettingProperty, name,
					general);
			}
		} else {
			subsettedProperties.add(subsettedProperty);
		}

		return subsettedProperties;
	}

	/**
	 * Merges the contents of (all of) the packages merged by the specified
	 * package using the specified options. If a supported option is not
	 * specified, it will be defaulted to <code>OPTION__IGNORE</code>.
	 * 
	 * @param package_
	 *            The receiving package.
	 * @param options
	 *            The options to use.
	 */
	public static void merge(org.eclipse.uml2.uml.Package package_,
			Map<String, String> options) {

		if (options == null) {
			options = new HashMap<String, String>();
		}

		if (!options
			.containsKey(PackageMerger.OPTION__DIFFERENT_PROPERTY_STATICITY)) {

			options.put(PackageMerger.OPTION__DIFFERENT_PROPERTY_STATICITY,
				OPTION__IGNORE);
		}

		if (!options
			.containsKey(PackageMerger.OPTION__DIFFERENT_PROPERTY_UNIQUENESS)) {

			options.put(PackageMerger.OPTION__DIFFERENT_PROPERTY_UNIQUENESS,
				OPTION__IGNORE);
		}

		if (!options
			.containsKey(PackageMerger.OPTION__REDUNDANT_GENERALIZATIONS)) {

			options.put(PackageMerger.OPTION__REDUNDANT_GENERALIZATIONS,
				OPTION__IGNORE);
		}

		if (!options.containsKey(PackageMerger.OPTION__IMPLICIT_REDEFINITIONS)) {
			options.put(PackageMerger.OPTION__IMPLICIT_REDEFINITIONS,
				OPTION__IGNORE);
		}

		if (!options.containsKey(PackageMerger.OPTION__INVALID_REDEFINITIONS)) {
			options.put(PackageMerger.OPTION__INVALID_REDEFINITIONS,
				OPTION__IGNORE);
		}

		if (!options.containsKey(PackageMerger.OPTION__INVALID_SUBSETS)) {
			options.put(PackageMerger.OPTION__INVALID_SUBSETS, OPTION__IGNORE);
		}

		if (!options.containsKey(PackageMerger.OPTION__EMPTY_UNIONS)) {
			options.put(PackageMerger.OPTION__EMPTY_UNIONS, OPTION__IGNORE);
		}

		if (!options
			.containsKey(PackageMerger.OPTION__ASSOCIATION_SPECIALIZATIONS)) {

			options.put(PackageMerger.OPTION__ASSOCIATION_SPECIALIZATIONS,
				OPTION__IGNORE);
		}

		if (!options.containsKey(PackageMerger.OPTION__CAPABILITIES)) {
			options.put(PackageMerger.OPTION__CAPABILITIES, OPTION__IGNORE);
		}

		merge(package_, options, null, null);
	}

	/**
	 * Merges the contents of (all of) the packages merged by the specified
	 * package using the specified options, reporting problems to the specified
	 * diagnostics, within the specified context. If a supported option is not
	 * specified, it will be defaulted to <code>OPTION__REPORT</code>.
	 * 
	 * @param package_
	 *            The receiving package.
	 * @param options
	 *            The options to use.
	 * @param diagnostics
	 *            The chain of diagnostics to which problems are to be appended.
	 * @param context
	 *            The cache of context-specific information.
	 */
	public static void merge(org.eclipse.uml2.uml.Package package_,
			Map<String, String> options, DiagnosticChain diagnostics,
			Map<Object, Object> context) {

		if (options == null) {
			options = new HashMap<String, String>();
		}

		if (!options
			.containsKey(PackageMerger.OPTION__DIFFERENT_PROPERTY_STATICITY)) {

			options.put(PackageMerger.OPTION__DIFFERENT_PROPERTY_STATICITY,
				OPTION__REPORT);
		}

		if (!options
			.containsKey(PackageMerger.OPTION__DIFFERENT_PROPERTY_UNIQUENESS)) {

			options.put(PackageMerger.OPTION__DIFFERENT_PROPERTY_UNIQUENESS,
				OPTION__REPORT);
		}

		if (!options
			.containsKey(PackageMerger.OPTION__REDUNDANT_GENERALIZATIONS)) {

			options.put(PackageMerger.OPTION__REDUNDANT_GENERALIZATIONS,
				OPTION__REPORT);
		}

		if (!options.containsKey(PackageMerger.OPTION__IMPLICIT_REDEFINITIONS)) {
			options.put(PackageMerger.OPTION__IMPLICIT_REDEFINITIONS,
				OPTION__REPORT);
		}

		if (!options.containsKey(PackageMerger.OPTION__INVALID_REDEFINITIONS)) {
			options.put(PackageMerger.OPTION__INVALID_REDEFINITIONS,
				OPTION__REPORT);
		}

		if (!options.containsKey(PackageMerger.OPTION__INVALID_SUBSETS)) {
			options.put(PackageMerger.OPTION__INVALID_SUBSETS, OPTION__REPORT);
		}

		if (!options.containsKey(PackageMerger.OPTION__EMPTY_UNIONS)) {
			options.put(PackageMerger.OPTION__EMPTY_UNIONS, OPTION__REPORT);
		}

		if (!options
			.containsKey(PackageMerger.OPTION__ASSOCIATION_SPECIALIZATIONS)) {

			options.put(PackageMerger.OPTION__ASSOCIATION_SPECIALIZATIONS,
				OPTION__REPORT);
		}

		if (!options.containsKey(PackageMerger.OPTION__CAPABILITIES)) {
			options.put(PackageMerger.OPTION__CAPABILITIES, OPTION__REPORT);
		}

		new PackageMerger().merge(package_, options, diagnostics, context);
	}

	/**
	 * Converts the specified package (and its contents) to Ecore using the
	 * specified options. If a supported option is not specified, it will be
	 * defaulted to <code>OPTION__IGNORE</code>.
	 * 
	 * @param package_
	 *            The package to convert.
	 * @param options
	 *            The options to use.
	 * @return An Ecore representation of the package.
	 */
	public static Collection<EPackage> convertToEcore(
			org.eclipse.uml2.uml.Package package_, Map<String, String> options) {

		if (options == null) {
			options = new HashMap<String, String>();
		}

		if (!options
			.containsKey(UML2EcoreConverter.OPTION__ECORE_TAGGED_VALUES)) {

			options.put(UML2EcoreConverter.OPTION__ECORE_TAGGED_VALUES,
				OPTION__IGNORE);
		}

		if (!options
			.containsKey(UML2EcoreConverter.OPTION__REDEFINING_OPERATIONS)) {

			options.put(UML2EcoreConverter.OPTION__REDEFINING_OPERATIONS,
				OPTION__IGNORE);
		}

		if (!options
			.containsKey(UML2EcoreConverter.OPTION__REDEFINING_PROPERTIES)) {

			options.put(UML2EcoreConverter.OPTION__REDEFINING_PROPERTIES,
				OPTION__IGNORE);
		}

		if (!options
			.containsKey(UML2EcoreConverter.OPTION__SUBSETTING_PROPERTIES)) {

			options.put(UML2EcoreConverter.OPTION__SUBSETTING_PROPERTIES,
				OPTION__IGNORE);
		}

		if (!options.containsKey(UML2EcoreConverter.OPTION__UNION_PROPERTIES)) {
			options.put(UML2EcoreConverter.OPTION__UNION_PROPERTIES,
				OPTION__IGNORE);
		}

		if (!options.containsKey(UML2EcoreConverter.OPTION__DERIVED_FEATURES)) {
			options.put(UML2EcoreConverter.OPTION__DERIVED_FEATURES,
				OPTION__IGNORE);
		}

		if (!options
			.containsKey(UML2EcoreConverter.OPTION__DUPLICATE_OPERATIONS)) {

			options.put(UML2EcoreConverter.OPTION__DUPLICATE_OPERATIONS,
				OPTION__IGNORE);
		}

		if (!options
			.containsKey(UML2EcoreConverter.OPTION__DUPLICATE_OPERATION_INHERITANCE)) {

			options.put(
				UML2EcoreConverter.OPTION__DUPLICATE_OPERATION_INHERITANCE,
				OPTION__IGNORE);
		}

		if (!options.containsKey(UML2EcoreConverter.OPTION__DUPLICATE_FEATURES)) {
			options.put(UML2EcoreConverter.OPTION__DUPLICATE_FEATURES,
				OPTION__IGNORE);
		}

		if (!options
			.containsKey(UML2EcoreConverter.OPTION__DUPLICATE_FEATURE_INHERITANCE)) {

			options.put(
				UML2EcoreConverter.OPTION__DUPLICATE_FEATURE_INHERITANCE,
				OPTION__IGNORE);
		}

		if (!options.containsKey(UML2EcoreConverter.OPTION__SUPER_CLASS_ORDER)) {
			options.put(UML2EcoreConverter.OPTION__SUPER_CLASS_ORDER,
				OPTION__IGNORE);
		}

		if (!options.containsKey(UML2EcoreConverter.OPTION__ANNOTATION_DETAILS)) {
			options.put(UML2EcoreConverter.OPTION__ANNOTATION_DETAILS,
				OPTION__IGNORE);
		}

		return convertToEcore(package_, options, null, null);
	}

	/**
	 * Converts the specified package (and its contents) to Ecore using the
	 * specified options, reporting problems to the specified diagnostics,
	 * within the specified context. If a supported option is not specified, it
	 * will be defaulted to <code>OPTION__REPORT</code>.
	 * 
	 * @param package_
	 *            The package to convert.
	 * @param options
	 *            The options to use.
	 * @param diagnostics
	 *            The chain of diagnostics to which problems are to be appended.
	 * @param context
	 *            The cache of context-specific information.
	 * @return An Ecore representation of the package.
	 */
	public static Collection<EPackage> convertToEcore(
			org.eclipse.uml2.uml.Package package_, Map<String, String> options,
			DiagnosticChain diagnostics, Map<Object, Object> context) {

		if (options == null) {
			options = new HashMap<String, String>();
		}

		if (!options
			.containsKey(UML2EcoreConverter.OPTION__ECORE_TAGGED_VALUES)) {

			options.put(UML2EcoreConverter.OPTION__ECORE_TAGGED_VALUES,
				OPTION__REPORT);
		}

		if (!options
			.containsKey(UML2EcoreConverter.OPTION__REDEFINING_OPERATIONS)) {

			options.put(UML2EcoreConverter.OPTION__REDEFINING_OPERATIONS,
				OPTION__REPORT);
		}

		if (!options
			.containsKey(UML2EcoreConverter.OPTION__REDEFINING_PROPERTIES)) {

			options.put(UML2EcoreConverter.OPTION__REDEFINING_PROPERTIES,
				OPTION__REPORT);
		}

		if (!options
			.containsKey(UML2EcoreConverter.OPTION__SUBSETTING_PROPERTIES)) {

			options.put(UML2EcoreConverter.OPTION__SUBSETTING_PROPERTIES,
				OPTION__REPORT);
		}

		if (!options.containsKey(UML2EcoreConverter.OPTION__UNION_PROPERTIES)) {
			options.put(UML2EcoreConverter.OPTION__UNION_PROPERTIES,
				OPTION__REPORT);
		}

		if (!options.containsKey(UML2EcoreConverter.OPTION__DERIVED_FEATURES)) {
			options.put(UML2EcoreConverter.OPTION__DERIVED_FEATURES,
				OPTION__REPORT);
		}

		if (!options
			.containsKey(UML2EcoreConverter.OPTION__DUPLICATE_OPERATIONS)) {

			options.put(UML2EcoreConverter.OPTION__DUPLICATE_OPERATIONS,
				OPTION__REPORT);
		}

		if (!options
			.containsKey(UML2EcoreConverter.OPTION__DUPLICATE_OPERATION_INHERITANCE)) {

			options.put(
				UML2EcoreConverter.OPTION__DUPLICATE_OPERATION_INHERITANCE,
				OPTION__REPORT);
		}

		if (!options.containsKey(UML2EcoreConverter.OPTION__DUPLICATE_FEATURES)) {
			options.put(UML2EcoreConverter.OPTION__DUPLICATE_FEATURES,
				OPTION__REPORT);
		}

		if (!options
			.containsKey(UML2EcoreConverter.OPTION__DUPLICATE_FEATURE_INHERITANCE)) {

			options.put(
				UML2EcoreConverter.OPTION__DUPLICATE_FEATURE_INHERITANCE,
				OPTION__REPORT);
		}

		if (!options.containsKey(UML2EcoreConverter.OPTION__SUPER_CLASS_ORDER)) {
			options.put(UML2EcoreConverter.OPTION__SUPER_CLASS_ORDER,
				OPTION__REPORT);
		}

		if (!options.containsKey(UML2EcoreConverter.OPTION__ANNOTATION_DETAILS)) {
			options.put(UML2EcoreConverter.OPTION__ANNOTATION_DETAILS,
				OPTION__REPORT);
		}

		@SuppressWarnings("unchecked")
		Collection<EPackage> ePackages = (Collection<EPackage>) new UML2EcoreConverter()
			.convert(Collections.singletonList(package_), options, diagnostics,
				context);

		return ePackages;
	}

	/**
	 * Converts the specified profile (and its contents) to Ecore using the
	 * specified options. If a supported option is not specified, it will be
	 * defaulted to <code>OPTION__IGNORE</code>.
	 * 
	 * @param profile
	 *            The profile to convert.
	 * @param options
	 *            The options to use.
	 * @return An Ecore representation of the profile.
	 */
	public static Collection<EPackage> convertToEcore(Profile profile,
			Map<String, String> options) {

		if (options == null) {
			options = new HashMap<String, String>();
		}

		if (!options
			.containsKey(UML2EcoreConverter.OPTION__ECORE_TAGGED_VALUES)) {

			options.put(UML2EcoreConverter.OPTION__ECORE_TAGGED_VALUES,
				OPTION__IGNORE);
		}

		if (!options
			.containsKey(UML2EcoreConverter.OPTION__REDEFINING_OPERATIONS)) {

			options.put(UML2EcoreConverter.OPTION__REDEFINING_OPERATIONS,
				OPTION__IGNORE);
		}

		if (!options
			.containsKey(UML2EcoreConverter.OPTION__REDEFINING_PROPERTIES)) {

			options.put(UML2EcoreConverter.OPTION__REDEFINING_PROPERTIES,
				OPTION__IGNORE);
		}

		if (!options
			.containsKey(UML2EcoreConverter.OPTION__SUBSETTING_PROPERTIES)) {

			options.put(UML2EcoreConverter.OPTION__SUBSETTING_PROPERTIES,
				OPTION__IGNORE);
		}

		if (!options.containsKey(UML2EcoreConverter.OPTION__UNION_PROPERTIES)) {
			options.put(UML2EcoreConverter.OPTION__UNION_PROPERTIES,
				OPTION__IGNORE);
		}

		if (!options.containsKey(UML2EcoreConverter.OPTION__DERIVED_FEATURES)) {
			options.put(UML2EcoreConverter.OPTION__DERIVED_FEATURES,
				OPTION__IGNORE);
		}

		if (!options
			.containsKey(UML2EcoreConverter.OPTION__DUPLICATE_OPERATIONS)) {

			options.put(UML2EcoreConverter.OPTION__DUPLICATE_OPERATIONS,
				OPTION__IGNORE);
		}

		if (!options
			.containsKey(UML2EcoreConverter.OPTION__DUPLICATE_OPERATION_INHERITANCE)) {

			options.put(
				UML2EcoreConverter.OPTION__DUPLICATE_OPERATION_INHERITANCE,
				OPTION__IGNORE);
		}

		if (!options.containsKey(UML2EcoreConverter.OPTION__DUPLICATE_FEATURES)) {
			options.put(UML2EcoreConverter.OPTION__DUPLICATE_FEATURES,
				OPTION__IGNORE);
		}

		if (!options
			.containsKey(UML2EcoreConverter.OPTION__DUPLICATE_FEATURE_INHERITANCE)) {

			options.put(
				UML2EcoreConverter.OPTION__DUPLICATE_FEATURE_INHERITANCE,
				OPTION__IGNORE);
		}

		if (!options.containsKey(UML2EcoreConverter.OPTION__SUPER_CLASS_ORDER)) {
			options.put(UML2EcoreConverter.OPTION__SUPER_CLASS_ORDER,
				OPTION__IGNORE);
		}

		if (!options.containsKey(UML2EcoreConverter.OPTION__ANNOTATION_DETAILS)) {
			options.put(UML2EcoreConverter.OPTION__ANNOTATION_DETAILS,
				OPTION__IGNORE);
		}

		return convertToEcore(profile, options, null, null);
	}

	/**
	 * Converts the specified profile (and its contents) to Ecore using the
	 * specified options, reporting problems to the specified diagnostics,
	 * within the specified context. If a supported option is not specified, it
	 * will be defaulted to <code>OPTION__REPORT</code>.
	 * 
	 * @param profile
	 *            The profile to convert.
	 * @param options
	 *            The options to use.
	 * @param diagnostics
	 *            The chain of diagnostics to which problems are to be appended.
	 * @param context
	 *            The cache of context-specific information.
	 * @return An Ecore representation of the profile.
	 */
	public static Collection<EPackage> convertToEcore(Profile profile,
			Map<String, String> options, DiagnosticChain diagnostics,
			Map<Object, Object> context) {

		if (options == null) {
			options = new HashMap<String, String>();
		}

		if (!options
			.containsKey(UML2EcoreConverter.OPTION__ECORE_TAGGED_VALUES)) {

			options.put(UML2EcoreConverter.OPTION__ECORE_TAGGED_VALUES,
				OPTION__REPORT);
		}

		if (!options
			.containsKey(UML2EcoreConverter.OPTION__REDEFINING_OPERATIONS)) {

			options.put(UML2EcoreConverter.OPTION__REDEFINING_OPERATIONS,
				OPTION__REPORT);
		}

		if (!options
			.containsKey(UML2EcoreConverter.OPTION__REDEFINING_PROPERTIES)) {

			options.put(UML2EcoreConverter.OPTION__REDEFINING_PROPERTIES,
				OPTION__REPORT);
		}

		if (!options
			.containsKey(UML2EcoreConverter.OPTION__SUBSETTING_PROPERTIES)) {

			options.put(UML2EcoreConverter.OPTION__SUBSETTING_PROPERTIES,
				OPTION__REPORT);
		}

		if (!options.containsKey(UML2EcoreConverter.OPTION__UNION_PROPERTIES)) {
			options.put(UML2EcoreConverter.OPTION__UNION_PROPERTIES,
				OPTION__REPORT);
		}

		if (!options.containsKey(UML2EcoreConverter.OPTION__DERIVED_FEATURES)) {
			options.put(UML2EcoreConverter.OPTION__DERIVED_FEATURES,
				OPTION__REPORT);
		}

		if (!options
			.containsKey(UML2EcoreConverter.OPTION__DUPLICATE_OPERATIONS)) {

			options.put(UML2EcoreConverter.OPTION__DUPLICATE_OPERATIONS,
				OPTION__REPORT);
		}

		if (!options
			.containsKey(UML2EcoreConverter.OPTION__DUPLICATE_OPERATION_INHERITANCE)) {

			options.put(
				UML2EcoreConverter.OPTION__DUPLICATE_OPERATION_INHERITANCE,
				OPTION__REPORT);
		}

		if (!options.containsKey(UML2EcoreConverter.OPTION__DUPLICATE_FEATURES)) {
			options.put(UML2EcoreConverter.OPTION__DUPLICATE_FEATURES,
				OPTION__REPORT);
		}

		if (!options
			.containsKey(UML2EcoreConverter.OPTION__DUPLICATE_FEATURE_INHERITANCE)) {

			options.put(
				UML2EcoreConverter.OPTION__DUPLICATE_FEATURE_INHERITANCE,
				OPTION__REPORT);
		}

		if (!options.containsKey(UML2EcoreConverter.OPTION__SUPER_CLASS_ORDER)) {
			options.put(UML2EcoreConverter.OPTION__SUPER_CLASS_ORDER,
				OPTION__REPORT);
		}

		if (!options.containsKey(UML2EcoreConverter.OPTION__ANNOTATION_DETAILS)) {
			options.put(UML2EcoreConverter.OPTION__ANNOTATION_DETAILS,
				OPTION__REPORT);
		}

		@SuppressWarnings("unchecked")
		Collection<EPackage> ePackages = (Collection<EPackage>) new Profile2EPackageConverter()
			.convert(Collections.singleton(profile), options, null, null);

		for (TreeIterator<EObject> allContents = EcoreUtil
			.getAllContents(ePackages); allContents.hasNext();) {

			new EcoreSwitch<Object>() {

				@Override
				public Object caseEAttribute(EAttribute eAttribute) {

					try {
						eAttribute.getDefaultValue();
					} catch (Exception e) {
						eAttribute.setDefaultValueLiteral(null);
					}

					return eAttribute;
				}

				@Override
				public Object caseEDataType(EDataType eDataType) {

					try {
						eDataType.getInstanceClass();
					} catch (Exception e) {
						eDataType
							.setInstanceClassName(EcorePackage.Literals.ESTRING
								.getInstanceClassName());
					}

					return eDataType;
				}

			}.doSwitch(allContents.next());
		}

		return ePackages;
	}

	/**
	 * Converts the specified Ecore package (and its contents) to UML using the
	 * specified options.
	 * 
	 * @param ePackage
	 *            The Ecore package to convert.
	 * @param options
	 *            The options to use.
	 * @return A UML representation of the Ecore package.
	 */
	public static Collection<org.eclipse.uml2.uml.Package> convertFromEcore(
			EPackage ePackage, Map<String, String> options) {

		if (options == null) {
			options = new HashMap<String, String>();
		}

		return convertFromEcore(ePackage, options, null, null);
	}

	/**
	 * Converts the specified Ecore package (and its contents) to UML using the
	 * specified options, reporting problems to the specified diagnostics,
	 * within the specified context.
	 * 
	 * @param ePackage
	 *            The Ecore package to convert.
	 * @param options
	 *            The options to use.
	 * @param diagnostics
	 *            The chain of diagnostics to which problems are to be appended.
	 * @param context
	 *            The cache of context-specific information.
	 * @return A UML representation of the Ecore package.
	 */
	public static Collection<org.eclipse.uml2.uml.Package> convertFromEcore(
			EPackage ePackage, Map<String, String> options,
			DiagnosticChain diagnostics, Map<Object, Object> context) {

		if (options == null) {
			options = new HashMap<String, String>();
		}

		@SuppressWarnings("unchecked")
		Collection<org.eclipse.uml2.uml.Package> packages = (Collection<org.eclipse.uml2.uml.Package>) new Ecore2UMLConverter()
			.convert(Collections.singleton(ePackage), options, diagnostics,
				context);
		return packages;
	}

}
