https://bugs.eclipse.org/bugs/show_bug.cgi?id=77406
diff --git a/deprecated/plugins/org.eclipse.uml2.resources/profiles/Basic.profile.properties b/deprecated/plugins/org.eclipse.uml2.resources/profiles/Basic.profile.properties
index 569b617..1f7ba89 100644
--- a/deprecated/plugins/org.eclipse.uml2.resources/profiles/Basic.profile.properties
+++ b/deprecated/plugins/org.eclipse.uml2.resources/profiles/Basic.profile.properties
@@ -18,3 +18,24 @@
 Basic__Trace = trace
 Basic__Type = type
 Basic__Utility = utility
+
+_label_Basic__Auxiliary = Auxiliary
+_label_Basic__BuildComponent = Build Component
+_label_Basic__Call = Call
+_label_Basic__Create = Create
+_label_Basic__Derive = Derive
+_label_Basic__Destroy = Destroy
+_label_Basic__Focus = Focus
+_label_Basic__Framework = Framework
+_label_Basic__Implement = Implement
+_label_Basic__ImplementationClass = Implementation Class
+_label_Basic__Instantiate = Instantiate
+_label_Basic__Metaclass = Metaclass
+_label_Basic__ModelLibrary = Model Library
+_label_Basic__Refine = Refine
+_label_Basic__Responsibility = Responsibility
+_label_Basic__Script = Script
+_label_Basic__Send = Send
+_label_Basic__Trace = Trace
+_label_Basic__Type = Type
+_label_Basic__Utility = Utility
diff --git a/deprecated/plugins/org.eclipse.uml2.resources/profiles/Complete.profile.properties b/deprecated/plugins/org.eclipse.uml2.resources/profiles/Complete.profile.properties
index 8ed7d95..959333e 100644
--- a/deprecated/plugins/org.eclipse.uml2.resources/profiles/Complete.profile.properties
+++ b/deprecated/plugins/org.eclipse.uml2.resources/profiles/Complete.profile.properties
@@ -1,2 +1,5 @@
 Complete__Metamodel = metamodel
 Complete__SystemModel = systemModel
+
+_label_Complete__Metamodel = Metamodel
+_label_Complete__SystemModel = System Model
diff --git a/deprecated/plugins/org.eclipse.uml2.resources/profiles/Ecore.profile.properties b/deprecated/plugins/org.eclipse.uml2.resources/profiles/Ecore.profile.properties
index 3ee5931..68702fb 100644
--- a/deprecated/plugins/org.eclipse.uml2.resources/profiles/Ecore.profile.properties
+++ b/deprecated/plugins/org.eclipse.uml2.resources/profiles/Ecore.profile.properties
@@ -2,8 +2,79 @@
 Ecore__EClass = eClass
 Ecore__EDataType = eDataType
 Ecore__EEnum = eEnum
+Ecore__EEnumLiteral = eEnumLiteral
 Ecore__EOperation = eOperation
 Ecore__EPackage = ePackage
 Ecore__EParameter = eParameter
 Ecore__EReference = eReference
-Ecore__EEnumLiteral = eEnumLiteral
+
+
+_label_Ecore__ContentKind = Content Kind
+_label_Ecore__ContentKind__ElementOnly = Element Only
+_label_Ecore__ContentKind__Empty = Empty
+_label_Ecore__ContentKind__Mixed = Mixed
+_label_Ecore__ContentKind__Simple = Simple
+_label_Ecore__ContentKind__Unspecified = Unspecified
+
+_label_Ecore__FeatureKind = Feature Kind
+_label_Ecore__FeatureKind__Attribute = Attribute
+_label_Ecore__FeatureKind__Element = Element
+_label_Ecore__FeatureKind__Simple = Simple
+_label_Ecore__FeatureKind__Unspecified = Unspecified
+
+_label_Ecore__VisibilityKind = Visibility Kind
+_label_Ecore__VisibilityKind__None = None
+_label_Ecore__VisibilityKind__ReadOnly = Read Only
+_label_Ecore__VisibilityKind__ReadOnlyUnsettable = Read Only Unsettable
+_label_Ecore__VisibilityKind__ReadWrite = Read Write
+_label_Ecore__VisibilityKind__ReadWriteUnsettable = Read Write Unsettable
+_label_Ecore__VisibilityKind__Unspecified = Unspecified
+
+_label_Ecore__EAttribute = Ecore Attribute
+_label_Ecore__EAttribute__attributeName = Attribute Name
+_label_Ecore__EAttribute__isID = Is ID
+
+_label_Ecore__EClass = Ecore Class
+_label_Ecore__EClass__className = Class Name
+_label_Ecore__EClass__xmlContentKind = XML Content Kind
+
+_label_Ecore__EClassifier = Ecore Classifier
+_label_Ecore__EClassifier__instanceClassName = Instance Class Name
+
+_label_Ecore__EDataType = Ecore Data Type
+_label_Ecore__EDataType__dataTypeName = Data Type Name
+
+_label_Ecore__EEnum = Ecore Enum
+_label_Ecore__EEnum__enumName = Enum Name
+
+_label_Ecore__EEnumLiteral = Ecore Enum Literal
+_label_Ecore__EEnumLiteral__enumLiteralName = Enum Literal Name
+
+_label_Ecore__ENamedElement = Ecore Named Element
+_label_Ecore__ENamedElement__xmlName = XML Name
+
+_label_Ecore__EOperation = Ecore Operation
+_label_Ecore__EOperation__operationName = Operation Name
+
+_label_Ecore__EPackage = Ecore Package
+_label_Ecore__EPackage__basePackage = Base Package
+_label_Ecore__EPackage__nsPrefix = Namespace Prefix
+_label_Ecore__EPackage__nsURI = Namespace URI
+_label_Ecore__EPackage__packageName = Package Name
+_label_Ecore__EPackage__prefix = Prefix
+
+_label_Ecore__EParameter = Ecore Parameter
+_label_Ecore__EParameter__parameterName = Parameter Name
+
+_label_Ecore__EReference = Ecore Reference
+_label_Ecore__EReference__referenceName = Reference Name
+_label_Ecore__EReference__isResolveProxies = Is Resolve Proxies
+
+_label_Ecore__EStructuralFeature = Ecore Structural Feature
+_label_Ecore__EStructuralFeature__isTransient = Is Transient
+_label_Ecore__EStructuralFeature__isUnsettable = Is Unsettable
+_label_Ecore__EStructuralFeature__isVolatile = Is Volatile
+_label_Ecore__EStructuralFeature__visibility = Visibility
+_label_Ecore__EStructuralFeature__xmlFeatureKind = XML Feature Kind
+_label_Ecore__EStructuralFeature__xmlNamespace = XML Namespace
+
diff --git a/deprecated/plugins/org.eclipse.uml2.resources/profiles/Intermediate.profile.properties b/deprecated/plugins/org.eclipse.uml2.resources/profiles/Intermediate.profile.properties
index 773e3a2..36e898b 100644
--- a/deprecated/plugins/org.eclipse.uml2.resources/profiles/Intermediate.profile.properties
+++ b/deprecated/plugins/org.eclipse.uml2.resources/profiles/Intermediate.profile.properties
@@ -9,3 +9,15 @@
 Intermediate__Source = source
 Intermediate__Specification = specification
 Intermediate__Subsystem = subsystem
+
+_label_Intermediate__Document = Document
+_label_Intermediate__Entity = Entity
+_label_Intermediate__Executable = Executable
+_label_Intermediate__File = File
+_label_Intermediate__Library = Library
+_label_Intermediate__Process = Process
+_label_Intermediate__Realization = Realization
+_label_Intermediate__Service = Service
+_label_Intermediate__Source = Source
+_label_Intermediate__Specification = Specification
+_label_Intermediate__Subsystem = Subsystem
diff --git a/deprecated/plugins/org.eclipse.uml2/src/org/eclipse/uml2/NamedElement.java b/deprecated/plugins/org.eclipse.uml2/src/org/eclipse/uml2/NamedElement.java
index 622d8b8..d1fe9b3 100644
--- a/deprecated/plugins/org.eclipse.uml2/src/org/eclipse/uml2/NamedElement.java
+++ b/deprecated/plugins/org.eclipse.uml2/src/org/eclipse/uml2/NamedElement.java
@@ -8,12 +8,11 @@
  * Contributors:
  *   IBM - Initial API and implementation
  *
- * $Id: NamedElement.java,v 1.6 2004/06/06 01:35:03 khussey Exp $
+ * $Id: NamedElement.java,v 1.7 2004/12/03 22:32:52 khussey Exp $
  */
 package org.eclipse.uml2;
 
 import java.util.List;
-
 import java.util.Map;
 
 import org.eclipse.emf.common.util.DiagnosticChain;
@@ -344,6 +343,13 @@
 
 	public static final String SEPARATOR = "::"; //$NON-NLS-1$
 
+	/**
+	 * Retrieves a (localized) label for this named element.
+	 * 
+	 * @return A label for this named element.
+	 */
+	public String getLabel();
+
 	// <!-- end-custom-operations -->
 
 } // NamedElement
diff --git a/deprecated/plugins/org.eclipse.uml2/src/org/eclipse/uml2/impl/NamedElementImpl.java b/deprecated/plugins/org.eclipse.uml2/src/org/eclipse/uml2/impl/NamedElementImpl.java
index cec7eef..085a8ef 100644
--- a/deprecated/plugins/org.eclipse.uml2/src/org/eclipse/uml2/impl/NamedElementImpl.java
+++ b/deprecated/plugins/org.eclipse.uml2/src/org/eclipse/uml2/impl/NamedElementImpl.java
@@ -8,7 +8,7 @@
  * Contributors:
  *   IBM - Initial API and implementation
  *
- * $Id: NamedElementImpl.java,v 1.10 2004/06/18 04:34:32 khussey Exp $
+ * $Id: NamedElementImpl.java,v 1.11 2004/12/03 22:32:52 khussey Exp $
  */
 package org.eclipse.uml2.impl;
 
@@ -38,6 +38,7 @@
 import org.eclipse.uml2.TemplateSignature;
 import org.eclipse.uml2.UML2Package;
 import org.eclipse.uml2.VisibilityKind;
+import org.eclipse.uml2.internal.operation.NamedElementOperations;
 
 /**
  * <!-- begin-user-doc -->
@@ -634,4 +635,17 @@
 		return result.toString();
 	}
 
+	// <!-- begin-custom-operations -->
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.uml2.NamedElement#getLabel()
+	 */
+	public String getLabel() {
+		return NamedElementOperations.getLabel(this);
+	}
+
+	// <!-- end-custom-operations -->
+
 } //NamedElementImpl
diff --git a/deprecated/plugins/org.eclipse.uml2/src/org/eclipse/uml2/internal/operation/NamedElementOperations.java b/deprecated/plugins/org.eclipse.uml2/src/org/eclipse/uml2/internal/operation/NamedElementOperations.java
index 19e2a8c..1b3e0c8 100644
--- a/deprecated/plugins/org.eclipse.uml2/src/org/eclipse/uml2/internal/operation/NamedElementOperations.java
+++ b/deprecated/plugins/org.eclipse.uml2/src/org/eclipse/uml2/internal/operation/NamedElementOperations.java
@@ -8,7 +8,7 @@
  * Contributors:
  *   IBM - Initial API and implementation
  *
- * $Id: NamedElementOperations.java,v 1.6 2004/05/11 15:24:01 khussey Exp $
+ * $Id: NamedElementOperations.java,v 1.7 2004/12/03 22:32:52 khussey Exp $
  */
 package org.eclipse.uml2.internal.operation;
 
@@ -22,16 +22,17 @@
 import org.eclipse.emf.common.util.DiagnosticChain;
 import org.eclipse.uml2.NamedElement;
 import org.eclipse.uml2.Namespace;
-import org.eclipse.uml2.util.UML2Validator;
 import org.eclipse.uml2.UML2Package;
 import org.eclipse.uml2.UML2Plugin;
-
+import org.eclipse.uml2.util.UML2Validator;
 
 /**
  * A static utility class that provides operations related to named elements.
  */
 public final class NamedElementOperations
-	extends UML2Operations {
+		extends UML2Operations {
+
+	protected static final String LABEL_KEY_PREFIX = "_label_"; //$NON-NLS-1$
 
 	/**
 	 * Constructs a new Named Element Operations. This constructor should never
@@ -101,7 +102,7 @@
 	/**
 	 * If there is no name, or one of the containing namespaces has no name,
 	 * there is no qualified name.
-	 *  
+	 * 
 	 */
 	public static boolean validateNoName(NamedElement namedElement,
 			DiagnosticChain diagnostics, Map context) {
@@ -123,12 +124,11 @@
 
 		if (!result && null != diagnostics) {
 			diagnostics.add(new BasicDiagnostic(Diagnostic.ERROR,
-					UML2Validator.DIAGNOSTIC_SOURCE,
-					UML2Validator.NAMED_ELEMENT__NO_NAME,
-					UML2Plugin.INSTANCE.getString(
-						"_UI_NamedElement_NoName_diagnostic", //$NON-NLS-1$
+				UML2Validator.DIAGNOSTIC_SOURCE,
+				UML2Validator.NAMED_ELEMENT__NO_NAME, UML2Plugin.INSTANCE
+					.getString("_UI_NamedElement_NoName_diagnostic", //$NON-NLS-1$
 						getMessageSubstitutions(context, namedElement)),
-					new Object[] {namedElement}));
+				new Object[]{namedElement}));
 		}
 
 		return result;
@@ -138,7 +138,7 @@
 	 * When there is a name, and all of the containing namespaces have a name,
 	 * the qualified name is constructed from the names of the containing
 	 * namespaces.
-	 *  
+	 * 
 	 */
 	public static boolean validateQualifiedName(NamedElement namedElement,
 			DiagnosticChain diagnostics, Map context) {
@@ -165,17 +165,13 @@
 				result = false;
 
 				if (null != diagnostics) {
-					diagnostics
-						.add(new BasicDiagnostic(
-								Diagnostic.ERROR,
-								UML2Validator.DIAGNOSTIC_SOURCE,
-								UML2Validator.NAMED_ELEMENT__NO_NAME,
-								UML2Plugin.INSTANCE
-									.getString(
-										"_UI_NamedElement_QualifiedName_diagnostic", //$NON-NLS-1$
-										getMessageSubstitutions(context,
-											namedElement)),
-								new Object[] {namedElement}));
+					diagnostics.add(new BasicDiagnostic(Diagnostic.ERROR,
+						UML2Validator.DIAGNOSTIC_SOURCE,
+						UML2Validator.NAMED_ELEMENT__NO_NAME,
+						UML2Plugin.INSTANCE.getString(
+							"_UI_NamedElement_QualifiedName_diagnostic", //$NON-NLS-1$
+							getMessageSubstitutions(context, namedElement)),
+						new Object[]{namedElement}));
 				}
 			}
 		}
@@ -186,7 +182,7 @@
 	/**
 	 * If a named element is not owned by a namespace, it does not have a
 	 * visibility.
-	 *  
+	 * 
 	 */
 	public static boolean validateVisibilityNeedsOwnership(
 			NamedElement namedElement, DiagnosticChain diagnostics, Map context) {
@@ -199,21 +195,36 @@
 			result = false;
 
 			if (null != diagnostics) {
-				diagnostics
-					.add(new BasicDiagnostic(
-							Diagnostic.WARNING,
-							UML2Validator.DIAGNOSTIC_SOURCE,
-							UML2Validator.NAMED_ELEMENT__VISIBILITY_NEEDS_OWNERSHIP,
-							UML2Plugin.INSTANCE
-								.getString(
-									"_UI_NamedElement_VisibilityNeedsOwnership_diagnostic", //$NON-NLS-1$
-									getMessageSubstitutions(context,
-										namedElement)),
-							new Object[] {namedElement}));
+				diagnostics.add(new BasicDiagnostic(Diagnostic.WARNING,
+					UML2Validator.DIAGNOSTIC_SOURCE,
+					UML2Validator.NAMED_ELEMENT__VISIBILITY_NEEDS_OWNERSHIP,
+					UML2Plugin.INSTANCE.getString(
+						"_UI_NamedElement_VisibilityNeedsOwnership_diagnostic", //$NON-NLS-1$
+						getMessageSubstitutions(context, namedElement)),
+					new Object[]{namedElement}));
 			}
 		}
 
 		return result;
 	}
 
+	/**
+	 * Retrieves a (localized) label for the specified named element.
+	 * 
+	 * @param namedElement
+	 *            The named element for which to retrieve a label.
+	 * @return A label for the named element.
+	 */
+	public static String getLabel(NamedElement namedElement) {
+		String label = EMPTY_STRING;
+
+		if (null != namedElement) {
+			label = getString(namedElement, LABEL_KEY_PREFIX
+				+ getValidIdentifier(namedElement.getQualifiedName().replace(
+					':', '_')), namedElement.getName());
+		}
+
+		return label;
+	}
+
 }
\ No newline at end of file
diff --git a/deprecated/plugins/org.eclipse.uml2/src/org/eclipse/uml2/internal/operation/ProfileOperations.java b/deprecated/plugins/org.eclipse.uml2/src/org/eclipse/uml2/internal/operation/ProfileOperations.java
index 1f97c08..8cdc5d7 100644
--- a/deprecated/plugins/org.eclipse.uml2/src/org/eclipse/uml2/internal/operation/ProfileOperations.java
+++ b/deprecated/plugins/org.eclipse.uml2/src/org/eclipse/uml2/internal/operation/ProfileOperations.java
@@ -8,27 +8,19 @@
  * Contributors:
  *   IBM - Initial API and implementation
  *
- * $Id: ProfileOperations.java,v 1.14 2004/12/02 21:21:18 khussey Exp $
+ * $Id: ProfileOperations.java,v 1.15 2004/12/03 22:32:52 khussey Exp $
  */
 package org.eclipse.uml2.internal.operation;
 
-import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.PropertyResourceBundle;
-import java.util.ResourceBundle;
 import java.util.Set;
 
 import org.eclipse.emf.common.util.AbstractTreeIterator;
 import org.eclipse.emf.common.util.EList;
 import org.eclipse.emf.common.util.TreeIterator;
-import org.eclipse.emf.common.util.URI;
 import org.eclipse.emf.ecore.EAnnotation;
 import org.eclipse.emf.ecore.EAttribute;
 import org.eclipse.emf.ecore.EClass;
@@ -43,10 +35,6 @@
 import org.eclipse.emf.ecore.EStructuralFeature;
 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.resource.URIConverter;
-import org.eclipse.emf.ecore.resource.impl.URIConverterImpl;
 import org.eclipse.emf.ecore.util.EcoreUtil;
 import org.eclipse.uml2.Classifier;
 import org.eclipse.uml2.DataType;
@@ -96,23 +84,6 @@
 	public static final String ANNOTATION_DETAILS_KEY__VERSION = "version"; //$NON-NLS-1$
 
 	/**
-	 * The default URI converter for resource bundle look-ups.
-	 */
-	private static final URIConverter DEFAULT_URI_CONVERTER = new URIConverterImpl();
-
-	/**
-	 * A cache of locales per profile.
-	 */
-	private static final Map PROFILE_LOCALES = Collections
-		.synchronizedMap(new HashMap());
-
-	/**
-	 * A cache of resource bundles per profile.
-	 */
-	private static final Map PROFILE_RESOURCE_BUNDLES = Collections
-		.synchronizedMap(new HashMap());
-
-	/**
 	 * Constructs a new Profile Operations. This constructor should never be
 	 * called because this is a static utility class.
 	 */
@@ -1312,67 +1283,6 @@
 	}
 
 	/**
-	 * Retrieves the (cached) resource bundle for the specified profile in the
-	 * specified locale.
-	 * 
-	 * @param profile
-	 *            The profile for which to retrieve the resource bundle.
-	 * @param locale
-	 *            The locale in which to retrieve the resource bundle.
-	 * @return The resource bundle for the profile in the locale.
-	 */
-	protected static ResourceBundle getResourceBundle(Profile profile,
-			Locale locale) {
-
-		if (!PROFILE_RESOURCE_BUNDLES.containsKey(profile)
-			|| !locale.equals(PROFILE_LOCALES.get(profile))) {
-
-			ResourceBundle resourceBundle = null;
-			Resource resource = profile.eResource();
-
-			if (null != resource) {
-				ResourceSet resourceSet = resource.getResourceSet();
-				URIConverter uriConverter = null == resourceSet
-					? DEFAULT_URI_CONVERTER
-					: resourceSet.getURIConverter();
-
-				for (Iterator resourceBundleURIs = getResourceBundleURIs(
-					resource.getURI(), locale).iterator(); resourceBundleURIs
-					.hasNext();) {
-
-					try {
-						resourceBundle = new PropertyResourceBundle(
-							uriConverter
-								.createInputStream((URI) resourceBundleURIs
-									.next()));
-						locale = resourceBundle.getLocale();
-						break;
-					} catch (IOException ioe) {
-						// ignore
-					}
-				}
-			}
-
-			PROFILE_LOCALES.put(profile, locale);
-			PROFILE_RESOURCE_BUNDLES.put(profile, resourceBundle);
-		}
-
-		return (ResourceBundle) PROFILE_RESOURCE_BUNDLES.get(profile);
-	}
-
-	/**
-	 * Retrieves the (cached) resource bundle for the specified profile in the
-	 * default locale.
-	 * 
-	 * @param profile
-	 *            The profile for which to retrieve the resource bundle.
-	 * @return The resource bundle for the profile in the default locale.
-	 */
-	protected static ResourceBundle getResourceBundle(Profile profile) {
-		return getResourceBundle(profile, Locale.getDefault());
-	}
-
-	/**
 	 * Creates and returns an instance of (the Ecore representation of) the
 	 * specified classifier defined in the specified profile.
 	 * 
diff --git a/deprecated/plugins/org.eclipse.uml2/src/org/eclipse/uml2/internal/operation/StereotypeOperations.java b/deprecated/plugins/org.eclipse.uml2/src/org/eclipse/uml2/internal/operation/StereotypeOperations.java
index 29c8e12..eb22304 100644
--- a/deprecated/plugins/org.eclipse.uml2/src/org/eclipse/uml2/internal/operation/StereotypeOperations.java
+++ b/deprecated/plugins/org.eclipse.uml2/src/org/eclipse/uml2/internal/operation/StereotypeOperations.java
@@ -8,7 +8,7 @@
  * Contributors:
  *   IBM - Initial API and implementation
  *
- * $Id: StereotypeOperations.java,v 1.14 2004/12/02 16:14:25 khussey Exp $
+ * $Id: StereotypeOperations.java,v 1.15 2004/12/03 22:32:52 khussey Exp $
  */
 package org.eclipse.uml2.internal.operation;
 
@@ -16,8 +16,6 @@
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
-import java.util.MissingResourceException;
-import java.util.ResourceBundle;
 import java.util.Set;
 
 import org.eclipse.emf.ecore.EAnnotation;
@@ -996,18 +994,8 @@
 		String keyword = EMPTY_STRING;
 
 		if (null != stereotype) {
-
-			try {
-				ResourceBundle resourceBundle = ProfileOperations
-					.getResourceBundle(stereotype.getProfile());
-
-				if (null != resourceBundle) {
-					keyword = resourceBundle.getString(stereotype
-						.getQualifiedName().replace(':', '_'));
-				}
-			} catch (MissingResourceException mre) {
-				// ignore
-			}
+			keyword = getString(stereotype, getValidIdentifier(stereotype
+				.getQualifiedName().replace(':', '_')), EMPTY_STRING);
 
 			if (isEmpty(keyword)) {
 				String identifier = getValidIdentifier(stereotype.getName());
diff --git a/deprecated/plugins/org.eclipse.uml2/src/org/eclipse/uml2/internal/operation/UML2Operations.java b/deprecated/plugins/org.eclipse.uml2/src/org/eclipse/uml2/internal/operation/UML2Operations.java
index 8d4bc64..c720f97 100644
--- a/deprecated/plugins/org.eclipse.uml2/src/org/eclipse/uml2/internal/operation/UML2Operations.java
+++ b/deprecated/plugins/org.eclipse.uml2/src/org/eclipse/uml2/internal/operation/UML2Operations.java
@@ -8,18 +8,25 @@
  * Contributors:
  *   IBM - Initial API and implementation
  *
- * $Id: UML2Operations.java,v 1.10 2004/11/02 15:30:10 khussey Exp $
+ * $Id: UML2Operations.java,v 1.11 2004/12/03 22:32:52 khussey Exp $
  */
 package org.eclipse.uml2.internal.operation;
 
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.ListIterator;
 import java.util.Locale;
 import java.util.Map;
+import java.util.MissingResourceException;
+import java.util.PropertyResourceBundle;
+import java.util.ResourceBundle;
 
+import org.eclipse.core.runtime.Platform;
 import org.eclipse.emf.common.util.EList;
 import org.eclipse.emf.common.util.URI;
 import org.eclipse.emf.ecore.EAnnotation;
@@ -30,8 +37,11 @@
 import org.eclipse.emf.ecore.EValidator;
 import org.eclipse.emf.ecore.EcoreFactory;
 import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.plugin.EcorePlugin;
 import org.eclipse.emf.ecore.resource.Resource;
 import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.URIConverter;
+import org.eclipse.emf.ecore.resource.impl.URIConverterImpl;
 import org.eclipse.emf.ecore.util.EContentsEList;
 import org.eclipse.emf.ecore.util.ECrossReferenceEList;
 import org.eclipse.emf.ecore.util.EcoreUtil;
@@ -45,6 +55,7 @@
 import org.eclipse.uml2.StructuredClassifier;
 import org.eclipse.uml2.Type;
 import org.eclipse.uml2.util.UML2Switch;
+import org.osgi.framework.Bundle;
 
 /**
  * The base class for all UML2 operation utility classes.
@@ -52,12 +63,12 @@
 class UML2Operations {
 
 	protected static class FilteredECrossReferenceEList
-		extends ECrossReferenceEList {
+			extends ECrossReferenceEList {
 
 		private final FilteredUsageCrossReferencer.Filter filter;
 
 		protected static class FilteredFeatureIteratorImpl
-			extends ECrossReferenceEList.FeatureIteratorImpl {
+				extends ECrossReferenceEList.FeatureIteratorImpl {
 
 			private final FilteredUsageCrossReferencer.Filter filter;
 
@@ -82,7 +93,7 @@
 		}
 
 		protected static class FilteredResolvingFeatureIteratorImpl
-			extends FilteredFeatureIteratorImpl {
+				extends FilteredFeatureIteratorImpl {
 
 			public FilteredResolvingFeatureIteratorImpl(EObject eObject,
 					EStructuralFeature[] eStructuralFeatures,
@@ -178,7 +189,7 @@
 	}
 
 	protected static class FilteredUsageCrossReferencer
-		extends EcoreUtil.UsageCrossReferencer {
+			extends EcoreUtil.UsageCrossReferencer {
 
 		protected static interface Filter {
 
@@ -245,6 +256,33 @@
 	 */
 	protected static final String PROPERTIES_FILE_EXTENSION = "properties"; //$NON-NLS-1$
 
+	/**
+	 * The scheme for platform URIs.
+	 */
+	private static final String URI_SCHEME_PLATFORM = "platform"; //$NON-NLS-1$
+
+	/**
+	 * The first segment for platform plugin URIs.
+	 */
+	private static final String URI_SEGMENT_PLUGIN = "plugin"; //$NON-NLS-1$
+
+	/**
+	 * The default URI converter for resource bundle look-ups.
+	 */
+	private static final URIConverter DEFAULT_URI_CONVERTER = new URIConverterImpl();
+
+	/**
+	 * A cache of locales.
+	 */
+	private static final Map LOCALES = Collections
+		.synchronizedMap(new HashMap());
+
+	/**
+	 * A cache of resource bundles.
+	 */
+	private static final Map RESOURCE_BUNDLES = Collections
+		.synchronizedMap(new HashMap());
+
 	protected static EAnnotation createEAnnotation(String source,
 			EModelElement eModelElement) {
 
@@ -510,4 +548,133 @@
 		return resourceBundleURIs;
 	}
 
+	/**
+	 * Retrieves the (cached) resource bundle for the specified object in the
+	 * specified locale.
+	 * 
+	 * @param eObject
+	 *            The object for which to retrieve the resource bundle.
+	 * @param locale
+	 *            The locale in which to retrieve the resource bundle.
+	 * @return The resource bundle for the object in the locale.
+	 */
+	protected static ResourceBundle getResourceBundle(EObject eObject,
+			Locale locale) {
+
+		eObject = EcoreUtil.getRootContainer(eObject);
+
+		if (!RESOURCE_BUNDLES.containsKey(eObject)
+			|| !locale.equals(LOCALES.get(eObject))) {
+
+			ResourceBundle resourceBundle = null;
+			Resource resource = eObject.eResource();
+
+			if (null != resource) {
+				ResourceSet resourceSet = resource.getResourceSet();
+				URIConverter uriConverter = null == resourceSet
+					? DEFAULT_URI_CONVERTER
+					: resourceSet.getURIConverter();
+
+				List resourceBundleURIs = getResourceBundleURIs(resource
+					.getURI(), locale);
+
+				if (null != EcorePlugin.getWorkspaceRoot()) {
+					URI normalizedURI = uriConverter.normalize(resource
+						.getURI());
+					int segmentCount = normalizedURI.segmentCount();
+
+					if (URI_SCHEME_PLATFORM.equals(normalizedURI.scheme())
+						&& segmentCount > 2
+						&& URI_SEGMENT_PLUGIN.equals(normalizedURI.segment(0))) {
+
+						Bundle bundle = Platform.getBundle(normalizedURI
+							.segment(1));
+
+						if (null != bundle) {
+							Bundle[] fragments = Platform.getFragments(bundle);
+
+							if (null != fragments) {
+								String[] trailingSegments = (String[]) normalizedURI
+									.segmentsList().subList(2, segmentCount)
+									.toArray(new String[]{});
+
+								for (int i = 0; i < fragments.length; i++) {
+									resourceBundleURIs.addAll(0,
+										getResourceBundleURIs(normalizedURI
+											.trimSegments(segmentCount - 1)
+											.appendSegment(
+												fragments[i].getSymbolicName())
+											.appendSegments(trailingSegments),
+											locale));
+								}
+							}
+						}
+					}
+				}
+
+				for (Iterator i = resourceBundleURIs.iterator(); i.hasNext();) {
+
+					try {
+						resourceBundle = new PropertyResourceBundle(
+							uriConverter.createInputStream((URI) i.next()));
+						locale = resourceBundle.getLocale();
+						break;
+					} catch (IOException ioe) {
+						// ignore
+					}
+				}
+			}
+
+			LOCALES.put(eObject, locale);
+			RESOURCE_BUNDLES.put(eObject, resourceBundle);
+		}
+
+		return (ResourceBundle) RESOURCE_BUNDLES.get(eObject);
+	}
+
+	/**
+	 * Retrieves the (cached) resource bundle for the specified object in the
+	 * default locale.
+	 * 
+	 * @param eObject
+	 *            The object for which to retrieve the resource bundle.
+	 * @return The resource bundle for the object in the default locale.
+	 */
+	protected static ResourceBundle getResourceBundle(EObject eObject) {
+		return getResourceBundle(eObject, Locale.getDefault());
+	}
+
+	/**
+	 * Retrieves a (localized) string for the specified object.
+	 * 
+	 * @param object
+	 *            The object for which to retrieve a string.
+	 * @param key
+	 *            The key in the resource bundle.
+	 * @param defaultString
+	 *            The string to return if no string for the given key can be
+	 *            found.
+	 * @return The (localized) string.
+	 */
+	protected static String getString(EObject eObject, String key,
+			String defaultString) {
+
+		String string = defaultString;
+
+		if (null != eObject) {
+
+			try {
+				ResourceBundle resourceBundle = getResourceBundle(eObject);
+
+				if (null != resourceBundle) {
+					string = resourceBundle.getString(key);
+				}
+			} catch (MissingResourceException mre) {
+				// ignore
+			}
+		}
+
+		return string;
+	}
+
 }
\ No newline at end of file