518821: add support for dynamic enums

Change-Id: I2716200fde64dd3f9def0ffeea0a3c234b9c4317
Signed-off-by: Florian Schmitt <florian.schmitt@atos.net>
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/AxisType.java b/src/main/java/org/eclipse/mdm/api/base/model/AxisType.java
index 9e88717..2576bbb 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/AxisType.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/AxisType.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Gigatronik Ingolstadt GmbH
+ * Copyright (c) 2016 Gigatronik Ingolstadt GmbH 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
@@ -16,7 +16,7 @@
  * @author Sebastian Dirsch, Gigatronik Ingolstadt GmbH
  * @see Channel
  */
-public enum AxisType {
+public class AxisType extends EnumerationValue{
 
 	// ======================================================================
 	// Enumerations
@@ -25,17 +25,17 @@
 	/**
 	 * A {@link Channel} of this type may be displayed as the x-axis.
 	 */
-	X_AXIS,
+	public static final AxisType X_AXIS = new AxisType(); 
 
 	/**
 	 * A {@link Channel} of this type may be displayed as the y-axis.
 	 */
-	Y_AXIS,
+	public static final AxisType Y_AXIS = new AxisType();
 
 	/**
 	 * A {@link Channel} of this type may be displayed as the x- or y-axis.
 	 */
-	XY_AXIS;
+	public static final AxisType XY_AXIS = new AxisType();
 
 	// ======================================================================
 	// Public methods
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/EnumRegistry.java b/src/main/java/org/eclipse/mdm/api/base/model/EnumRegistry.java
new file mode 100644
index 0000000..0b01923
--- /dev/null
+++ b/src/main/java/org/eclipse/mdm/api/base/model/EnumRegistry.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2017 Florian Schmitt
+ * 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
+ */
+
+package org.eclipse.mdm.api.base.model;
+
+import java.util.HashMap;
+
+/**
+ * This singleton class registers globally available enumerations.
+ *
+ */
+public class EnumRegistry {
+
+	// singleton instance
+	private static final EnumRegistry instance = new EnumRegistry();
+
+	public static final String SCALAR_TYPE = "ScalarType";
+	public static final String INTERPOLATION = "Interpolation";
+	public static final String SEQUENCE_REPRESENTATION = "SequenceRepresentation";
+	public static final String TYPE_SPECIFICATION = "TypeSpecification";
+	public static final String VALUE_TYPE = "ValueType";
+	public static final String VERSION_STATE = "VersionState";
+	public static final String AXIS_TYPE = "AxisType";
+
+	private HashMap<String, Enumeration<?>> enumerations;
+
+	/**
+	 * Constructor. Not called directly. Use getInstance() instead.
+	 */
+	private EnumRegistry() {
+		enumerations = new HashMap<>();
+		add(INTERPOLATION, new Enumeration<Interpolation>(Interpolation.class, INTERPOLATION));
+		add(SCALAR_TYPE, new Enumeration<ScalarType>(ScalarType.class, SCALAR_TYPE));
+		add(SEQUENCE_REPRESENTATION,
+				new Enumeration<SequenceRepresentation>(SequenceRepresentation.class, SEQUENCE_REPRESENTATION));
+		add(TYPE_SPECIFICATION, new Enumeration<TypeSpecification>(TypeSpecification.class, TYPE_SPECIFICATION));
+		add(VALUE_TYPE, new Enumeration<ValueType>(ValueType.class, VALUE_TYPE));
+		add(VERSION_STATE, new Enumeration<VersionState>(VersionState.class, VERSION_STATE));
+		add(AXIS_TYPE, new Enumeration<AxisType>(AxisType.class, AXIS_TYPE));
+	}
+
+	/**
+	 * adds a new enumeration to the registry
+	 * 
+	 * @param name
+	 *            the name under which the enumeration can be accessed
+	 * @param enumeration
+	 *            the dynamic enumeration object
+	 */
+	public void add(String name, Enumeration<?> enumeration) {
+		enumerations.put(name, enumeration);
+	}
+
+	/**
+	 * @param name
+	 *            the name of the registered enumeration
+	 * @return the dynamic enumeration object
+	 */
+	@SuppressWarnings("rawtypes")
+	public Enumeration get(String name) {
+		return enumerations.get(name);
+	}
+
+	/**
+	 * @return the instance of this singleton
+	 */
+	public static EnumRegistry getInstance() {
+		return instance;
+	}
+}
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/Enumeration.java b/src/main/java/org/eclipse/mdm/api/base/model/Enumeration.java
new file mode 100644
index 0000000..f0a823e
--- /dev/null
+++ b/src/main/java/org/eclipse/mdm/api/base/model/Enumeration.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2017 Florian Schmitt
+ * 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
+ */
+
+package org.eclipse.mdm.api.base.model;
+
+import java.lang.reflect.Field;
+import java.util.HashMap;
+
+/**
+ * A class which dynamically bundles enumeration values
+ *
+ * @param <E>
+ */
+public class Enumeration<E extends EnumerationValue> {
+	public E ens = null;
+
+	private HashMap<String, E> values;
+
+	private HashMap<E, String> revvalues;
+
+	private HashMap<Integer, String> ordinals;
+
+	private HashMap<String, Integer> revordinals;
+
+	private int nextordinal;
+
+	private String name;
+
+	private Class<E> enumclass;
+
+	/**
+	 * Constructor. Static fields in the given enumclass of the same type are
+	 * added automatically as enum values. This way you can simply prefill the
+	 * object with static values.
+	 * 
+	 * @param enumclass
+	 *            the class of the enumeration values
+	 * @param name
+	 *            the name of the enumeration bundle
+	 */
+	@SuppressWarnings("unchecked")
+	public Enumeration(Class<E> enumclass, String name) {
+		this.nextordinal = 0;
+		this.values = new HashMap<>();
+		this.revvalues = new HashMap<>();
+		this.ordinals = new HashMap<>();
+		this.revordinals = new HashMap<>();
+		this.name = name;
+		this.enumclass = enumclass;
+		java.lang.reflect.Field[] fields = enumclass.getFields();
+		for (Field field : fields) {
+			if (java.lang.reflect.Modifier.isStatic(field.getModifiers())) // only
+																			// examine
+																			// static
+																			// fields
+			{
+				Object fieldObject;
+				try {
+					fieldObject = field.get(null);
+					if (!(enumclass.isInstance(fieldObject))) {
+						continue;
+					}
+				} catch (Exception e) {
+					throw new RuntimeException(e);
+				}
+				String fname = ((EnumerationValue) fieldObject).name();
+				if (fname == null) {
+					fname = field.getName();
+					((EnumerationValue) fieldObject).setName(fname);
+				}
+				((EnumerationValue) fieldObject).setOwner(this);
+				values.put(fname, (E) fieldObject);
+				revvalues.put((E) fieldObject, fname);
+				ordinals.put(nextordinal, fname);
+				revordinals.put(fname, nextordinal);
+				nextordinal++;
+			}
+		}
+	}
+
+	/**
+	 * adds a value to the dynamic enumeration
+	 * 
+	 * @param enumeration
+	 */
+	public void addValue(E enumeration) {
+		enumeration.setOwner(this);
+		String name = enumeration.name();
+		int ordinal = enumeration.ordinal();
+		values.put(name, enumeration);
+		revvalues.put(enumeration, name);
+		ordinals.put(ordinal, name);
+		revordinals.put(name, ordinal);
+	}
+
+	/**
+	 * returns the value represented by the given name
+	 * 
+	 * @param name
+	 * @return
+	 */
+	public E valueOf(String name) {
+		return values.get(name);
+	}
+
+	/**
+	 * returns the value represented by the given number
+	 * 
+	 * @param ordinal
+	 * @return
+	 */
+	public E valueOf(int ordinal) {
+		return values.get(ordinals.get(ordinal));
+	}
+
+	/**
+	 * returns the ordinal represented by the given enumeration value
+	 * 
+	 * @param enumval
+	 * @return
+	 */
+	public int ordinal(EnumerationValue enumval) {
+		return revordinals.get(revvalues.get(enumval));
+	}
+
+	/**
+	 * @return the class of the enumeration values represented by this dynamic
+	 *         enumeration
+	 */
+	public Class<E> getEnumClass() {
+		return enumclass;
+	}
+
+	/**
+	 * @return the name of the dynamic enumeration collection
+	 */
+	public String getName() {
+		return name;
+	}
+
+}
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/EnumerationValue.java b/src/main/java/org/eclipse/mdm/api/base/model/EnumerationValue.java
new file mode 100644
index 0000000..8fc2803
--- /dev/null
+++ b/src/main/java/org/eclipse/mdm/api/base/model/EnumerationValue.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2017 Florian Schmitt
+ * 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
+ */
+
+package org.eclipse.mdm.api.base.model;
+
+/**
+ * This class emulates the behaviour of a java enum. The reason for its
+ * existence is that classic enums can't be extended by new values. This class
+ * on the other hand can be extended by java's inheritance mechanism.
+ * 
+ * For a basic emulation of java enums, just extend this class and add static
+ * fields whose type is of the derivative class.
+ * 
+ * To be able to add dynamically enum values and for full initialization, you
+ * should set an owner enumeration (either by choosing the right
+ * constructor or by calling the setOwner method)
+ * 
+ * @author Florian Schmitt
+ *
+ */
+public class EnumerationValue {
+
+	private String name;
+	private Integer ordinal;
+
+	private Enumeration<? extends EnumerationValue> owner;
+
+	/**
+	 * explicitly set the name of this element.
+	 * 
+	 * @param name
+	 */
+	protected void setName(String name) {
+		this.name = name;
+	}
+
+	/**
+	 * 
+	 * set the owner dynamic enumeration of this object.
+	 * 
+	 * @param er
+	 */
+	protected void setOwner(Enumeration<? extends EnumerationValue> er) {
+		owner = er;
+	}
+
+	/**
+	 * get the owner dynamic enumeration of this object
+	 * 
+	 * @return
+	 */
+	@SuppressWarnings("rawtypes")
+	public Enumeration getOwner() {
+		return owner;
+	}
+
+	/**
+	 * 
+	 * This Constructor is protected to avoid accidental misuse.
+	 * 
+	 * be sure to initialize the enumeration fully, by either adding it as a
+	 * static field in an extending class, or setting name and ordinal by hand.
+	 * You'll also have to add the resulting object to a DynamiEnumeration for
+	 * it to be completely usable.
+	 */
+	protected EnumerationValue() {
+		this(null, null);
+	}
+
+	/**
+	 * This Constructor is protected to avoid accidental misuse.
+	 * 
+	 * be sure to initialize the enumeration fully, by either adding it as a
+	 * static field in an extending class, or setting the ordinal by hand.
+	 * You'll also have to add the resulting object to a DynamiEnumeration for
+	 * it to be completely usable.
+	 * 
+	 * @param name
+	 */
+	protected EnumerationValue(String name) {
+		this(name, null);
+	}
+
+	/**
+	 * This Constructor is protected to avoid accidental misuse.
+	 * 
+	 * You'll have to add the resulting object to a DynamiEnumeration for it to
+	 * be completely usable.
+	 * 
+	 * @param name
+	 */
+	protected EnumerationValue(String name, Integer ordinal) {
+		this.name = name;
+		this.ordinal = ordinal;
+		this.owner = null;
+	}
+
+	/**
+	 * @return the name of this enumeration value
+	 */
+	public String name() {
+		return name;
+	}
+
+	/**
+	 * @return the enumeration value represented by the given name
+	 */
+	public EnumerationValue valueOf(String name) {
+		return owner.valueOf(name);
+	}
+
+	/**
+	 * @return the ordinal value represented by this enumeration value
+	 */
+	public Integer ordinal() {
+		if (this.ordinal != null) {
+			return this.ordinal;
+		} else {
+			return owner.ordinal(this);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see java.lang.Object#toString()
+	 */
+	@Override
+	public String toString() {
+		return name();
+	}
+
+}
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/Interpolation.java b/src/main/java/org/eclipse/mdm/api/base/model/Interpolation.java
index 339b1c5..932db5f 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/Interpolation.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/Interpolation.java
@@ -15,7 +15,7 @@
  * @author Viktor Stoehr, Gigatronik Ingolstadt GmbH
  * @author Sebastian Dirsch, Gigatronik Ingolstadt GmbH
  */
-public enum Interpolation {
+public class Interpolation extends EnumerationValue {
 
 	// ======================================================================
 	// Enumerations
@@ -24,17 +24,17 @@
 	/**
 	 * No interpolation is used.
 	 */
-	NONE,
+	public static final Interpolation NONE = new Interpolation();
 
 	/**
 	 * Interpolation is linear.
 	 */
-	LINEAR,
+	public static final Interpolation LINEAR = new Interpolation();
 
 	/**
 	 * Interpolation is application specific.
 	 */
-	SPECIFIC;
+	public static final Interpolation SPECIFIC = new Interpolation();
 
 	// ======================================================================
 	// Public methods
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/ScalarType.java b/src/main/java/org/eclipse/mdm/api/base/model/ScalarType.java
index d8638b3..170ff36 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/ScalarType.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/ScalarType.java
@@ -21,7 +21,10 @@
  * @author Viktor Stoehr, Gigatronik Ingolstadt GmbH
  * @author Sebastian Dirsch, Gigatronik Ingolstadt GmbH
  */
-public enum ScalarType {
+
+
+
+public class ScalarType extends EnumerationValue {
 
 	// ======================================================================
 	// Enumerations
@@ -31,96 +34,96 @@
 	 * A {@link MeasuredValues} with this type contains an array sequence of
 	 * {@code String} values.
 	 */
-	STRING(ValueType.STRING_SEQUENCE, String.class),
+	public static final ScalarType STRING = new ScalarType(ValueType.STRING_SEQUENCE, String.class);
 
 	/**
 	 * A {@link MeasuredValues} with this type contains an array sequence of
 	 * {@code LocalDateTime} values.
 	 */
-	DATE(ValueType.DATE_SEQUENCE, LocalDateTime.class),
+	public static final ScalarType DATE = new ScalarType(ValueType.DATE_SEQUENCE, LocalDateTime.class);
 
 	/**
 	 * A {@link MeasuredValues} with this type contains an array sequence of
 	 * {@code boolean} values.
 	 */
-	BOOLEAN(ValueType.BOOLEAN_SEQUENCE, boolean.class),
+	public static final ScalarType BOOLEAN = new ScalarType(ValueType.BOOLEAN_SEQUENCE, boolean.class);
 
 	/**
 	 * A {@link MeasuredValues} with this type contains an array sequence of
 	 * {@code byte} values.
 	 */
-	BYTE(ValueType.BYTE_SEQUENCE, byte.class),
+	public static final ScalarType BYTE = new ScalarType(ValueType.BYTE_SEQUENCE, byte.class);
 
 	/**
 	 * A {@link MeasuredValues} with this type contains an array sequence of
 	 * {@code short} values.
 	 */
-	SHORT(ValueType.SHORT_SEQUENCE, short.class),
+	public static final ScalarType SHORT = new ScalarType(ValueType.SHORT_SEQUENCE, short.class);
 
 	/**
 	 * A {@link MeasuredValues} with this type contains an array sequence of
 	 * {@code int} values.
 	 */
-	INTEGER(ValueType.INTEGER_SEQUENCE, int.class),
+	public static final ScalarType INTEGER = new ScalarType(ValueType.INTEGER_SEQUENCE, int.class);
 
 	/**
 	 * A {@link MeasuredValues} with this type contains an array sequence of
 	 * {@code long} values.
 	 */
-	LONG(ValueType.LONG_SEQUENCE, long.class),
+	public static final ScalarType LONG = new ScalarType(ValueType.LONG_SEQUENCE, long.class);
 
 	/**
 	 * A {@link MeasuredValues} with this type contains an array sequence of
 	 * {@code float} values.
 	 */
-	FLOAT(ValueType.FLOAT_SEQUENCE, float.class),
+	public static final ScalarType FLOAT = new ScalarType(ValueType.FLOAT_SEQUENCE, float.class);
 
 	/**
 	 * A {@link MeasuredValues} with this type contains an array sequence of
 	 * {@code double} values.
 	 */
-	DOUBLE(ValueType.DOUBLE_SEQUENCE, double.class),
+	public static final ScalarType DOUBLE = new ScalarType(ValueType.DOUBLE_SEQUENCE, double.class);
 
 	/**
 	 * A {@link MeasuredValues} with this type contains an array sequence of
 	 * {@code byte[]} values.
 	 */
-	BYTE_STREAM(ValueType.BYTE_STREAM_SEQUENCE, byte[].class),
+	public static final ScalarType BYTE_STREAM = new ScalarType(ValueType.BYTE_STREAM_SEQUENCE, byte[].class);
 
 	/**
 	 * A {@link MeasuredValues} with this type contains an array sequence of
 	 * {@code FloatComplex} values.
 	 */
-	FLOAT_COMPLEX(ValueType.FLOAT_COMPLEX_SEQUENCE, FloatComplex.class),
+	public static final ScalarType FLOAT_COMPLEX = new ScalarType(ValueType.FLOAT_COMPLEX_SEQUENCE, FloatComplex.class);
 
 	/**
 	 * A {@link MeasuredValues} with this type contains an array sequence of
 	 * {@code DoubleComplex} values.
 	 */
-	DOUBLE_COMPLEX(ValueType.DOUBLE_COMPLEX_SEQUENCE, DoubleComplex.class),
+	public static final ScalarType DOUBLE_COMPLEX = new ScalarType(ValueType.DOUBLE_COMPLEX_SEQUENCE, DoubleComplex.class);
 
 	/**
 	 * {@link MeasuredValues} are not allowed to be of this type. This constant
 	 * may be used in other contexts.
 	 */
-	ENUMERATION(ValueType.ENUMERATION_SEQUENCE),
+	public static final ScalarType ENUMERATION = new ScalarType(ValueType.ENUMERATION_SEQUENCE);
 
 	/**
 	 * A {@link MeasuredValues} with this type contains an array sequence of
 	 * {@code FileLink} values.
 	 */
-	FILE_LINK(ValueType.FILE_LINK_SEQUENCE, FileLink.class),
+	public static final ScalarType FILE_LINK = new ScalarType(ValueType.FILE_LINK_SEQUENCE, FileLink.class);
 
 	/**
 	 * TODO ...
 	 */
-	BLOB(ValueType.BLOB, Object.class),
+	public static final ScalarType BLOB = new ScalarType(ValueType.BLOB, Object.class);
 
 	/**
 	 * {@link MeasuredValues} are not allowed to be of this type. This constant
 	 * may be used in other contexts.
 	 */
-	UNKNOWN(ValueType.UNKNOWN);
+	public static final ScalarType UNKNOWN = new ScalarType(ValueType.UNKNOWN);
 
 	// ======================================================================
 	// Instance variables
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/SequenceRepresentation.java b/src/main/java/org/eclipse/mdm/api/base/model/SequenceRepresentation.java
index 2452140..7a45464 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/SequenceRepresentation.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/SequenceRepresentation.java
@@ -16,7 +16,7 @@
  * @author Sebastian Dirsch, Gigatronik Ingolstadt GmbH
  * @see Channel
  */
-public enum SequenceRepresentation {
+public class SequenceRepresentation extends EnumerationValue {
 
 	// ======================================================================
 	// Enumerations
@@ -26,14 +26,14 @@
 	 * Measured values are stored as is and values are therefore immediately
 	 * available.
 	 */
-	EXPLICIT,
+	public static final SequenceRepresentation EXPLICIT = new SequenceRepresentation();
 
 	/**
 	 * Each value x<sub>i</sub> is generated as follows: x<sub>i</sub> = p for i
 	 * &isin; [1, n], n is the total number of values and generation parameter p
 	 * (offset).
 	 */
-	IMPLICIT_CONSTANT,
+	public static final SequenceRepresentation IMPLICIT_CONSTANT = new SequenceRepresentation();
 
 	/**
 	 * Each value x<sub>i</sub> is generated as follows: x<sub>i</sub> =
@@ -41,7 +41,7 @@
 	 * number of values and generation parameters p<sub>1</sub> (start value)
 	 * and p<sub>2</sub> (increment).
 	 */
-	IMPLICIT_LINEAR,
+	public static final SequenceRepresentation IMPLICIT_LINEAR = new SequenceRepresentation();
 
 	/**
 	 * Each value x<sub>i</sub> is generated as follows: x<sub>i</sub> =
@@ -52,7 +52,7 @@
 	 * (p<sub>3</sub>-p<sub>1</sub>)/p<sub>2</sub> must be truncated to integer
 	 * to start each saw curve cycle at p<sub>1</sub>.
 	 */
-	IMPLICIT_SAW,
+	public static final SequenceRepresentation IMPLICIT_SAW = new SequenceRepresentation();
 
 	/**
 	 * Each value x<sub>i</sub> is generated as follows: x<sub>i</sub> =
@@ -60,7 +60,7 @@
 	 * total number of values and generation parameters p<sub>1</sub> (offset),
 	 * p<sub>2</sub> (factor) and the raw value r at position i.
 	 */
-	RAW_LINEAR,
+	public static final SequenceRepresentation RAW_LINEAR = new SequenceRepresentation();
 
 	/**
 	 * Each value x<sub>i</sub> is generated as follows: x<sub>i</sub> = &sum;
@@ -70,13 +70,18 @@
 	 * p<sub>j</sub> for j &isin; [1, p<sub>1</sub>] and the raw value r at
 	 * position i.
 	 */
-	RAW_POLYNOMIAL,
+	public static final SequenceRepresentation RAW_POLYNOMIAL = new SequenceRepresentation();
 
+	/*
+	 * Not used. Do not remove, because this changes the ordinal numbers of the enumeration.
+	 */
+	public static final SequenceRepresentation FORMULA = new SequenceRepresentation();
+	
 	/**
 	 * Measured values are stored as is in an external file and values are
 	 * therefore immediately available.
 	 */
-	EXPLICIT_EXTERNAL,
+	public static final SequenceRepresentation EXPLICIT_EXTERNAL = new SequenceRepresentation();
 
 	/**
 	 * Each value x<sub>i</sub> is generated as follows: x<sub>i</sub> =
@@ -85,7 +90,7 @@
 	 * p<sub>2</sub> (factor) and the raw value r at position i read from an
 	 * external file.
 	 */
-	RAW_LINEAR_EXTERNAL,
+	public static final SequenceRepresentation RAW_LINEAR_EXTERNAL = new SequenceRepresentation();
 
 	/**
 	 * Each value x<sub>i</sub> is generated as follows: x<sub>i</sub> = &sum;
@@ -95,7 +100,7 @@
 	 * p<sub>j</sub> for j &isin; [1, p<sub>1</sub>] and the raw value r at
 	 * position i read from an external file.
 	 */
-	RAW_POLYNOMIAL_EXTERNAL,
+	public static final SequenceRepresentation RAW_POLYNOMIAL_EXTERNAL = new SequenceRepresentation();
 
 	/**
 	 * Each value x<sub>i</sub> is generated as follows: x<sub>i</sub> =
@@ -104,7 +109,7 @@
 	 * p<sub>1</sub> (offset), p<sub>2</sub> (factor), p<sub>2</sub>
 	 * (calibration) and the raw value r at position i.
 	 */
-	RAW_LINEAR_CALIBRATED,
+	public static final SequenceRepresentation RAW_LINEAR_CALIBRATED = new SequenceRepresentation();
 
 	/**
 	 * Each value x<sub>i</sub> is generated as follows: x<sub>i</sub> =
@@ -114,7 +119,7 @@
 	 * (calibration) and the raw value r at position i read from an external
 	 * file.
 	 */
-	RAW_LINEAR_CALIBRATED_EXTERNAL;
+	public static final SequenceRepresentation RAW_LINEAR_CALIBRATED_EXTERNAL = new SequenceRepresentation();
 
 	// ======================================================================
 	// Public methods
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/TypeSpecification.java b/src/main/java/org/eclipse/mdm/api/base/model/TypeSpecification.java
index b94cfd9..9c8dd6c 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/TypeSpecification.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/TypeSpecification.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Gigatronik Ingolstadt GmbH
+ * Copyright (c) 2016 Gigatronik Ingolstadt GmbH 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
@@ -16,86 +16,86 @@
  * @author Sebastian Dirsch, Gigatronik Ingolstadt GmbH
  * @see Channel
  */
-public enum TypeSpecification {
+public class TypeSpecification extends EnumerationValue {
 
 	// ======================================================================
 	// Enumerations
 	// ======================================================================
 
-	BOOLEAN,
+	final static TypeSpecification BOOLEAN = new TypeSpecification();
 
-	BYTE,
+	final static TypeSpecification BYTE = new TypeSpecification();
 
-	SHORT,
+	final static TypeSpecification SHORT = new TypeSpecification();
 
-	INTEGER,
+	final static TypeSpecification INTEGER = new TypeSpecification();
 
-	LONG,
+	final static TypeSpecification LONG = new TypeSpecification();
 
-	FLOAT,
+	final static TypeSpecification FLOAT = new TypeSpecification();
 
-	DOUBLE,
+	final static TypeSpecification DOUBLE = new TypeSpecification();
 
-	SHORT_BEO,
+	final static TypeSpecification SHORT_BEO = new TypeSpecification();
 
-	INTEGER_BEO,
+	final static TypeSpecification INTEGER_BEO = new TypeSpecification();
 
-	LONG_BEO,
+	final static TypeSpecification LONG_BEO = new TypeSpecification();
 
-	FLOAT_BEO,
+	final static TypeSpecification FLOAT_BEO = new TypeSpecification();
 
-	DOUBLE_BEO,
+	final static TypeSpecification DOUBLE_BEO = new TypeSpecification();
 
-	STRING,
+	final static TypeSpecification STRING = new TypeSpecification();
 
-	BYTE_STREAM,
+	final static TypeSpecification BYTE_STREAM = new TypeSpecification();
 
-	BLOB,
+	final static TypeSpecification BLOB = new TypeSpecification();
 
-	BOOLEAN_FLAGS_BEO,
+	final static TypeSpecification BOOLEAN_FLAGS_BEO = new TypeSpecification();
 
-	BYTE_FLAGS_BEO,
+	final static TypeSpecification BYTE_FLAGS_BEO = new TypeSpecification();
 
-	STRING_FLAGS_BEO,
+	final static TypeSpecification STRING_FLAGS_BEO = new TypeSpecification();
 
-	BYTE_STREAM_BEO,
+	final static TypeSpecification BYTE_STREAM_BEO = new TypeSpecification();
 
 	// SBYTE,
-	SIGNED_BYTE,
+	final static TypeSpecification SIGNED_BYTE = new TypeSpecification();
 
 	// SBYTE_FLAGS_BEO,
-	SIGNED_BYTE_FLAGS_BEO,
+	final static TypeSpecification SIGNED_BYTE_FLAGS_BEO = new TypeSpecification();
 
 	// USHORT,
-	UNSIGNED_SHORT,
+	final static TypeSpecification UNSIGNED_SHORT = new TypeSpecification();
 
 	// USHORT_BEO,
-	UNSIGNED_SHORT_BEO,
+	final static TypeSpecification UNSIGNED_SHORT_BEO = new TypeSpecification();
 
 	// UINTEGER,
-	UNSIGNED_INTEGER,
+	final static TypeSpecification UNSIGNED_INTEGER = new TypeSpecification();
 
 	// UINTEGER_BEO,
-	UNSIGNED_INTEGER_BEO,
+	final static TypeSpecification UNSIGNED_INTEGER_BEO = new TypeSpecification();
 
-	STRING_UTF8,
+	final static TypeSpecification STRING_UTF8 = new TypeSpecification();
 
-	STRING_UTF8_FLAGS_BEO,
+	final static TypeSpecification STRING_UTF8_FLAGS_BEO = new TypeSpecification();
 
 	// BIT_INT,
-	BIT_INTEGER,
+	final static TypeSpecification BIT_INTEGER = new TypeSpecification();
 
 	// BIT_INT_BEO,
-	BIT_INTEGER_BEO,
+	final static TypeSpecification BIT_INTEGER_BEO = new TypeSpecification();
 
 	// BIT_UINT,
-	BIT_UNSIGNED_INTEGER,
+	final static TypeSpecification BIT_UNSIGNED_INTEGER = new TypeSpecification();
 
 	// BIT_UINT_BEO,
-	BIT_UNSIGNED_INTEGER_BEO,
+	final static TypeSpecification BIT_UNSIGNED_INTEGER_BEO = new TypeSpecification();
 
-	BIT_FLOAT,
+	final static TypeSpecification BIT_FLOAT = new TypeSpecification();
 
-	BIT_FLOAT_BEO
+	final static TypeSpecification BIT_FLOAT_BEO = new TypeSpecification();
 
 }
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/Value.java b/src/main/java/org/eclipse/mdm/api/base/model/Value.java
index 6849be8..da04ef9 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/Value.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/Value.java
@@ -47,6 +47,7 @@
 	private Object value;
 
 	private final Class<?> valueClass;
+	private final String valueTypeDescr;
 	private final Object defaultValue;
 
 	// ======================================================================
@@ -72,8 +73,9 @@
 	 *            Used as null replacement.
 	 */
 	Value(ValueType valueType, String name, String unit, boolean valid, Object value, Class<?> valueClass,
-			Object defaultValue) {
+			Object defaultValue, String valueTypeDescr) {
 		this.valueType = valueType;
+		this.valueTypeDescr = valueTypeDescr;
 		this.name = name;
 		this.unit = unit == null ? "" : unit;
 
@@ -99,7 +101,7 @@
 	 *            The new value.
 	 */
 	private Value(Value origin, Object input) {
-		this(origin.valueType, origin.name, origin.unit, origin.valid, input, origin.valueClass, origin.defaultValue);
+		this(origin.valueType, origin.name, origin.unit, origin.valid, input, origin.valueClass, origin.defaultValue, origin.valueTypeDescr);
 	}
 
 	// ======================================================================
@@ -193,6 +195,22 @@
 		} else if (valueClass.isInstance(input)) {
 			value = input;
 			setValid(true);
+		} else if (input instanceof EnumerationValue) {
+			String inpvalueTypeDescr = ((EnumerationValue)input).getOwner().getName();
+		    if (inpvalueTypeDescr==null) {
+		    	throw new IllegalArgumentException("EnumerationValue value description of input value not correctly initialized");
+		    }
+			if (valueTypeDescr==null)
+				throw new IllegalArgumentException("EnumerationValue value description not correctly initialized got null, '"
+						+ "' expected '" + valueClass.getSimpleName() + "'.");
+		
+		    if (valueTypeDescr.equals(inpvalueTypeDescr)){
+		       value=input;
+		       setValid(true);
+		    } else {
+		    	throw new IllegalArgumentException("Incompatible value type description'" + inpvalueTypeDescr  
+						+ "' passed, expected '" + valueTypeDescr + "'.");
+		    }
 		} else {
 			throw new IllegalArgumentException("Incompatible value type '" + input.getClass().getSimpleName()
 					+ "' passed, expected '" + valueClass.getSimpleName() + "'.");
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/ValueType.java b/src/main/java/org/eclipse/mdm/api/base/model/ValueType.java
index 0861aa7..2ad9cc6 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/ValueType.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/ValueType.java
@@ -18,7 +18,7 @@
  * @author Viktor Stoehr, Gigatronik Ingolstadt GmbH

  * @author Sebastian Dirsch, Gigatronik Ingolstadt GmbH

  */

-public enum ValueType {

+public class ValueType extends EnumerationValue {

 

 	// ======================================================================

 	// Enumerations

@@ -28,145 +28,145 @@
 	 * A {@link Value} with this type contains a {@code String} value and

 	 * replaces {@code null} with an empty {@code String}.

 	 */

-	STRING(String.class, ""),

+	public static final ValueType STRING = new ValueType(String.class, "");

 

 	/**

 	 * A {@link Value} with this type contains a {@code String[]} value replaces

 	 * {@code null} with an empty {@code String} array.

 	 */

-	STRING_SEQUENCE(String[].class, new String[0]),

+	public static final ValueType STRING_SEQUENCE = new ValueType(String[].class, new String[0]);

 

 	/**

 	 * A {@link Value} with this type contains a {@link LocalDateTime} value and

 	 * does not replace {@code null}.

 	 */

-	DATE(LocalDateTime.class, null),

+	public static final ValueType DATE = new ValueType(LocalDateTime.class, null);

 

 	/**

 	 * A {@link Value} with this type contains a {@code LocalDateTime[]} value

 	 * and replaces {@code null} with an empty {@code LocalDateTime} array.

 	 */

-	DATE_SEQUENCE(LocalDateTime[].class, new LocalDateTime[0]),

+	public static final ValueType DATE_SEQUENCE = new ValueType(LocalDateTime[].class, new LocalDateTime[0]);

 

 	/**

 	 * A {@link Value} with this type contains a {@link Boolean} value and

 	 * replaces {@code null} with {@link Boolean#FALSE}.

 	 */

-	BOOLEAN(Boolean.class, Boolean.FALSE),

+	public static final ValueType BOOLEAN = new ValueType(Boolean.class, Boolean.FALSE);

 

 	/**

 	 * A {@link Value} with this type contains a {@code boolean[]} value and

 	 * replaces {@code null} with an empty {@code boolean} array.

 	 */

-	BOOLEAN_SEQUENCE(boolean[].class, new boolean[0]),

+	public static final ValueType BOOLEAN_SEQUENCE = new ValueType(boolean[].class, new boolean[0]);

 

 	/**

 	 * A {@link Value} with this type contains a {@link Byte} value and replaces

 	 * {@code null} with a {@code Byte} containing zero.

 	 */

-	BYTE(Byte.class, Byte.valueOf((byte) 0)),

+	public static final ValueType BYTE = new ValueType(Byte.class, Byte.valueOf((byte) 0));

 

 	/**

 	 * A {@link Value} with this type contains a {@code byte[]} value and

 	 * replaces {@code null} with an empty {@code byte} array.

 	 */

-	BYTE_SEQUENCE(byte[].class, new byte[0]),

+	public static final ValueType BYTE_SEQUENCE = new ValueType(byte[].class, new byte[0]);

 

 	/**

 	 * A {@link Value} with this type contains a {@link Short} value and

 	 * replaces {@code null} with a {@code Short} containing zero.

 	 */

-	SHORT(Short.class, Short.valueOf((short) 0)),

+	public static final ValueType SHORT = new ValueType(Short.class, Short.valueOf((short) 0));

 

 	/**

 	 * A {@link Value} with this type contains a {@code short[]} value and

 	 * replaces {@code null} with an empty {@code short} array.

 	 */

-	SHORT_SEQUENCE(short[].class, new short[0]),

+	public static final ValueType SHORT_SEQUENCE = new ValueType(short[].class, new short[0]);

 

 	/**

 	 * A {@link Value} with this type contains a {@link Integer} value and

 	 * replaces {@code null} with a {@code Integer} containing zero.

 	 */

-	INTEGER(Integer.class, Integer.valueOf(0)),

+	public static final ValueType INTEGER = new ValueType(Integer.class, Integer.valueOf(0));

 

 	/**

 	 * A {@link Value} with this type contains a {@code int[]} value and

 	 * replaces {@code null} with an empty {@code int} array.

 	 */

-	INTEGER_SEQUENCE(int[].class, new int[0]),

+	public static final ValueType INTEGER_SEQUENCE = new ValueType(int[].class, new int[0]);

 

 	/**

 	 * A {@link Value} with this type contains a {@link Long} value and replaces

 	 * {@code null} with a {@code Long} containing zero.

 	 */

-	LONG(Long.class, Long.valueOf(0)),

+	public static final ValueType LONG = new ValueType(Long.class, Long.valueOf(0));

 

 	/**

 	 * A {@link Value} with this type contains a {@code long[]} value and

 	 * replaces {@code null} with an empty {@code long} array.

 	 */

-	LONG_SEQUENCE(long[].class, new long[0]),

+	public static final ValueType LONG_SEQUENCE = new ValueType(long[].class, new long[0]);

 

 	/**

 	 * A {@link Value} with this type contains a {@link Float} value and

 	 * replaces {@code null} with a {@code Float} containing zero.

 	 */

-	FLOAT(Float.class, Float.valueOf(0)),

+	public static final ValueType FLOAT = new ValueType(Float.class, Float.valueOf(0));

 

 	/**

 	 * A {@link Value} with this type contains a {@code float[]} value and

 	 * replaces {@code null} with an empty {@code float} array.

 	 */

-	FLOAT_SEQUENCE(float[].class, new float[0]),

+	public static final ValueType FLOAT_SEQUENCE = new ValueType(float[].class, new float[0]);

 

 	/**

 	 * A {@link Value} with this type contains a {@link Double} value and

 	 * replaces {@code null} with a {@code Double} containing zero.

 	 */

-	DOUBLE(Double.class, Double.valueOf(0)),

+	public static final ValueType DOUBLE = new ValueType(Double.class, Double.valueOf(0));

 

 	/**

 	 * A {@link Value} with this type contains a {@code double[]} value and

 	 * replaces {@code null} with an empty {@code double} array.

 	 */

-	DOUBLE_SEQUENCE(double[].class, new double[0]),

+	public static final ValueType DOUBLE_SEQUENCE = new ValueType(double[].class, new double[0]);

 

 	/**

 	 * A {@link Value} with this type contains a {@code byte[]} value and

 	 * replaces {@code null} with an empty {@code byte} array.

 	 */

-	BYTE_STREAM(byte[].class, new byte[0]),

+	public static final ValueType BYTE_STREAM = new ValueType(byte[].class, new byte[0]);

 

 	/**

 	 * A {@link Value} with this type contains a {@code byte[][]} value and

 	 * replaces {@code null} with an empty {@code byte[][]} array.

 	 */

-	BYTE_STREAM_SEQUENCE(byte[][].class, new byte[0][]),

+	public static final ValueType BYTE_STREAM_SEQUENCE = new ValueType(byte[][].class, new byte[0][]);

 

 	/**

 	 * A {@link Value} with this type contains a {@link FloatComplex} value and

 	 * does not replaces {@code null}.

 	 */

-	FLOAT_COMPLEX(FloatComplex.class, null),

+	public static final ValueType FLOAT_COMPLEX = new ValueType(FloatComplex.class, null);

 

 	/**

 	 * A {@link Value} with this type contains a {@code FloatComplex[]} value

 	 * and replaces {@code null} with an empty {@code FloatComplex[]} array.

 	 */

-	FLOAT_COMPLEX_SEQUENCE(FloatComplex[].class, new FloatComplex[0]),

+	public static final ValueType FLOAT_COMPLEX_SEQUENCE = new ValueType(FloatComplex[].class, new FloatComplex[0]);

 

 	/**

 	 * A {@link Value} with this type contains a {@link DoubleComplex} value and

 	 * does not replaces {@code null}.

 	 */

-	DOUBLE_COMPLEX(DoubleComplex.class, null),

+	public static final ValueType DOUBLE_COMPLEX = new ValueType(DoubleComplex.class, null);

 

 	/**

 	 * A {@link Value} with this type contains a {@code DoubleComplex[]} value

 	 * and replaces {@code null} with an empty {@code DoubleComplex[]} array.

 	 */

-	DOUBLE_COMPLEX_SEQUENCE(DoubleComplex[].class, new DoubleComplex[0]),

+	public static final ValueType DOUBLE_COMPLEX_SEQUENCE = new ValueType(DoubleComplex[].class, new DoubleComplex[0]);

 

 	/**

 	 * A {@link Value} with this type contains a modeled enumeration constant

@@ -175,7 +175,7 @@
 	 * @see #create(Class, String)

 	 * @see #create(Class, String, String, boolean, Object)

 	 */

-	ENUMERATION,

+	public static final ValueType ENUMERATION = new ValueType();

 

 	/**

 	 * A {@link Value} with this type contains a modeled enumeration constant

@@ -185,31 +185,31 @@
 	 * @see #create(Class, String)

 	 * @see #create(Class, String, String, boolean, Object)

 	 */

-	ENUMERATION_SEQUENCE,

+	public static final ValueType ENUMERATION_SEQUENCE = new ValueType();

 

 	/**

 	 * A {@link Value} with this type contains a {@link FileLink} value and does

 	 * not replace {@code null}.

 	 */

-	FILE_LINK(FileLink.class, null),

+	public static final ValueType FILE_LINK = new ValueType(FileLink.class, null);

 

 	/**

 	 * A {@link Value} with this type contains a {@code FileLink[]} value and

 	 * replaces {@code null} with an empty {@code FileLink} array.

 	 */

-	FILE_LINK_SEQUENCE(FileLink[].class, new FileLink[0]),

+	public static final ValueType FILE_LINK_SEQUENCE = new ValueType(FileLink[].class, new FileLink[0]);

 

 	/**

 	 * TODO ...

 	 */

-	BLOB(Object.class, null),

+	public static final ValueType BLOB  = new ValueType(Object.class, null);

 

 	/**

 	 * A {@link Value} with this type contains a {@link Object} value and does

 	 * not replace {@code null}. This value type does not have a corresponding

 	 * sequence type.

 	 */

-	UNKNOWN;

+	public static final ValueType UNKNOWN  = new ValueType();

 

 	// ======================================================================

 	// Instance variables

@@ -323,7 +323,7 @@
 			throw new IllegalStateException("This value type is an enumeration type.");

 		}

 

-		return new Value(this, name, unit, valid, input, type, defaultValue);

+		return new Value(this, name, unit, valid, input, type, defaultValue, null);

 	}

 

 	/**

@@ -347,8 +347,8 @@
 	 * @throws IllegalStateException

 	 *             Thrown if {@link #isEnumerationType()} returns {@code false}.

 	 */

-	public <E extends Enum<?>> Value create(Class<E> enumClass, String name) {

-		return create(enumClass, name, "", false, null);

+	public <E extends EnumerationValue> Value create(Enumeration<?> enumObj, String name) {

+		return create(enumObj, name, "", false, null, enumObj.getName());

 	}

 

 	/**

@@ -374,16 +374,16 @@
 	 * @throws IllegalStateException

 	 *             Thrown if {@link #isEnumerationType()} returns {@code false}.

 	 */

-	public <E extends Enum<?>> Value create(Class<E> enumClass, String name, String unit, boolean valid, Object input) {

+	public <E extends EnumerationValue> Value create(Enumeration<?> enumObj, String name, String unit, boolean valid, Object input, String valueTypeDescr) {

 		if (isEnumerationType()) {

 			Object nullReplacement = null;

-			Class<?> valueClass = enumClass;

+			Class<?> valueClass = enumObj.getClass();

 			if (isSequence()) {

-				nullReplacement = Array.newInstance(enumClass, 0);

+				nullReplacement = Array.newInstance(valueClass, 0);

 				valueClass = nullReplacement.getClass();

 			}

 

-			return new Value(this, name, unit, valid, input, valueClass, nullReplacement);

+			return new Value(this, name, unit, valid, input, valueClass, nullReplacement, valueTypeDescr);

 		}

 

 		throw new IllegalStateException("This value type is not an enumeration type.");

@@ -990,29 +990,39 @@
 	/**

 	 * Returns the sequence version of this value type. This method returns

 	 * itself, if this value type is a sequence type.

+	 * 

+	 * If you extend the class ValueType, you have to ensure that T contains a field 

+	 * of the correct name and type,

+	 * otherwise a runtime error will occur. 

 	 *

 	 * @return The sequence version of this value type is returned.

 	 */

-	public ValueType toSequenceType() {

+	@SuppressWarnings("unchecked")

+	public <T extends ValueType> T toSequenceType() {

 		if (isSequence()) {

-			return this;

+			return (T)this;

 		}

 

-		return ValueType.valueOf(name() + "_SEQUENCE");

+		return (T)valueOf(name() + "_SEQUENCE");

 	}

 

 	/**

 	 * Returns the scalar version of this value type. This method returns

 	 * itself, if this value type is a scalar type.

+	 * 

+	 * If you extend the class ValueType, you have to ensure that T 

+	 * contains a field of the correct name and type,

+	 * otherwise a runtime error will occur. 

 	 *

 	 * @return The sequence version of this value type is returned.

 	 */

-	public ValueType toSingleType() {

+	@SuppressWarnings("unchecked")

+	public <T extends ValueType> T toSingleType() {

 		if (isSequence()) {

-			return ValueType.valueOf(name().replace("_SEQUENCE", ""));

+			return (T)valueOf(name().replace("_SEQUENCE", ""));

 		}

 

-		return this;

+		return (T)this;

 	}

 

 	/**

@@ -1029,4 +1039,5 @@
 		return type;

 	}

 

+

 }

diff --git a/src/main/java/org/eclipse/mdm/api/base/model/VersionState.java b/src/main/java/org/eclipse/mdm/api/base/model/VersionState.java
index f2c1606..9d242ab 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/VersionState.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/VersionState.java
@@ -16,7 +16,7 @@
  * @author Sebastian Dirsch, Gigatronik Ingolstadt GmbH
  * @see FileLink
  */
-public enum VersionState {
+public class VersionState extends EnumerationValue {
 
 	// ======================================================================
 	// Enumerations
@@ -26,7 +26,7 @@
 	 * An entity with this version state is still editable and hence not allowed
 	 * be used when creating new entities.
 	 */
-	EDITABLE,
+	public static final VersionState EDITABLE = new VersionState(); 
 
 	/**
 	 * An entity with this version state is no longer editable and is allowed to
@@ -36,7 +36,7 @@
 	 * <b>Note:</b> If an entity's version state is this state, then its version
 	 * state is only allowed to be changed to {@link #ARCHIVED}.
 	 */
-	VALID,
+	public static final VersionState VALID = new VersionState(); 
 
 	/**
 	 * An entity with this version state is neither editable nor is it allowed
@@ -46,7 +46,7 @@
 	 * <b>Note:</b> If an entity's version state is this state, then its version
 	 * state is no longer allowed to be changed.
 	 */
-	ARCHIVED;
+	public static final VersionState ARCHIVED = new VersionState(); 
 
 	// ======================================================================
 	// Public methods
diff --git a/src/main/java/org/eclipse/mdm/api/base/query/Attribute.java b/src/main/java/org/eclipse/mdm/api/base/query/Attribute.java
index 395d07d..e8816b1 100644
--- a/src/main/java/org/eclipse/mdm/api/base/query/Attribute.java
+++ b/src/main/java/org/eclipse/mdm/api/base/query/Attribute.java
@@ -8,6 +8,7 @@
 
 package org.eclipse.mdm.api.base.query;
 
+import org.eclipse.mdm.api.base.model.Enumeration;
 import org.eclipse.mdm.api.base.model.Value;
 import org.eclipse.mdm.api.base.model.ValueType;
 
@@ -66,7 +67,7 @@
 	 *             neither {@link ValueType#ENUMERATION} nor
 	 *             {@link ValueType#ENUMERATION_SEQUENCE}.
 	 */
-	Class<? extends Enum<?>> getEnumClass();
+	Enumeration<?> getEnumObj();
 
 	/**
 	 * Creates a new and empty {@link Value}.
@@ -76,7 +77,7 @@
 	default Value createValue() {
 		ValueType valueType = getValueType();
 		if (valueType.isEnumerationType()) {
-			return valueType.create(getEnumClass(), getName());
+			return valueType.create(getEnumObj(), getName());
 		} else {
 			return valueType.create(getName());
 		}
@@ -119,7 +120,7 @@
 	default Value createValueSeq(String unit, Object input) {
 		ValueType valueType = getValueType().toSequenceType();
 		if (valueType.isEnumerationType()) {
-			return valueType.create(getEnumClass(), getName(), unit, true, input);
+			return valueType.create(getEnumObj(), getName(), unit, true, input, getEnumObj().getName());
 		} else {
 			return valueType.create(getName(), unit, true, input);
 		}
@@ -140,7 +141,7 @@
 	default Value createValue(String unit, boolean valid, Object input) {
 		ValueType valueType = getValueType();
 		if (valueType.isEnumerationType()) {
-			return valueType.create(getEnumClass(), getName(), unit, valid, input);
+			return valueType.create(getEnumObj(), getName(), unit, valid, input, getEnumObj().getName());
 		} else {
 			return valueType.create(getName(), unit, valid, input);
 		}
diff --git a/src/test/java/org/eclipse/mdm/api/base/AttributeImpl.java b/src/test/java/org/eclipse/mdm/api/base/AttributeImpl.java
index 3d18778..05d3253 100755
--- a/src/test/java/org/eclipse/mdm/api/base/AttributeImpl.java
+++ b/src/test/java/org/eclipse/mdm/api/base/AttributeImpl.java
@@ -8,6 +8,7 @@
 

 package org.eclipse.mdm.api.base;

 

+import org.eclipse.mdm.api.base.model.Enumeration;

 import org.eclipse.mdm.api.base.model.ValueType;

 import org.eclipse.mdm.api.base.query.Attribute;

 import org.eclipse.mdm.api.base.query.EntityType;

@@ -50,7 +51,7 @@
 	}

 

 	@Override

-	public Class<? extends Enum<?>> getEnumClass() {

+	public Enumeration<?> getEnumObj() {

 		throw new UnsupportedOperationException();

 	}

 }

diff --git a/src/test/java/org/eclipse/mdm/api/base/model/ModelTest.java b/src/test/java/org/eclipse/mdm/api/base/model/ModelTest.java
index 5102f31..f8e49a3 100755
--- a/src/test/java/org/eclipse/mdm/api/base/model/ModelTest.java
+++ b/src/test/java/org/eclipse/mdm/api/base/model/ModelTest.java
@@ -55,7 +55,7 @@
 	public void parameterValue() {
 		Map<String, Value> map = new HashMap<String, Value>();
 		map.put("DataType", new Value(ValueType.STRING, "DataType", null, true, ScalarType.FLOAT, ScalarType.class,
-				ScalarType.FLOAT));
+				ScalarType.FLOAT, EnumRegistry.SCALAR_TYPE));
 		map.put("Value", ValueType.STRING.create("Value", null, true, "5.7"));
 		map.put("Name", ValueType.STRING.create("Name", null, true, "paramname"));
 		Core core = new CoreImpl(map);
@@ -152,7 +152,7 @@
 	public void getQuantity() {
 		Map<String, Value> map = new HashMap<String, Value>();
 		map.put("DefDataType", new Value(ValueType.ENUMERATION, "name", "unit", true, ScalarType.FLOAT,
-				ScalarType.class, ScalarType.FLOAT));
+				ScalarType.class, ScalarType.FLOAT, EnumRegistry.SCALAR_TYPE));
 		Core core = new CoreImpl(map);
 		Quantity quantity = new Quantity(core);
 		ScalarType defaultScalarType = quantity.getDefaultScalarType();
@@ -193,7 +193,7 @@
 		map.put("Current", ValueType.INTEGER.create("Length", null, true, 0));
 		map.put("MolarAmount", ValueType.INTEGER.create("Length", null, true, 0));
 		map.put("LuminousIntensity", ValueType.INTEGER.create("Length", null, true, 0));
-		// TODO: check if angle in lower case is correct
+		// TODO (Florian Schmitt): check if angle in lower case is correct
 		map.put("angle", ValueType.INTEGER.create("Length", null, true, 0));
 		Core core = new CoreImpl(map);
 		EntityFactoryImpl ef = new EntityFactoryImpl(core);
@@ -216,9 +216,9 @@
 		map.put("DefTypeSize", ValueType.INTEGER.create("DefTypeSize", null, true, 8));
 		map.put("DefMQName", ValueType.STRING.create("DefMQName", null, true, "mqname"));
 		map.put("DefDataType", new Value(ValueType.ENUMERATION, "DefDataType", "", true, ScalarType.DOUBLE,
-				ScalarType.class, ScalarType.DOUBLE));
+				ScalarType.class, ScalarType.DOUBLE, EnumRegistry.SCALAR_TYPE));
 		map.put("ValidFlag", new Value(ValueType.ENUMERATION, "ValidFlag", "", false, VersionState.ARCHIVED,
-				VersionState.class, null));
+				VersionState.class, null, EnumRegistry.VERSION_STATE));
 		map.put("Description", ValueType.STRING.create("Description", null, true, null));
 		core = new CoreImpl(map);
 		ef = new EntityFactoryImpl(core);
@@ -256,9 +256,11 @@
 		map = new HashMap<String, Value>();
 		map.put("Name", ValueType.STRING.create("Name", null, true, null));
 		map.put("Description", ValueType.STRING.create("Description", null, true, null));
-		map.put("Interpolation",
-				new Value(ValueType.ENUMERATION, "Interpolation", "", true, null, Interpolation.class, null));
-		map.put("DataType", new Value(ValueType.ENUMERATION, "DataType", "", true, null, ScalarType.class, null));
+		map.put("Interpolation", new Value(ValueType.ENUMERATION, "Interpolation", "", true, null, Interpolation.class,
+				null, EnumRegistry.SCALAR_TYPE));
+		map.put("DataType", new Value(ValueType.ENUMERATION, "DataType", "", true, null, ScalarType.class, null,
+				EnumRegistry.SCALAR_TYPE));
+
 		map.put("TypeSize", ValueType.INTEGER.create("TypeSize", null, true, null));
 		map.put("Rank", ValueType.INTEGER.create("Rank", null, true, null));
 		core = new CoreImpl(map);
@@ -272,8 +274,12 @@
 	 */
 	@org.junit.Test
 	public void valueType() {
+		EnumRegistry.getInstance();
 		assertEquals(ValueType.SHORT_SEQUENCE.toSingleType(), ValueType.SHORT);
 		assertEquals(ValueType.DATE.toSequenceType(), ValueType.DATE_SEQUENCE);
+		assertEquals(ValueType.ENUMERATION_SEQUENCE.toSingleType(), ValueType.ENUMERATION);
+		assertEquals(ValueType.ENUMERATION.toSingleType(), ValueType.ENUMERATION);
+		assertEquals(ValueType.ENUMERATION, ValueType.ENUMERATION.valueOf(ValueType.ENUMERATION.toSingleType().name()));
 		assertEquals(Float.class, ValueType.FLOAT.getValueClass());
 		assertEquals(true, ValueType.DOUBLE.isAnyFloatType());
 		assertEquals(true, ValueType.DOUBLE.isDouble());
@@ -305,6 +311,12 @@
 		assertTrue(SequenceRepresentation.EXPLICIT_EXTERNAL.isExplicit());
 		assertTrue(SequenceRepresentation.EXPLICIT_EXTERNAL.isExternal());
 		assertFalse(SequenceRepresentation.EXPLICIT_EXTERNAL.isImplicit());
+		assertEquals(SequenceRepresentation.EXPLICIT.ordinal(), (Integer) 0);
+		assertEquals((Integer) 5, SequenceRepresentation.RAW_POLYNOMIAL.ordinal());
+		assertEquals((Integer) 7, SequenceRepresentation.EXPLICIT_EXTERNAL.ordinal());
+		assertEquals((Integer) 9, SequenceRepresentation.RAW_POLYNOMIAL_EXTERNAL.ordinal());
+		assertEquals((Integer) 10, SequenceRepresentation.RAW_LINEAR_CALIBRATED.ordinal());
+		assertEquals((Integer) 11, SequenceRepresentation.RAW_LINEAR_CALIBRATED_EXTERNAL.ordinal());
 	}
 
 	/**
@@ -352,5 +364,15 @@
 	public void interpolation() {
 		assertTrue(Interpolation.LINEAR.isLinear());
 		assertFalse(Interpolation.NONE.isSpecific());
+		assertEquals(Interpolation.NONE.ordinal(), (Integer) 0);
+		assertEquals(Interpolation.LINEAR.ordinal(), (Integer) 1);
+		assertEquals(Interpolation.SPECIFIC.ordinal(), (Integer) 2);
 	}
+
+	@org.junit.Test
+	public void enumRegistry() {
+		EnumRegistry er = EnumRegistry.getInstance();
+		assertTrue(er.get("Interpolation") instanceof Enumeration<?>);
+	}
+
 }