From 411406269e8ab64e15b7945dbefdeca5c1d35bae Mon Sep 17 00:00:00 2001
From: Simon Barner <barner@fortiss.org>
Date: Mon, 8 Sep 2014 10:50:53 +0000
Subject: [PATCH] - Polish instantiation of IAnnotationProviders   - Get
 factory from EStructuralFeature types   - Get default values from meta-model 
  - Remove EStructuralFeatureDescriptor   - Enable automatic construction of a
 EStructuralFeatureValueProviderBase for all features of a given EClass
 (instance key = field name) - Unify creation of editing support   - Merge
 Enum support into EStructuralFeatureValueProviderBase   - Enable management
 of input selectable from ComboBox also in the multi-instance case refs 1841

---
 .../base/ui/annotation/AnnotationEntry.java   |   4 +-
 .../DerivedAnnotationValueProviderBase.java   |   6 +-
 ...icInstanceAnnotationValueProviderBase.java |   5 +-
 .../EStructuralFeatureDescriptor.java         |  62 ------
 .../EStructuralFeatureValueProviderBase.java  | 198 +++++++++++-------
 .../IAnnotationValueProvider.java             |   6 +-
 .../SingleEnumAttributeValueProviderBase.java |  88 --------
 .../valueprovider/ValueProviderBase.java      | 126 ++++++-----
 .../view/GenericAnnotationView.java           |  44 ++--
 9 files changed, 234 insertions(+), 305 deletions(-)
 delete mode 100644 org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/EStructuralFeatureDescriptor.java
 delete mode 100644 org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/SingleEnumAttributeValueProviderBase.java

diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/AnnotationEntry.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/AnnotationEntry.java
index fc716aa78..128ab69d0 100644
--- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/AnnotationEntry.java
+++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/AnnotationEntry.java
@@ -191,9 +191,11 @@ public final class AnnotationEntry {
 	/**
 	 * Creates the {@link EditingSupport} element for the {@link IAnnotatedSpecification} of type
 	 * {@code clazz} (for use in the {@link GenericAnnotationView} .
+	 * 
+	 * @throws Exception
 	 */
 	public EditingSupport createSpecificationEditElement(ColumnViewer viewer,
-			Class<? extends IAnnotatedSpecification> clazz, String instanceKey) {
+			Class<? extends IAnnotatedSpecification> clazz, String instanceKey) throws Exception {
 		for(IAnnotatedSpecification s : specificationsList) {
 			if(clazz.isInstance(s)) {
 				return providerSpecMapping.get(clazz).createEditingSupport(viewer, clazz,
diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/DerivedAnnotationValueProviderBase.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/DerivedAnnotationValueProviderBase.java
index d83fac55e..1fd5c6a4a 100644
--- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/DerivedAnnotationValueProviderBase.java
+++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/DerivedAnnotationValueProviderBase.java
@@ -18,7 +18,6 @@ $Id$
 package org.fortiss.tooling.base.ui.annotation.valueprovider;
 
 import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EFactory;
 import org.eclipse.jface.viewers.ColumnViewer;
 import org.eclipse.jface.viewers.EditingSupport;
 import org.fortiss.tooling.base.model.element.IAnnotatedSpecification;
@@ -40,9 +39,8 @@ public abstract class DerivedAnnotationValueProviderBase<T extends IDerivedAnnot
 	 * Constructs a {@link IAnnotationValueProvider} for derived annotations (i.e., based on
 	 * {@link IDerivedAnnotation}).
 	 */
-	public DerivedAnnotationValueProviderBase(EClass annotatedSpecificationEClass,
-			EFactory annotationFactory) {
-		super(annotatedSpecificationEClass, annotationFactory);
+	public DerivedAnnotationValueProviderBase(EClass annotatedSpecificationEClass) {
+		super(annotatedSpecificationEClass);
 	}
 
 	/** {@inheritDoc} */
diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/DynamicInstanceAnnotationValueProviderBase.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/DynamicInstanceAnnotationValueProviderBase.java
index 589d22176..5b0be31cf 100644
--- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/DynamicInstanceAnnotationValueProviderBase.java
+++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/DynamicInstanceAnnotationValueProviderBase.java
@@ -74,9 +74,8 @@ public abstract class DynamicInstanceAnnotationValueProviderBase<T extends IAnno
 	 * {@link EStructuralFeature}.
 	 */
 	public DynamicInstanceAnnotationValueProviderBase(EClass annotatedSpecificationEClass,
-			EFactory annotationFactory, EStructuralFeature structuralFeature,
-			EFactory attributeFactory, EDataType valueDataType, EFactory valueFactory) {
-		super(annotatedSpecificationEClass, annotationFactory, structuralFeature, attributeFactory);
+			EStructuralFeature structuralFeature, EDataType valueDataType, EFactory valueFactory) {
+		super(annotatedSpecificationEClass, structuralFeature);
 		this.valueDataType = valueDataType;
 		this.valueFactory = valueFactory;
 	}
diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/EStructuralFeatureDescriptor.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/EStructuralFeatureDescriptor.java
deleted file mode 100644
index 592e25581..000000000
--- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/EStructuralFeatureDescriptor.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*--------------------------------------------------------------------------+
-$Id$
-|                                                                          |
-| Copyright 2014 ForTISS GmbH                     |
-|                                                                          |
-| Licensed under the Apache License, Version 2.0 (the "License");          |
-| you may not use this file except in compliance with the License.         |
-| You may obtain a copy of the License at                                  |
-|                                                                          |
-|    http://www.apache.org/licenses/LICENSE-2.0                            |
-|                                                                          |
-| Unless required by applicable law or agreed to in writing, software      |
-| distributed under the License is distributed on an "AS IS" BASIS,        |
-| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
-| See the License for the specific language governing permissions and      |
-| limitations under the License.                                           |
-+--------------------------------------------------------------------------*/
-package org.fortiss.tooling.base.ui.annotation.valueprovider;
-
-import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EFactory;
-import org.eclipse.emf.ecore.EStructuralFeature;
-
-/**
- * Descriptor for a single {@link EStructuralFeature} (used in
- * {@link EStructuralFeatureValueProviderBase} to support multiple {@link EStructuralFeature}s
- * contained in a single {@link EClass}.
- */
-public class EStructuralFeatureDescriptor {
-	/** Reference to {@link EStructuralFeature}. */
-	private EStructuralFeature structuralFeature;
-
-	/** {@link EFactory} used to initialize {@link EStructuralFeature}. */
-	EFactory structuralFeatureFactory;
-
-	/** Default value used to initialize {@link EStructuralFeature}. */
-	String structuralFeatureDefaultValue;
-
-	/** Generates a descriptor for a single {@link EStructuralFeature}. */
-	public EStructuralFeatureDescriptor(EStructuralFeature structuralFeature,
-			EFactory structuralFeatureFactory, String structuralFeatureDefaultValue) {
-		this.structuralFeature = structuralFeature;
-		this.structuralFeatureFactory = structuralFeatureFactory;
-		this.structuralFeatureDefaultValue = structuralFeatureDefaultValue;
-	}
-
-	/** Returns structuralFeature. */
-	public EStructuralFeature getStructuralFeature() {
-		return structuralFeature;
-	}
-
-	/** Returns structuralFeatureFactory. */
-	public EFactory getStructuralFeatureFactory() {
-		return structuralFeatureFactory;
-	}
-
-	/** Returns structuralFeatureDefaultValue. */
-	public String getStructuralFeatureDefaultValue() {
-		return structuralFeatureDefaultValue;
-	}
-
-}
diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/EStructuralFeatureValueProviderBase.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/EStructuralFeatureValueProviderBase.java
index ba7cfb967..e2991a442 100644
--- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/EStructuralFeatureValueProviderBase.java
+++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/EStructuralFeatureValueProviderBase.java
@@ -17,18 +17,27 @@ $Id$
 +--------------------------------------------------------------------------*/
 package org.fortiss.tooling.base.ui.annotation.valueprovider;
 
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 import org.eclipse.emf.ecore.EAttribute;
 import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EClassifier;
 import org.eclipse.emf.ecore.EDataType;
+import org.eclipse.emf.ecore.EEnum;
+import org.eclipse.emf.ecore.EEnumLiteral;
 import org.eclipse.emf.ecore.EFactory;
 import org.eclipse.emf.ecore.EReference;
 import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.ETypedElement;
+import org.eclipse.jface.viewers.ColumnViewer;
+import org.eclipse.jface.viewers.EditingSupport;
 import org.fortiss.tooling.base.model.element.IAnnotatedSpecification;
 import org.fortiss.tooling.base.model.element.IModelElement;
+import org.fortiss.tooling.base.ui.annotation.editingsupport.ComboBoxEditingSupport;
 
 /**
  * Base class for {@link IAnnotationValueProvider}s that manages {@link EStructuralFeature}s
@@ -43,17 +52,11 @@ public abstract class EStructuralFeatureValueProviderBase<T extends IAnnotatedSp
 		extends ValueProviderBase<T> {
 
 	/**
-	 * Default key used in case this {@link IAnnotationValueProvider} is used to manage a single
-	 * {@link EStructuralFeature}, only.
-	 */
-	final static String DEFAULT_KEY = null;
-
-	/**
-	 * Map: Instance key -> {@link EStructuralFeatureDescriptor}s of the
-	 * {@link IAnnotatedSpecification} managed by
+	 * Map: Instance key -> {@link EStructuralFeature}s of the {@link IAnnotatedSpecification}
+	 * managed by
 	 * this {@link IAnnotationValueProvider}.
 	 */
-	final protected Map<String, EStructuralFeatureDescriptor> structuralFeatureDescriptorMap;
+	final protected Map<String, EStructuralFeature> structuralFeatureMap;
 
 	/**
 	 * Flag if multiple {@link EStructuralFeature}s are managed by this
@@ -63,65 +66,89 @@ public abstract class EStructuralFeatureValueProviderBase<T extends IAnnotatedSp
 
 	/**
 	 * Constructs a {@link IAnnotationValueProvider} for a {@link IAnnotatedSpecification} that
-	 * whose storage is implemented by a single {@link EStructuralFeature}, and that uses the
-	 * default constructor to construct a new value for the structural feature.
+	 * whose storage is implemented by a single {@link EStructuralFeature}.
 	 */
 	public EStructuralFeatureValueProviderBase(EClass annotatedSpecificationEClass,
-			EFactory annotationFactory, EStructuralFeature structuralFeature,
-			EFactory structuralFeatureFactory) {
-		this(annotatedSpecificationEClass, annotationFactory, structuralFeature,
-				structuralFeatureFactory, null);
+			EStructuralFeature structuralFeature) {
+
+		super(annotatedSpecificationEClass);
+
+		structuralFeatureMap = new HashMap<String, EStructuralFeature>();
+		structuralFeatureMap.put(DEFAULT_KEY, structuralFeature);
+
+		handlesMultipleEstructuralFeatures = false;
 	}
 
 	/**
 	 * Constructs a {@link IAnnotationValueProvider} for a {@link IAnnotatedSpecification} that
-	 * whose storage is implemented by a single {@link EStructuralFeature}.
+	 * whose storage is implemented by a number of {@link EStructuralFeature}s contained in a single
+	 * {@link EClass}. The mapping of of instance keys to the corresponding
+	 * {@link EStructuralFeature}s is explicitly provided in a {@link Map}.
 	 */
 	public EStructuralFeatureValueProviderBase(EClass annotatedSpecificationEClass,
-			EFactory annotationFactory, EStructuralFeature structuralFeature,
-			EFactory structuralFeatureFactory, final String structuralFeatureDefaultValue) {
+			Map<String, EStructuralFeature> structuralFeatureMap) {
 
-		super(annotatedSpecificationEClass, annotationFactory);
+		super(annotatedSpecificationEClass);
 
-		structuralFeatureDescriptorMap = new HashMap<String, EStructuralFeatureDescriptor>();
-		structuralFeatureDescriptorMap.put(DEFAULT_KEY, new EStructuralFeatureDescriptor(
-				structuralFeature, structuralFeatureFactory, structuralFeatureDefaultValue));
+		this.structuralFeatureMap = structuralFeatureMap;
 
-		handlesMultipleEstructuralFeatures = false;
+		handlesMultipleEstructuralFeatures = true;
 	}
 
 	/**
 	 * Constructs a {@link IAnnotationValueProvider} for a {@link IAnnotatedSpecification} that
-	 * whose storage is implemented by a number of {@link EStructuralFeature}s contained in a single
-	 * EClass, and that uses the default constructor to construct a new value for the structural
-	 * features.
+	 * whose storage is implemented all {@link EStructuralFeature}s defined locally in a single
+	 * {@link EClass} (i.e., not considering inherited attributes). The instance keys, and the
+	 * mapping to the corresponding {@link EStructuralFeature}s are automatically derived from the
+	 * underlying {@link EClass} (instance keys = field names of {@link EStructuralFeature}).
+	 */
+	public EStructuralFeatureValueProviderBase(EClass annotatedSpecificationEClass) {
+
+		this(annotatedSpecificationEClass, false);
+	}
+
+	/**
+	 * Constructs a {@link IAnnotationValueProvider} for a {@link IAnnotatedSpecification} that
+	 * whose storage is implemented all {@link EStructuralFeature}s defined locally in a single
+	 * {@link EClass} (i.e., not considering inherited attributes). The instance keys, and the
+	 * mapping to the corresponding {@link EStructuralFeature}s are automatically derived from the
+	 * underlying {@link EClass} (instance keys = field names of {@link EStructuralFeature}).
 	 */
 	public EStructuralFeatureValueProviderBase(EClass annotatedSpecificationEClass,
-			EFactory annotationFactory,
-			Map<String, EStructuralFeatureDescriptor> structuralFeatureDescriptorMap) {
+			boolean inheritedFeatures) {
 
-		super(annotatedSpecificationEClass, annotationFactory);
+		super(annotatedSpecificationEClass);
 
-		this.structuralFeatureDescriptorMap = structuralFeatureDescriptorMap;
+		structuralFeatureMap = new HashMap<String, EStructuralFeature>();
+
+		for(EStructuralFeature structuralFeature : (inheritedFeatures
+				? annotatedSpecificationEClass.getEAllStructuralFeatures()
+				: annotatedSpecificationEClass.getEStructuralFeatures())) {
+			structuralFeatureMap.put(structuralFeature.getName(), structuralFeature);
+		}
 
 		handlesMultipleEstructuralFeatures = true;
 	}
 
 	/**
-	 * Returns the {@link EStructuralFeatureDescriptor} for a given {@code instanceKey}, or throws
+	 * Returns the {@link EStructuralFeature} for a given {@code instanceKey}, or throws
 	 * an exception, if the key is unknown.
 	 * 
 	 */
-	protected EStructuralFeatureDescriptor getEStructuralFeatureDescriptor(String instanceKey)
-			throws Exception {
-		EStructuralFeatureDescriptor fd = structuralFeatureDescriptorMap.get(instanceKey);
-		if(fd == null) {
+	protected EStructuralFeature getEStructuralFeature(String instanceKey) throws Exception {
+		EStructuralFeature structuralFeature = structuralFeatureMap.get(instanceKey);
+		if(structuralFeature == null) {
 			throw new Exception("Instance key " + instanceKey +
 					" is unknown for annotation provider " +
 					annotatedSpecificationEClass.getInstanceClassName() + ".");
 		}
 
-		return fd;
+		return structuralFeature;
+	}
+
+	/** Returns the {@link EFactory} for the given {@link EStructuralFeature}. */
+	private EFactory getEFactory(EStructuralFeature structuralFeature) {
+		return structuralFeature.getEType().getEPackage().getEFactoryInstance();
 	}
 
 	/**
@@ -132,12 +159,11 @@ public abstract class EStructuralFeatureValueProviderBase<T extends IAnnotatedSp
 			setAnnotationValueFromString(String value, T specification, String instanceKey)
 					throws Exception {
 
-		EStructuralFeatureDescriptor fd = getEStructuralFeatureDescriptor(instanceKey);
-
+		EStructuralFeature structuralFeature = getEStructuralFeature(instanceKey);
 		specification.eSet(
-				fd.getStructuralFeature(),
-				fd.getStructuralFeatureFactory().createFromString(
-						((EAttribute)fd.getStructuralFeature()).getEAttributeType(), value));
+				structuralFeature,
+				getEFactory(structuralFeature).createFromString(
+						((EAttribute)structuralFeature).getEAttributeType(), value));
 	}
 
 	/** {@inheritDoc} */
@@ -152,7 +178,9 @@ public abstract class EStructuralFeatureValueProviderBase<T extends IAnnotatedSp
 			// In case the last occurrence of a value choice has been removed, it will be no longer
 			// be offered in the combo box.
 			if(((String)value).isEmpty()) {
-				String rval = getAnnotationValueAndUpdateInputChoice((String)value, specification);
+				String rval =
+						getAnnotationValueAndUpdateInputChoice((String)value, specification,
+								instanceKey);
 				if(rval != null) {
 					value = (U)rval;
 				}
@@ -160,8 +188,7 @@ public abstract class EStructuralFeatureValueProviderBase<T extends IAnnotatedSp
 
 			setAnnotationValueFromString((String)value, specification, instanceKey);
 		} else {
-			specification.eSet(getEStructuralFeatureDescriptor(instanceKey).getStructuralFeature(),
-					value);
+			specification.eSet(getEStructuralFeature(instanceKey), value);
 		}
 	}
 
@@ -177,14 +204,13 @@ public abstract class EStructuralFeatureValueProviderBase<T extends IAnnotatedSp
 			throws Exception {
 		// See comment in setAnnotationValue(U value, T specification)
 		if((value == null || value.isEmpty())) {
-			String rval = getAnnotationValueAndUpdateInputChoice(value, specification);
+			String rval = getAnnotationValueAndUpdateInputChoice(value, specification, instanceKey);
 			if(rval != null) {
 				value = rval;
 			}
 		}
 
-		EStructuralFeature structuralFeature =
-				getEStructuralFeatureDescriptor(instanceKey).getStructuralFeature();
+		EStructuralFeature structuralFeature = getEStructuralFeature(instanceKey);
 
 		if(structuralFeature instanceof EAttribute) {
 			setAnnotationValueFromString(value, specification, instanceKey);
@@ -207,8 +233,7 @@ public abstract class EStructuralFeatureValueProviderBase<T extends IAnnotatedSp
 	@SuppressWarnings("unchecked")
 	@Override
 	public <U> U getAnnotationValue(T specification, String instanceKey) throws Exception {
-		return (U)specification.eGet(getEStructuralFeatureDescriptor(instanceKey)
-				.getStructuralFeature());
+		return (U)specification.eGet(getEStructuralFeature(instanceKey));
 	}
 
 	/** {@inheritDoc} */
@@ -217,54 +242,68 @@ public abstract class EStructuralFeatureValueProviderBase<T extends IAnnotatedSp
 		return getAnnotationValue(specification, DEFAULT_KEY);
 	}
 
+	/** {@inheritDoc} */
+	@Override
+	public EditingSupport createEditingSupport(ColumnViewer viewer,
+			Class<? extends IAnnotatedSpecification> clazz, String instanceKey) throws Exception {
+
+		EStructuralFeature structuralFeature = getEStructuralFeature(instanceKey);
+		if(structuralFeature.getUpperBound() > 1 ||
+				structuralFeature.getUpperBound() == ETypedElement.UNBOUNDED_MULTIPLICITY) {
+			throw new Exception(
+					"EStructuralValueProvider has not been implemented for attribute multiplicity > 1.");
+		}
+		EClassifier eType = null;
+		try {
+			eType = structuralFeature.getEType();
+		} catch(Exception e) {
+			// Ignore
+		}
+		if(eType instanceof EEnum) {
+			List<String> enumValues = new ArrayList<String>();
+			for(EEnumLiteral e : ((EEnum)eType).getELiterals()) {
+				enumValues.add(e.getName());
+			}
+
+			return new ComboBoxEditingSupport(viewer, clazz, enumValues, false);
+		}
+
+		return super.createEditingSupport(viewer, clazz, instanceKey);
+	}
+
 	/**
 	 * Creates a new instance of the {@link EStructuralFeature} (use to populate newly created
 	 * annotation instances created in
 	 * {@link #getAnnotatedSpecificationForModelElement(IModelElement)}.
 	 */
 	protected Object createStructuralFeatureInstance(String instanceKey) throws Exception {
-		EStructuralFeatureDescriptor fd = getEStructuralFeatureDescriptor(instanceKey);
+		EStructuralFeature structuralFeature = getEStructuralFeature(instanceKey);
 
-		if(fd.getStructuralFeature() instanceof EAttribute) {
+		EFactory factory = getEFactory(structuralFeature);
+		if(structuralFeature instanceof EAttribute) {
 
-			EDataType attributeEDataType =
-					((EAttribute)fd.getStructuralFeature()).getEAttributeType();
+			EDataType attributeEDataType = ((EAttribute)structuralFeature).getEAttributeType();
 
-			if(fd.getStructuralFeatureDefaultValue() != null) {
+			if(structuralFeature.getDefaultValueLiteral() != null) {
 				// Use default value if it has been specified
-				return fd.structuralFeatureFactory.createFromString(attributeEDataType,
-						fd.getStructuralFeatureDefaultValue());
-			}
-
-			// Return data types default value, if it is non-null.
-			Object rval = attributeEDataType.getDefaultValue();
-
-			if(rval != null) {
-				return rval;
-			}
-
-			try {
-				// Try to construct attribute from empty string
-				rval = fd.getStructuralFeatureFactory().createFromString(attributeEDataType, "");
-			} catch(NumberFormatException e) {
-				// Last try: initialize numbers with 0 (throws NumberFormatException if not
-				// successful).
-				rval = fd.getStructuralFeatureFactory().createFromString(attributeEDataType, "0");
+				return factory.createFromString(attributeEDataType,
+						structuralFeature.getDefaultValueLiteral());
 			}
 
-			return rval;
-		} else if(fd.getStructuralFeature() instanceof EReference) {
-			EReference reference = (EReference)fd.getStructuralFeature();
+			// Return data types default value
+			return attributeEDataType.getDefaultValue();
+		} else if(structuralFeature instanceof EReference) {
+			EReference reference = (EReference)structuralFeature;
 			if(reference.isContainment()) {
 				// EClasses attached to contained EReferences are created lazily by the
 				// corresponding generated code on the first access (i.e., also during get / "read")
 				return null;
 			}
-			return fd.getStructuralFeatureFactory().create(reference.getEReferenceType());
+			return factory.create(reference.getEReferenceType());
 		} else {
 			throw new Exception(
 					"createStructuralFeatureInstance() is not supported / has not been implemented the annotation type " +
-							fd.getStructuralFeature().getName() + ".");
+							structuralFeature.getName() + ".");
 		}
 	}
 
@@ -276,8 +315,7 @@ public abstract class EStructuralFeatureValueProviderBase<T extends IAnnotatedSp
 		// Create and set structural feature implementing the annotation
 		Object structuralFeatureVal = createStructuralFeatureInstance(instanceKey);
 		if(structuralFeatureVal != null) {
-			specification.eSet(getEStructuralFeatureDescriptor(instanceKey).getStructuralFeature(),
-					structuralFeatureVal);
+			specification.eSet(getEStructuralFeature(instanceKey), structuralFeatureVal);
 		}
 	}
 
@@ -285,7 +323,7 @@ public abstract class EStructuralFeatureValueProviderBase<T extends IAnnotatedSp
 	@Override
 	public Collection<String> getInstanceKeys(T specification) {
 		if(handlesMultipleEstructuralFeatures) {
-			return structuralFeatureDescriptorMap.keySet();
+			return structuralFeatureMap.keySet();
 		}
 		return super.getInstanceKeys(specification);
 	}
diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/IAnnotationValueProvider.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/IAnnotationValueProvider.java
index 280b7d8e6..98f843eb7 100644
--- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/IAnnotationValueProvider.java
+++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/IAnnotationValueProvider.java
@@ -138,9 +138,13 @@ public interface IAnnotationValueProvider<T extends IAnnotatedSpecification> ext
 	 * {@link EditingSupport}. For annotations whose {@link IAnnotationValueProvider}s support
 	 * multiple instances, an {@code instanceKey} to identify the corresponding instance of the
 	 * {@link IAnnotatedSpecification} needs to be provided.
+	 * 
+	 * @throws Exception
+	 *             If the editing support could not be created for the particular
+	 *             {@link IAnnotatedSpecification}.
 	 */
 	public EditingSupport createEditingSupport(ColumnViewer viewer,
-			Class<? extends IAnnotatedSpecification> clazz, String instanceKey);
+			Class<? extends IAnnotatedSpecification> clazz, String instanceKey) throws Exception;
 
 	/**
 	 * Factory method that creates a new {@link IAnnotatedSpecification} specialization of type T to
diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/SingleEnumAttributeValueProviderBase.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/SingleEnumAttributeValueProviderBase.java
deleted file mode 100644
index 921851247..000000000
--- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/SingleEnumAttributeValueProviderBase.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*--------------------------------------------------------------------------+
-$Id$
-|                                                                          |
-| Copyright 2014 ForTISS GmbH                     |
-|                                                                          |
-| Licensed under the Apache License, Version 2.0 (the "License");          |
-| you may not use this file except in compliance with the License.         |
-| You may obtain a copy of the License at                                  |
-|                                                                          |
-|    http://www.apache.org/licenses/LICENSE-2.0                            |
-|                                                                          |
-| Unless required by applicable law or agreed to in writing, software      |
-| distributed under the License is distributed on an "AS IS" BASIS,        |
-| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
-| See the License for the specific language governing permissions and      |
-| limitations under the License.                                           |
-+--------------------------------------------------------------------------*/
-package org.fortiss.tooling.base.ui.annotation.valueprovider;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.eclipse.emf.ecore.EAttribute;
-import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EEnum;
-import org.eclipse.emf.ecore.EEnumLiteral;
-import org.eclipse.emf.ecore.EFactory;
-import org.eclipse.jface.viewers.ColumnViewer;
-import org.eclipse.jface.viewers.EditingSupport;
-import org.fortiss.tooling.base.model.element.IAnnotatedSpecification;
-import org.fortiss.tooling.base.ui.annotation.editingsupport.ComboBoxEditingSupport;
-
-/**
- * Base class for {@link IAnnotationValueProvider}s that manages a single enumeration contained in a
- * {@link IAnnotatedSpecification}. The provider will provide a {@link ComboBoxEditingSupport} that
- * is initialized to the enumeration value names specified in the respective ECore model
- * containing the enumeration type.
- * 
- * @author barner
- * @author $Author$
- * @version $Rev$
- * @ConQAT.Rating RED Hash:
- */
-public abstract class SingleEnumAttributeValueProviderBase<T extends IAnnotatedSpecification>
-		extends EStructuralFeatureValueProviderBase<T> {
-
-	/** Data type of the enumeration managed by this {@link IAnnotationValueProvider} */
-	private EEnum eEnum;
-
-	/**
-	 * Constructs a {@link IAnnotationValueProvider} for a {@link IAnnotatedSpecification} that
-	 * that that manages a single enumeration attribute contained in a
-	 * {@link IAnnotatedSpecification}. The enumeration attribute is initialized to its default
-	 * value.
-	 */
-	public SingleEnumAttributeValueProviderBase(EClass annotatedSpecificationEClass,
-			EFactory annotationFactory, EAttribute attribute, EEnum eEnum, EFactory attributeFactory) {
-		this(annotatedSpecificationEClass, annotationFactory, attribute, eEnum, attributeFactory,
-				null);
-	}
-
-	/**
-	 * Constructs a {@link IAnnotationValueProvider} for a {@link IAnnotatedSpecification} that
-	 * that that manages a single enumeration attribute contained in a
-	 * {@link IAnnotatedSpecification}. The constructor assumes that the
-	 * {@code attributeDefaultValue} matches of the enumeration names.
-	 */
-	public SingleEnumAttributeValueProviderBase(EClass annotatedSpecificationEClass,
-			EFactory annotationFactory, EAttribute attribute, EEnum eEnum,
-			EFactory attributeFactory, final String attributeDefaultValue) {
-		super(annotatedSpecificationEClass, annotationFactory, attribute, attributeFactory,
-				attributeDefaultValue);
-		this.eEnum = eEnum;
-	}
-
-	/** {@inheritDoc} */
-	@Override
-	public EditingSupport createEditingSupport(ColumnViewer viewer,
-			Class<? extends IAnnotatedSpecification> clazz, String instanceKey) {
-
-		List<String> enumValues = new ArrayList<String>();
-		for(EEnumLiteral e : eEnum.getELiterals()) {
-			enumValues.add(e.getName());
-		}
-
-		return new ComboBoxEditingSupport(viewer, clazz, enumValues, false);
-	}
-}
diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/ValueProviderBase.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/ValueProviderBase.java
index 6244062db..979e902b4 100644
--- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/ValueProviderBase.java
+++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/ValueProviderBase.java
@@ -19,14 +19,16 @@ package org.fortiss.tooling.base.ui.annotation.valueprovider;
 
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.TreeSet;
 
 import org.eclipse.emf.common.util.EList;
 import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EFactory;
+import org.eclipse.emf.ecore.EEnum;
 import org.eclipse.emf.ecore.EObject;
 import org.eclipse.jface.viewers.ColumnViewer;
 import org.eclipse.jface.viewers.EditingSupport;
@@ -50,39 +52,49 @@ import org.fortiss.tooling.kernel.utils.EcoreUtils;
 public abstract class ValueProviderBase<T extends IAnnotatedSpecification> implements
 		IAnnotationValueProvider<T> {
 
+	/**
+	 * Default key used in case this {@link IAnnotationValueProvider} is used to manage a single
+	 * instance key only.
+	 */
+	protected final static String DEFAULT_KEY = null;
+
 	/**
 	 * {@link EClass} of {@link IAnnotatedSpecification} that contains the respective structural
 	 * feature and that is managed by this {@link IAnnotationValueProvider}.
 	 */
 	protected final EClass annotatedSpecificationEClass;
-	/**
-	 * {@link EFactory} of ECore model that contains {@link IAnnotatedSpecification} identified by
-	 * {@code annotatedSpecificationEClass} (used to create new instances of the annotation).
-	 */
-	protected final EFactory annotationFactory;
 
 	/**
-	 * Fixed input choice to be offered in a combo box. The semantics of this field is as follows:
+	 * Map: instanceKey -> Fixed input choice to be offered in a combo box. The semantics of the map
+	 * value is as follows:
 	 * <ul>
-	 * <li> {@code fixedInputChoice == null} -> do not use fixed values, provide text input cell.</li>
-	 * <li> {@code !fixedInputChoice.isEmpty()} -> provide a fixed set of choices in an input box.
-	 * For enum types, see {@link SingleEnumAttributeValueProviderBase}</li>
-	 * <li> {@code fixedInputChoice.isEmpty()} -> dynamically manage the set of provided values, i.e.
-	 * the combo box is editable and enables the user to add new values and remove existing choices
-	 * (by removing all instances of them).</li>
+	 * <li> {@code fixedInputChoice[key] == null} -> do not use fixed values, provide text input
+	 * cell.</li>
+	 * <li> {@code !fixedInputChoice[key].isEmpty()} -> provide a fixed set of choices in an input
+	 * box.
+	 * <li> {@code fixedInputChoice[key].isEmpty()} -> dynamically manage the set of provided values,
+	 * i.e. the combo box is editable and enables the user to add new values and remove existing
+	 * choices (by removing all instances of them).</li>
+	 * <li>For enum types, the set of inputs is automatically initialized from the underlying
+	 * {@link EEnum} type definition.</li>
 	 */
-	private List<String> fixedInputChoice;
+	private Map<String, List<String>> fixedInputChoiceMap;
 
-	/** Current input choice, computed according to the initialization of {@link #fixedInputChoice}. */
-	private Collection<String> currentInputChoice;
+	/**
+	 * Map: instanceKey -> Current input choice, computed according to the initialization of
+	 * {@link #fixedInputChoiceMap}.
+	 */
+	private Map<String, Collection<String>> currentInputChoiceMap;
 
 	/**
 	 * Constructs a new {@link IAnnotationValueProvider} for an annotation specified in a given
-	 * {@link EClass}, and constructed using a given {@link EFactory}.
+	 * {@link EClass}.
 	 */
-	public ValueProviderBase(EClass annotatedSpecificationEClass, EFactory annotationFactory) {
+	public ValueProviderBase(EClass annotatedSpecificationEClass) {
 		this.annotatedSpecificationEClass = annotatedSpecificationEClass;
-		this.annotationFactory = annotationFactory;
+
+		fixedInputChoiceMap = new HashMap<String, List<String>>();
+		currentInputChoiceMap = new HashMap<String, Collection<String>>();
 	}
 
 	/** {@inheritDoc} */
@@ -128,20 +140,24 @@ public abstract class ValueProviderBase<T extends IAnnotatedSpecification> imple
 						specification.getClass());
 	}
 
-	/** {@inheritDoc} */
+	/**
+	 * {@inheritDoc}
+	 * 
+	 * @throws Exception
+	 */
 	@Override
 	public EditingSupport createEditingSupport(ColumnViewer viewer,
-			Class<? extends IAnnotatedSpecification> clazz, String instanceKey) {
+			Class<? extends IAnnotatedSpecification> clazz, String instanceKey) throws Exception {
 
 		try {
-			initializeInputChoice(viewer, clazz);
+			initializeInputChoice(viewer, clazz, instanceKey);
 		} catch(Exception e) {
 			// Use standard text editor as fallback
-			currentInputChoice = null;
+			currentInputChoiceMap = null;
 		}
 
 		// Input is not restricted -> free editing in text cell
-		if(currentInputChoice == null) {
+		if(currentInputChoiceMap.get(instanceKey) == null) {
 			if(instanceKey == null) {
 				return new TextEditingSupport(viewer, clazz);
 			}
@@ -153,8 +169,8 @@ public abstract class ValueProviderBase<T extends IAnnotatedSpecification> imple
 
 		// Input is restricted to concrete set of values
 		// (use SingleEnumAttributeValueProviderBase for Enum types!)
-		return new ComboBoxEditingSupport(viewer, clazz, currentInputChoice,
-				fixedInputChoice.isEmpty());
+		return new ComboBoxEditingSupport(viewer, clazz, currentInputChoiceMap.get(instanceKey),
+				fixedInputChoiceMap.get(instanceKey).isEmpty());
 	}
 
 	/**
@@ -162,7 +178,7 @@ public abstract class ValueProviderBase<T extends IAnnotatedSpecification> imple
 	 * {@link #createEditingSupport(ColumnViewer, Class, String)}).
 	 */
 	public EditingSupport createEditingSupport(ColumnViewer viewer,
-			Class<? extends IAnnotatedSpecification> clazz) {
+			Class<? extends IAnnotatedSpecification> clazz) throws Exception {
 
 		return createEditingSupport(viewer, clazz, null);
 	}
@@ -210,7 +226,9 @@ public abstract class ValueProviderBase<T extends IAnnotatedSpecification> imple
 		}
 
 		// Create annotation
-		T specification = (T)annotationFactory.create(annotatedSpecificationEClass);
+		T specification =
+				(T)annotatedSpecificationEClass.getEPackage().getEFactoryInstance()
+						.create(annotatedSpecificationEClass);
 		if(getInstanceKeys(specification).isEmpty()) {
 			decorateAnnotationSpecification(specification);
 		} else {
@@ -252,26 +270,35 @@ public abstract class ValueProviderBase<T extends IAnnotatedSpecification> imple
 		return false;
 	}
 
-	/** Sets the {@link #fixedInputChoice} field. */
+	/** Sets the {@link #fixedInputChoiceMap} field for a specific instance key */
+	public void setFixedInputChoice(List<String> fixedInputChoice, String instanceKey) {
+		this.fixedInputChoiceMap.put(instanceKey, fixedInputChoice);
+	}
+
+	/**
+	 * Sets the {@link #fixedInputChoiceMap} field for an {@link IAnnotationValueProvider} that
+	 * manages only a single instance key.
+	 */
 	public void setFixedInputChoice(List<String> fixedInputChoice) {
-		this.fixedInputChoice = fixedInputChoice;
+		setFixedInputChoice(fixedInputChoice, DEFAULT_KEY);
 	}
 
 	/**
-	 * Initializes the {@link #currentInputChoice} field (called during the construction of the
+	 * Initializes the {@link #currentInputChoiceMap} field (called during the construction of the
 	 * editing support in {@link #createEditingSupport(ColumnViewer, Class)}).
 	 */
 	@SuppressWarnings("unchecked")
 	private void initializeInputChoice(ColumnViewer viewer,
-			Class<? extends IAnnotatedSpecification> clazz) throws Exception {
+			Class<? extends IAnnotatedSpecification> clazz, String instanceKey) throws Exception {
 		// Input choice is not set, or it is restricted to concrete set of values
 		// (use SingleEnumAttributeValueProviderBase for Enum types!)
-		if(fixedInputChoice == null || !fixedInputChoice.isEmpty()) {
-			currentInputChoice = fixedInputChoice;
+		if(fixedInputChoiceMap.get(instanceKey) == null ||
+				!fixedInputChoiceMap.get(instanceKey).isEmpty()) {
+			currentInputChoiceMap.put(instanceKey, fixedInputChoiceMap.get(instanceKey));
 
 		} else if(!(viewer.getInput() instanceof Set<?>) || ((Set<?>)viewer.getInput()).isEmpty() ||
 				!(((Set<?>)viewer.getInput()).iterator().next() instanceof AnnotationEntry)) {
-			currentInputChoice = null;
+			currentInputChoiceMap.put(instanceKey, null);
 
 		} else {
 
@@ -283,10 +310,12 @@ public abstract class ValueProviderBase<T extends IAnnotatedSpecification> imple
 				root = root.eContainer();
 			}
 
-			currentInputChoice = new TreeSet<String>();
+			Set<String> choices = new TreeSet<String>();
 			for(T specification : (EList<T>)EcoreUtils.getChildrenWithType(root, clazz)) {
-				currentInputChoice.add(getAnnotationValue(specification).toString());
+				choices.add(getAnnotationValue(specification).toString());
 			}
+
+			currentInputChoiceMap.put(instanceKey, choices);
 		}
 	}
 
@@ -295,31 +324,32 @@ public abstract class ValueProviderBase<T extends IAnnotatedSpecification> imple
 	 * {@link #setAnnotationValue(String, IAnnotatedSpecification)}. In particular, this
 	 * method handles the removal of input choices from if these are dynamically managed.
 	 */
-	protected String getAnnotationValueAndUpdateInputChoice(String value, T specification)
-			throws Exception {
-		if((value == null || value.isEmpty()) && currentInputChoice != null &&
-				!currentInputChoice.isEmpty()) {
+	protected String getAnnotationValueAndUpdateInputChoice(String value, T specification,
+			String instanceKey) throws Exception {
+		if((value == null || value.isEmpty()) && currentInputChoiceMap.get(instanceKey) != null &&
+				!currentInputChoiceMap.get(instanceKey).isEmpty()) {
 			// Only one entry left: do not remove
-			if(currentInputChoice.size() == 1) {
-				return currentInputChoice.iterator().next();
+			if(currentInputChoiceMap.get(instanceKey).size() == 1) {
+				return currentInputChoiceMap.get(instanceKey).iterator().next();
 			}
 
 			// 1st entry is to be removed: Choose 2nd entry as new value
 			String currentValue = getAnnotationValue(specification);
-			if(currentInputChoice.iterator().next().equals(currentValue)) {
-				Iterator<String> iter = currentInputChoice.iterator();
+			if(currentInputChoiceMap.get(instanceKey).iterator().next().equals(currentValue)) {
+				Iterator<String> iter = currentInputChoiceMap.get(instanceKey).iterator();
 				iter.next();
 				String rval = iter.next();
-				currentInputChoice.remove(currentValue);
+				currentInputChoiceMap.get(instanceKey).remove(currentValue);
 				return rval;
 			}
 
 			// Otherwise, return the entry just before the entry to be removed.
 			String rval = null;
-			for(Iterator<String> iter = currentInputChoice.iterator(); iter.hasNext();) {
+			for(Iterator<String> iter = currentInputChoiceMap.get(instanceKey).iterator(); iter
+					.hasNext();) {
 				String s = iter.next();
 				if(s != null && s.equals(currentValue)) {
-					currentInputChoice.remove(currentValue);
+					currentInputChoiceMap.get(instanceKey).remove(currentValue);
 					return rval;
 				}
 				rval = s;
diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/view/GenericAnnotationView.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/view/GenericAnnotationView.java
index 9be2f037b..f7ea75ddd 100644
--- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/view/GenericAnnotationView.java
+++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/view/GenericAnnotationView.java
@@ -584,7 +584,7 @@ public class GenericAnnotationView extends AnnotationViewPartBase {
 	/** Creates a column in tableViewer that displays the annotation given in spec */
 	protected void createAnnotationColumn(ColumnHandle columnHandle) {
 
-		TableColumn tableColumn;
+		TableColumn tableColumn = null;
 		if(columnHandle.isCreateColumn()) {
 			// Create column that contains a button for adding new instances of the
 			// current annotation type.
@@ -595,30 +595,38 @@ public class GenericAnnotationView extends AnnotationViewPartBase {
 			tableColumn = column.getColumn();
 
 		} else {
+			Class<? extends IAnnotatedSpecification> annotationClass =
+					columnHandle.getAnnotatedSpecification().getClass();
 
-			// Add new new column
-			TableViewerColumn column = new TableViewerColumn(tableViewer, SWT.NONE);
-			tableColumn = column.getColumn();
+			// Add new column
+			try {
 
-			String specName = getColumnName(columnHandle);
-			tableColumn.setText(specName);
+				// Have the matching EditingSupport created for the current annotated specification
+				// (work is delegated to respective IAnnotationValueProvider implementation)
+				EditingSupport editingSupport =
+						columnHandle.getEntry().createSpecificationEditElement(tableViewer,
+								annotationClass, columnHandle.getInstanceKey());
+				TableViewerColumn column = new TableViewerColumn(tableViewer, SWT.NONE);
+				tableColumn = column.getColumn();
 
-			Class<? extends IAnnotatedSpecification> annotationClass =
-					columnHandle.getAnnotatedSpecification().getClass();
+				String specName = getColumnName(columnHandle);
+				tableColumn.setText(specName);
+
+				column.setEditingSupport(editingSupport);
 
-			// Have the matching EditingSupport created for the current annotated specification
-			// (work is delegated to respective IAnnotationValueProvider implementation)
-			EditingSupport editingSupport =
-					columnHandle.getEntry().createSpecificationEditElement(tableViewer,
-							annotationClass, columnHandle.getInstanceKey());
-			column.setEditingSupport(editingSupport);
+				// Add column label provider, and set EditingSupport
+				column.setLabelProvider(new AnnotationLabelProvider(annotationClass, this,
+						columnHandle.getInstanceKey()));
+			} catch(Exception e) {
+				System.out.println("Failed to create editing support for annotation class " +
+						annotationClass.getCanonicalName() + ": " + e.getMessage());
+			}
 
-			// Add column label provider, and set EditingSupport
-			column.setLabelProvider(new AnnotationLabelProvider(annotationClass, this, columnHandle
-					.getInstanceKey()));
 		}
 
-		tableColumn.setWidth(125);
+		if(tableColumn != null) {
+			tableColumn.setWidth(125);
+		}
 
 	}
 
-- 
GitLab