Bug 545578: [Profile Definition] Reapplying a profile doesn't work well
with Optional Enums
https://bugs.eclipse.org/bugs/show_bug.cgi?id=545578

Change-Id: I6ba15bf2089d5c968c33366cfa7faa99426d171b
Signed-off-by: Camille Letavernier <cletavernier@eclipsesource.com>
diff --git a/plugins/org.eclipse.uml2.uml/src/org/eclipse/uml2/uml/internal/operations/PackageOperations.java b/plugins/org.eclipse.uml2.uml/src/org/eclipse/uml2/uml/internal/operations/PackageOperations.java
index 8f6d817..dead399 100644
--- a/plugins/org.eclipse.uml2.uml/src/org/eclipse/uml2/uml/internal/operations/PackageOperations.java
+++ b/plugins/org.eclipse.uml2.uml/src/org/eclipse/uml2/uml/internal/operations/PackageOperations.java
@@ -13,7 +13,7 @@
  *   Christian W. Damus (CEA) - 300957, 431998
  *   Christian W. Damus - 444588
  *   Alain Le Guennec (Esterel Technologies SAS) - 497153
- *
+ *   Camille Letavernier (EclipseSource) - 545578
  */
 package org.eclipse.uml2.uml.internal.operations;
 
@@ -239,8 +239,7 @@
 			if (!eAttribute.isUnsettable() || eObject.eIsSet(eAttribute)) {
 
 				try {
-					if (eAttribute.getEType().eClass()
-						.getClassifierID() == EcorePackage.EENUM) {
+					if (UMLUtil.isEnumType(eAttribute.getEType())) {
 						copyEEnumAttribute(eAttribute, eObject, copyEObject);
 					} else {
 						copyEDataTypeAttribute(eAttribute, eObject,
@@ -305,8 +304,8 @@
 			EAttribute targetEAttribute = (EAttribute) getTarget(eAttribute);
 
 			if (targetEAttribute != null && targetEAttribute.isChangeable()) {
-				EEnum targetEEnum = (EEnum) targetEAttribute
-					.getEAttributeType();
+				EEnum targetEEnum = UMLUtil.getEnumType(targetEAttribute
+					.getEAttributeType());
 
 				if (targetEAttribute.isMany()) {
 					@SuppressWarnings("unchecked")
diff --git a/plugins/org.eclipse.uml2.uml/src/org/eclipse/uml2/uml/util/UMLUtil.java b/plugins/org.eclipse.uml2.uml/src/org/eclipse/uml2/uml/util/UMLUtil.java
index 3dd952a..667f121 100644
--- a/plugins/org.eclipse.uml2.uml/src/org/eclipse/uml2/uml/util/UMLUtil.java
+++ b/plugins/org.eclipse.uml2.uml/src/org/eclipse/uml2/uml/util/UMLUtil.java
@@ -16,7 +16,7 @@
  *   E.D.Willink - 420338, 512439
  *   Christian W. Damus - 444588, 497359, 501740
  *   Camille Letavernier - 528925, 529564
- *   Camille Letavernier (EclipseSource) - 544487
+ *   Camille Letavernier (EclipseSource) - 544487, 545578
  */
 package org.eclipse.uml2.uml.util;
 
@@ -13874,6 +13874,56 @@
 
 		return false;
 	}
+	
+	/**
+	 * Test if the given {@link EClassifier} represents an Enum Type.
+	 * 
+	 * @param classifier
+	 * 		The Classifier
+	 * @return
+	 * 		<code>true</code> if this {@link EClassifier} is an Enum Type, <code>false</code> otherwise
+	 * 
+	 * @see ExtendedMetaData#getBaseType
+	 * 
+	 * @since 5.6
+	 */
+	public static boolean isEnumType(EClassifier classifier) {
+		if (classifier instanceof EEnum) {
+			return true;
+		}
+
+		if (classifier instanceof EDataType) {
+			return getEnumType(classifier) != null;
+		}
+
+		return false;
+	}
+
+	/**
+	 * If the given {@link EClassifier} represents an Enum Type, return
+	 * the corresponding {@link EEnum}.
+	 * 
+	 * @param classifier
+	 * 		The Classifier
+	 * @return
+	 * 		The {@link EEnum} represented by this {@link EClassifier}, or <code>null</code>
+	 * 		if this classifier doesn't represent an {@link EEnum}
+	 * 
+	 * @see ExtendedMetaData#getBaseType
+	 * 
+	 * @since 5.6
+	 */
+	public static EEnum getEnumType(EClassifier eType) {
+		if (eType instanceof EEnum) { // Standard Enums
+			return (EEnum) eType;
+		} else if (eType instanceof EDataType) { // Optional Enums
+			EDataType implType = (EDataType) eType;
+			EDataType baseType = ExtendedMetaData.INSTANCE.getBaseType(implType);
+			return baseType instanceof EEnum ? (EEnum) baseType : null;
+		}
+
+		return null;
+	}
 
 	/**
 	 * Retrieves an OCL compliant version of the specified UML body expression.