Merge branch 'dev'
diff --git a/build.gradle b/build.gradle
index 32a0ab1..45038ed 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,139 +1,149 @@
-/*

- * Copyright (c) 2016 Gigatronik Ingolstadt GmbH

- * 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

- */

-

-description = 'MDM API - ODSAdapter'

-group = 'org.eclipse.mdm'

-version = '1.0.0'

-

-apply plugin: 'java'

-apply plugin: 'maven'

-apply plugin: 'eclipse'

-apply plugin: 'com.google.protobuf'

-

-buildscript {

-    repositories {

-        mavenCentral()

-    }

-    dependencies {

-        classpath 'com.google.protobuf:protobuf-gradle-plugin:0.7.7'

-    }

-}

-

-repositories {

-	jcenter()

-	mavenLocal()

-    mavenCentral()

-}

-

-sourceSets {

-    generated {

-        java {

-            srcDir 'src/gen/java'

-            srcDir 'build/generated/source/proto/main/java'

-        }

-    }

-    

-    main {

-        compileClasspath += generated.output

-        runtimeClasspath += generated.output

-    }

-    

-    test {

-        compileClasspath += generated.output

-        runtimeClasspath += generated.output

-    }

-}

-

-dependencies {

-	compile 'javax:javaee-api:7.0'

-

-	// logging	

-	compile 'org.slf4j:slf4j-api:1.7.19'

-	

-	// MDM5 API

-	compile 'org.eclipse.mdm:org.eclipse.mdm.api.base:1.0.0'

-	compile 'org.eclipse.mdm:org.eclipse.mdm.api.default:1.0.0'

-	

-	// compile CORBA idl using JDK tools

-    generatedCompile files(System.getenv('JAVA_HOME') + '/lib/tools.jar')

-    

-    	// Peak notification service

- 	compile 'com.google.protobuf:protobuf-java:3.0.0-beta-3'

- 	compile 'com.google.protobuf:protobuf-java-util:3.0.0-beta-3'

-	compile 'com.google.guava:guava:18.0'

- 	compile 'org.glassfish.jersey.core:jersey-client:2.23.1'

- 	compile 'org.glassfish.jersey.media:jersey-media-sse:2.23.1'

-    

-     	// Avalon notification service

- 	compile 'org.jacorb:jacorb-services:3.8'

-    

-    // querying es

-	compile 'commons-httpclient:commons-httpclient:3.1'

-	compile 'org.apache.commons:commons-lang3:3.4'

-    

-    // testing

-    testCompile 'junit:junit:4.12'

-	testRuntime 'org.slf4j:slf4j-simple:1.7.19'

-	testCompile 'org.mockito:mockito-core:1.+'

-	  testCompile 'org.assertj:assertj-core:3.6.2'

-  	testCompile(group: 'org.elasticsearch', name: 'elasticsearch', version: '2.3.4')

-	testCompile(group: 'org.elasticsearch', name: 'elasticsearch', version: '2.3.4', classifier: 'tests')

-}

-

-test {

-    if(project.hasProperty('host')) {

-        systemProperty 'host', project.property('host')

-    } else {

-        systemProperty 'host', '<host>'

-    }

-    

-    if(project.hasProperty('port')) {

-        systemProperty 'port', project.property('port')

-    } else {

-        systemProperty 'port', '2809'

-    }

-    

-    if(project.hasProperty('service')) {

-        systemProperty 'service', project.property('service')

-    } else {

-        systemProperty 'service', '<service>'

-    }

-    

-	jvmArgs '-Dorg.slf4j.simpleLogger.defaultLogLevel=debug'

-}

-

-protobuf {

-  protoc {

-    artifact = 'com.google.protobuf:protoc:3.0.0-beta-3'

-  }

-}

-

-

-task compileIDL(type: JavaExec) {

-    classpath = configurations.generatedCompile

-

-    main = 'com.sun.tools.corba.se.idl.toJavaPortable.Compile'

-    

- 	// add 'fallTIE' if <Type>POA & <Type>POATie have to be generated   

-    args '-td', 'src/gen/java/', 'src/main/idl/ods530.idl'

-}

-

-// generate classes from idl and compile them

-compileGeneratedJava.dependsOn compileIDL

-compileJava.dependsOn compileGeneratedJava

-

-jar {

-    from sourceSets.generated.output

-    dependsOn generatedClasses

-}

-

-task deleteGenerated(type: Delete) {

-    delete 'src/gen/java/org'

-}

-

-clean.dependsOn deleteGenerated
\ No newline at end of file
+/*
+ * Copyright (c) 2016 Gigatronik Ingolstadt GmbH
+ * 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
+ */
+
+description = 'MDM API - ODSAdapter'
+group = 'org.eclipse.mdm'
+version = '1.0.0'
+
+apply plugin: 'java'
+apply plugin: 'maven'
+apply plugin: 'eclipse'
+apply plugin: 'com.google.protobuf'
+
+buildscript {
+	repositories {
+		mavenCentral()
+	}
+	dependencies {
+		classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.1'
+	}
+}
+
+repositories {
+	jcenter()
+	mavenLocal()
+	mavenCentral()
+}
+
+sourceSets {
+
+	generated {
+		java {
+			srcDir 'src/gen/java'
+			srcDir 'build/generated/source/proto/main/java'
+		}
+	}
+
+	main {
+		compileClasspath += generated.output
+		runtimeClasspath += generated.output
+	}
+
+	test {
+		compileClasspath += generated.output
+		runtimeClasspath += generated.output
+	}
+}
+
+dependencies {
+	compile 'javax:javaee-api:7.0'
+
+	// logging	
+	compile 'org.slf4j:slf4j-api:1.7.19'
+	
+	// MDM5 API
+	compile 'org.eclipse.mdm:org.eclipse.mdm.api.base:1.0.0'
+	compile 'org.eclipse.mdm:org.eclipse.mdm.api.default:1.0.0'
+	
+	// compile CORBA idl using JDK tools
+	generatedCompile files(System.getenv('JAVA_HOME') + '/lib/tools.jar')
+
+	// Peak notification service
+	compile 'com.google.protobuf:protobuf-java:3.0.0-beta-3'
+	compile 'com.google.protobuf:protobuf-java-util:3.0.0-beta-3'
+	compile 'com.google.guava:guava:18.0'
+	compile 'org.glassfish.jersey.core:jersey-client:2.23.1'
+	compile 'org.glassfish.jersey.media:jersey-media-sse:2.23.1'
+	generatedCompile 'com.google.protobuf:protobuf-java:3.0.0-beta-3'
+
+	// Avalon notification service
+	compile 'org.jacorb:jacorb-services:3.8'
+
+	// querying es
+	compile 'commons-httpclient:commons-httpclient:3.1'
+	compile 'org.apache.commons:commons-lang3:3.4'
+
+	// testing
+	testCompile 'junit:junit:4.12'
+	testRuntime 'org.slf4j:slf4j-simple:1.7.19'
+	testCompile 'org.mockito:mockito-core:1.+'
+	testCompile 'org.assertj:assertj-core:3.6.2'
+	testCompile(group: 'org.elasticsearch', name: 'elasticsearch', version: '2.3.4')
+	testCompile(group: 'org.elasticsearch', name: 'elasticsearch', version: '2.3.4', classifier: 'tests')
+}
+
+test {
+	if(project.hasProperty('host')) {
+		systemProperty 'host', project.property('host')
+	} else {
+		systemProperty 'host', '<host>'
+	}
+
+	if(project.hasProperty('port')) {
+		systemProperty 'port', project.property('port')
+	} else {
+		systemProperty 'port', '2809'
+	}
+	
+	if(project.hasProperty('service')) {
+		systemProperty 'service', project.property('service')
+	} else {
+		systemProperty 'service', '<service>'
+	}
+
+	jvmArgs '-Dorg.slf4j.simpleLogger.defaultLogLevel=debug'
+}
+
+protobuf {
+	protoc {
+		artifact = 'com.google.protobuf:protoc:3.0.0-beta-3'
+	}
+}
+
+
+task compileIDL(type: JavaExec) {
+	classpath = configurations.generatedCompile
+
+	main = 'com.sun.tools.corba.se.idl.toJavaPortable.Compile'
+
+	// add 'fallTIE' if <Type>POA & <Type>POATie have to be generated   
+	args '-td', 'src/gen/java/', 'src/main/idl/ods530.idl'
+
+	outputs.dir("src/gen/java")
+}
+
+compileGeneratedJava {
+	inputs.dir("build/generated/source")
+	inputs.dir("src/gen/java")
+}
+
+// generate classes from idl and compile them
+compileGeneratedJava.dependsOn compileIDL
+compileJava.dependsOn compileGeneratedJava
+
+jar {
+	from sourceSets.generated.output
+	dependsOn generatedClasses
+}
+
+task deleteGenerated(type: Delete) {
+	delete 'src/gen'
+	delete 'build'
+}
+
+clean.dependsOn deleteGenerated
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 217ac1e..e27e7c3 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -3,5 +3,5 @@
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
-distributionUrl=https://services.gradle.org/distributions/gradle-2.13-bin.zip
+distributionUrl=https://services.gradle.org/distributions/gradle-4.1-bin.zip
 
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/ODSEntityManager.java b/src/main/java/org/eclipse/mdm/api/odsadapter/ODSEntityManager.java
index bb24acf..b62782e 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/ODSEntityManager.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/ODSEntityManager.java
@@ -9,6 +9,7 @@
 package org.eclipse.mdm.api.odsadapter;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.EnumMap;
 import java.util.List;
@@ -35,7 +36,7 @@
 import org.eclipse.mdm.api.base.query.DataAccessException;
 import org.eclipse.mdm.api.base.query.EntityType;
 import org.eclipse.mdm.api.base.query.Filter;
-import org.eclipse.mdm.api.base.query.Join;
+import org.eclipse.mdm.api.base.query.JoinType;
 import org.eclipse.mdm.api.base.query.ModelManager;
 import org.eclipse.mdm.api.base.query.Query;
 import org.eclipse.mdm.api.base.query.Record;
@@ -183,17 +184,17 @@
 	 * {@inheritDoc}
 	 */
 	@Override
-	public <T extends Entity> T load(Class<T> entityClass, String instanceID) throws DataAccessException {
-		return entityLoader.load(new Key<>(entityClass), instanceID);
+	public <T extends Entity> List<T> load(Class<T> entityClass, Collection<String> instanceIDs) throws DataAccessException {
+		return entityLoader.loadAll(new Key<>(entityClass), instanceIDs);
 	}
 
 	/**
 	 * {@inheritDoc}
 	 */
 	@Override
-	public <T extends Entity> T load(Class<T> entityClass, ContextType contextType, String instanceID)
+	public <T extends Entity> List<T> load(Class<T> entityClass, ContextType contextType, Collection<String> instanceIDs)
 			throws DataAccessException {
-		return entityLoader.load(new Key<>(entityClass, contextType), instanceID);
+		return entityLoader.loadAll(new Key<>(entityClass, contextType), instanceIDs);
 	}
 
 	/**
@@ -332,7 +333,7 @@
 		for (ContextType contextType : ContextType.values()) {
 			EntityType entityType = modelManager.getEntityType(ContextRoot.class, contextType);
 			contextRootEntityTypes.put(contextType, entityType);
-			query.join(contextDescribableEntityType.getRelation(entityType), Join.OUTER).selectID(entityType);
+			query.join(contextDescribableEntityType.getRelation(entityType), JoinType.OUTER).selectID(entityType);
 		}
 
 		Optional<Result> result = query
@@ -365,7 +366,7 @@
 		for (ContextType contextType : contextTypes.length == 0 ? ContextType.values() : contextTypes) {
 			EntityType entityType = modelManager.getEntityType(ContextRoot.class, contextType);
 			contextRootEntityTypes.put(contextType, entityType);
-			query.join(contextDescribableEntityType.getRelation(entityType), Join.OUTER).selectID(entityType);
+			query.join(contextDescribableEntityType.getRelation(entityType), JoinType.OUTER).selectID(entityType);
 		}
 
 		Optional<Result> result = query
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/ReadRequestHandler.java b/src/main/java/org/eclipse/mdm/api/odsadapter/ReadRequestHandler.java
index 53611f0..f14aa77 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/ReadRequestHandler.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/ReadRequestHandler.java
@@ -131,7 +131,7 @@
 					throw new DataAccessException("Column with name '" + channel.getName() + "' not found.");
 				}
 				Column column = columns[0];
-				if (!unit.nameMatches(channel.getUnit().getName())) {
+				if (!unit.nameEquals(channel.getUnit().getName())) {
 					column.setUnit(unit.getName());
 				}
 				columnList.add(column);
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/ChildRequest.java b/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/ChildRequest.java
index ebdd4f2..7baa3b5 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/ChildRequest.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/ChildRequest.java
@@ -11,7 +11,7 @@
 import org.eclipse.mdm.api.base.query.DataAccessException;
 import org.eclipse.mdm.api.base.query.EntityType;
 import org.eclipse.mdm.api.base.query.Filter;
-import org.eclipse.mdm.api.base.query.Operation;
+import org.eclipse.mdm.api.base.query.ComparisonOperator;
 import org.eclipse.mdm.api.base.query.Query;
 import org.eclipse.mdm.api.base.query.Record;
 import org.eclipse.mdm.api.base.query.Relation;
@@ -94,7 +94,7 @@
 			adjustedFilter.ids(parentRelation, parent.entityResult.getIDs());
 			if (entityConfig.isReflexive()) {
 				// extend to retrieve all reflexive child candidates
-				adjustedFilter.add(Operation.IS_NOT_NULL.create(reflexiveRelation.getAttribute(), 0L));
+				adjustedFilter.add(ComparisonOperator.IS_NOT_NULL.create(reflexiveRelation.getAttribute(), 0L));
 			}
 		}
 
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/EntityLoader.java b/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/EntityLoader.java
index 1707353..6179bbb 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/EntityLoader.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/EntityLoader.java
@@ -58,7 +58,7 @@
 	public <T extends Entity> T load(Key<T> key, String instanceID) throws DataAccessException {
 		List<T> entities = loadAll(key, Collections.singletonList(instanceID));
 		if (entities.size() != 1) {
-			throw new DataAccessException("Faild to load entity by instance ID.");
+			throw new DataAccessException("Failed to load entity by instance ID.");
 		}
 		return entities.get(0);
 	}
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/EntityRequest.java b/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/EntityRequest.java
index 9c81920..6407bb4 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/EntityRequest.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/EntityRequest.java
@@ -20,7 +20,7 @@
 import org.eclipse.mdm.api.base.query.EntityType;
 import org.eclipse.mdm.api.base.query.Filter;
 import org.eclipse.mdm.api.base.query.ModelManager;
-import org.eclipse.mdm.api.base.query.Operation;
+import org.eclipse.mdm.api.base.query.ComparisonOperator;
 import org.eclipse.mdm.api.base.query.Query;
 import org.eclipse.mdm.api.base.query.Record;
 import org.eclipse.mdm.api.base.query.Relation;
@@ -272,7 +272,7 @@
 			adjustedFilter.merge(filter);
 			if (entityConfig.isReflexive()) {
 				// extend to retrieve all reflexive child candidates
-				adjustedFilter.add(Operation.IS_NOT_NULL.create(reflexiveRelation.getAttribute(), 0L));
+				adjustedFilter.add(ComparisonOperator.IS_NOT_NULL.create(reflexiveRelation.getAttribute(), 0L));
 			}
 		}
 
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/EntityResult.java b/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/EntityResult.java
index a54912c..0ad1498 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/EntityResult.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/EntityResult.java
@@ -18,7 +18,8 @@
 import org.eclipse.mdm.api.base.model.Core;
 import org.eclipse.mdm.api.base.model.Deletable;
 import org.eclipse.mdm.api.base.model.Entity;
-import org.eclipse.mdm.api.base.model.ScalarType;
+import org.eclipse.mdm.api.base.model.EnumRegistry;
+import org.eclipse.mdm.api.base.model.Enumeration;
 import org.eclipse.mdm.api.base.model.Value;
 import org.eclipse.mdm.api.base.model.ValueType;
 import org.eclipse.mdm.api.base.query.Attribute;
@@ -171,11 +172,12 @@
 		Value enumerationClass = ValueType.STRING.create(VATTR_ENUMERATION_CLASS);
 		values.put(VATTR_ENUMERATION_CLASS, enumerationClass);
 		if (attribute.getValueType().isEnumerationType()) {
-			enumerationClass.set(attribute.getEnumClass().getName());
+			enumerationClass.set(attribute.getEnumObj().getName());
 		}
 
-		Value scalarType = ValueType.ENUMERATION.create(ScalarType.class, VATTR_SCALAR_TYPE);
-		scalarType.set(ScalarType.valueOf(attribute.getValueType().toSingleType().name()));
+		Enumeration<?> scalarTypeObj=EnumRegistry.getInstance().get("ScalarType");
+		Value scalarType = ValueType.ENUMERATION.create(scalarTypeObj, VATTR_SCALAR_TYPE);
+		scalarType.set(scalarTypeObj.valueOf(attribute.getValueType().toSingleType().name()));
 		values.put(VATTR_SCALAR_TYPE, scalarType);
 
 		values.put(VATTR_SEQUENCE, ValueType.BOOLEAN.create(VATTR_SEQUENCE, attribute.getValueType().isSequence()));
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/notification/NotificationEntityLoader.java b/src/main/java/org/eclipse/mdm/api/odsadapter/notification/NotificationEntityLoader.java
index 3dcb43d..c976faa 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/notification/NotificationEntityLoader.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/notification/NotificationEntityLoader.java
@@ -14,8 +14,8 @@
 import org.eclipse.mdm.api.base.query.DataAccessException;
 import org.eclipse.mdm.api.base.query.EntityType;
 import org.eclipse.mdm.api.base.query.Filter;
-import org.eclipse.mdm.api.base.query.Join;
-import org.eclipse.mdm.api.base.query.Operation;
+import org.eclipse.mdm.api.base.query.JoinType;
+import org.eclipse.mdm.api.base.query.ComparisonOperator;
 import org.eclipse.mdm.api.base.query.Record;
 import org.eclipse.mdm.api.odsadapter.lookup.EntityLoader;
 import org.eclipse.mdm.api.odsadapter.lookup.config.EntityConfig;
@@ -102,13 +102,13 @@
 		final EntityType measurement = modelManager.getEntityType(Measurement.class);
 
 		List<String> testStepIDs = modelManager.createQuery().selectID(testStep)
-				.join(testStep.getRelation(contextRoot), Join.OUTER)
-				.fetch(Filter.and().add(Operation.IN_SET.create(contextRoot.getIDAttribute(), ids)))
+				.join(testStep.getRelation(contextRoot), JoinType.OUTER)
+				.fetch(Filter.and().add(ComparisonOperator.IN_SET.create(contextRoot.getIDAttribute(), ids)))
 				.stream().map(r -> r.getRecord(testStep)).map(Record::getID).collect(Collectors.toList());
 
 		List<String> measurementIDs = modelManager.createQuery().selectID(measurement)
-				.join(measurement.getRelation(contextRoot), Join.OUTER)
-				.fetch(Filter.and().add(Operation.IN_SET.create(contextRoot.getIDAttribute(), ids)))
+				.join(measurement.getRelation(contextRoot), JoinType.OUTER)
+				.fetch(Filter.and().add(ComparisonOperator.IN_SET.create(contextRoot.getIDAttribute(), ids)))
 				.stream().map(r -> r.getRecord(measurement)).map(Record::getID).collect(Collectors.toList());
 
 		List<ContextDescribable> list = new ArrayList<>();
@@ -139,15 +139,15 @@
 		final EntityType measurement = modelManager.getEntityType(Measurement.class);
 
 		List<String> testStepIDs = modelManager.createQuery().selectID(testStep)
-				.join(testStep.getRelation(contextRoot), Join.OUTER)
-				.join(contextRoot.getRelation(contextComponent), Join.OUTER)
-				.fetch(Filter.and().add(Operation.IN_SET.create(contextComponent.getIDAttribute(), ids)))
+				.join(testStep.getRelation(contextRoot), JoinType.OUTER)
+				.join(contextRoot.getRelation(contextComponent), JoinType.OUTER)
+				.fetch(Filter.and().add(ComparisonOperator.IN_SET.create(contextComponent.getIDAttribute(), ids)))
 				.stream().map(r -> r.getRecord(testStep)).map(Record::getID).collect(Collectors.toList());
 
 		List<String> measurementIDs = modelManager.createQuery().selectID(measurement)
-				.join(measurement.getRelation(contextRoot), Join.OUTER)
-				.join(contextRoot.getRelation(contextComponent), Join.OUTER)
-				.fetch(Filter.and().add(Operation.IN_SET.create(contextComponent.getIDAttribute(), ids)))
+				.join(measurement.getRelation(contextRoot), JoinType.OUTER)
+				.join(contextRoot.getRelation(contextComponent), JoinType.OUTER)
+				.fetch(Filter.and().add(ComparisonOperator.IN_SET.create(contextComponent.getIDAttribute(), ids)))
 				.stream().map(r -> r.getRecord(measurement)).map(Record::getID).collect(Collectors.toList());
 
 		List<ContextDescribable> list = new ArrayList<>();
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/notification/peak/PeakNotificationManager.java b/src/main/java/org/eclipse/mdm/api/odsadapter/notification/peak/PeakNotificationManager.java
index ed8431a..68b41cf 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/notification/peak/PeakNotificationManager.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/notification/peak/PeakNotificationManager.java
@@ -122,7 +122,9 @@
 
 		try {
 			LOGGER.info("Requesting event input for " + registration);
-			EventInput eventInput = endpoint.path(registration).request().get(EventInput.class);
+			EventInput eventInput = endpoint.path(registration)
+					.request(SseFeature.SERVER_SENT_EVENTS_TYPE)
+					.get(EventInput.class);
 
 			LOGGER.info("Received event input, starting event processor.");
 			EventProcessor processor = new EventProcessor(eventInput, listener, this, eventMediaType);
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSAttribute.java b/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSAttribute.java
index 8b91f88..ca8a946 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSAttribute.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSAttribute.java
@@ -14,6 +14,7 @@
 
 import org.asam.ods.ApplAttr;
 import org.eclipse.mdm.api.base.model.Value;
+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;
@@ -32,11 +33,11 @@
 	// Instance variables
 	// ======================================================================
 
-	private final Class<? extends Enum<?>> enumClass;
+	private final Enumeration<?> enumObj;
 	private final String name;
 	private final String unit;
 	private final EntityType entityType;
-	private final ValueType valueType;
+	private final ValueType<?> valueType;
 	private final boolean isIdAttribute;
 
 	// ======================================================================
@@ -55,7 +56,7 @@
 	 * @param enumClass
 	 *            The enumeration class, may be null.
 	 */
-	ODSAttribute(EntityType entityType, ApplAttr applAttr, String unit, Class<? extends Enum<?>> enumClass) {
+	ODSAttribute(EntityType entityType, ApplAttr applAttr, String unit, Enumeration<?> enumObj) {
 		this.entityType = entityType;
 		name = applAttr.aaName;
 		this.unit = unit == null ? "" : unit;
@@ -68,12 +69,12 @@
 			isIdAttribute = false;
 		}
 
-		if (valueType.isEnumerationType() && enumClass == null) {
+		if (valueType.isEnumerationType() && enumObj == null) {
 			throw new IllegalStateException(
-					"A modeled attribute with an enumeration vaue type must have an " + "enumeration definition.");
+					"A modeled attribute with an enumeration value type must have an " + "enumeration definition.");
 		}
 
-		this.enumClass = enumClass;
+		this.enumObj = enumObj;
 	}
 
 	private boolean isIDAttribute(EntityType entityType, ApplAttr applAttr) {
@@ -120,7 +121,7 @@
 	 * {@inheritDoc}
 	 */
 	@Override
-	public ValueType getValueType() {
+	public ValueType<?> getValueType() {
 		return valueType;
 	}
 
@@ -128,9 +129,9 @@
 	 * {@inheritDoc}
 	 */
 	@Override
-	public Class<? extends Enum<?>> getEnumClass() {
+	public Enumeration<?> getEnumObj() {
 		if (getValueType().isEnumerationType()) {
-			return enumClass;
+			return enumObj;
 		}
 
 		throw new IllegalStateException("The value type of this attribute is not an enumeration type.");
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSEntityFactory.java b/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSEntityFactory.java
index af50bad..3f093b5 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSEntityFactory.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSEntityFactory.java
@@ -20,6 +20,8 @@
 import org.eclipse.mdm.api.base.model.ContextType;
 import org.eclipse.mdm.api.base.model.Core;
 import org.eclipse.mdm.api.base.model.Entity;
+import org.eclipse.mdm.api.base.model.EnumRegistry;
+import org.eclipse.mdm.api.base.model.EnumerationValue;
 import org.eclipse.mdm.api.base.model.Interpolation;
 import org.eclipse.mdm.api.base.model.ScalarType;
 import org.eclipse.mdm.api.base.model.SequenceRepresentation;
@@ -45,7 +47,7 @@
 	// Class variables
 	// ======================================================================
 
-	private static final Set<Class<? extends Enum<?>>> ENUM_CLASSES = new HashSet<>();
+	private static final Set<Class<? extends EnumerationValue>> ENUM_CLASSES = new HashSet<>();
 
 	static {
 		ENUM_CLASSES.add(ScalarType.class);
@@ -128,7 +130,7 @@
 	 * {@inheritDoc}
 	 */
 	@Override
-	protected void validateEnum(Class<? extends Enum<?>> enumClass) {
+	protected void validateEnum(Class<? extends EnumerationValue> enumClass) {
 		if (ENUM_CLASSES.contains(enumClass)) {
 			// given enumeration class is a default one, which is always
 			// supported
@@ -160,7 +162,7 @@
 
 		if (CatalogAttribute.class.equals(entityConfig.getEntityClass())) {
 			core.getValues().put(VATTR_ENUMERATION_CLASS, ValueType.STRING.create(VATTR_ENUMERATION_CLASS));
-			core.getValues().put(VATTR_SCALAR_TYPE, ValueType.ENUMERATION.create(ScalarType.class, VATTR_SCALAR_TYPE));
+			core.getValues().put(VATTR_SCALAR_TYPE, ValueType.ENUMERATION.create(EnumRegistry.getInstance().get("ScalarType"), VATTR_SCALAR_TYPE));
 			core.getValues().put(VATTR_SEQUENCE, ValueType.BOOLEAN.create(VATTR_SEQUENCE));
 		}
 
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSEntityType.java b/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSEntityType.java
index 0cba1dd..6fc22c6 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSEntityType.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSEntityType.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
@@ -26,10 +26,11 @@
 
 import org.asam.ods.ApplElem;
 import org.asam.ods.T_LONGLONG;
+import org.eclipse.mdm.api.base.model.Enumeration;
 import org.eclipse.mdm.api.base.query.Attribute;
 import org.eclipse.mdm.api.base.query.EntityType;
 import org.eclipse.mdm.api.base.query.Relation;
-import org.eclipse.mdm.api.base.query.Relationship;
+import org.eclipse.mdm.api.base.query.RelationType;
 import org.eclipse.mdm.api.odsadapter.utils.ODSConverter;
 
 /**
@@ -47,7 +48,7 @@
 	private final Map<EntityType, Map<String, Relation>> relationsByEntityName = new HashMap<>();
 	private final Map<EntityType, Relation> relationsByEntity = new HashMap<>();
 
-	private final Map<Relationship, List<Relation>> relationsByType = new EnumMap<>(Relationship.class);
+	private final Map<RelationType, List<Relation>> relationsByType = new EnumMap<>(RelationType.class);
 	private final List<Relation> relations = new ArrayList<>();
 
 	private final Map<String, Attribute> attributeByName;
@@ -74,8 +75,9 @@
 	 *            The enumeration class {@code Map} for enum mapping of
 	 *            attributes.
 	 */
+
 	ODSEntityType(String sourceName, ApplElem applElem, Map<String, String> units,
-			Map<String, Class<? extends Enum<?>>> enumClasses) {
+			Map<String, Enumeration<?>> enumObjs) {
 		this.sourceName = sourceName;
 		baseName = applElem.beName;
 		name = applElem.aeName;
@@ -83,8 +85,7 @@
 
 		attributeByName = Arrays
 				.stream(applElem.attributes).map(a -> new ODSAttribute(this, a,
-						units.get(Long.toString(ODSConverter.fromODSLong(a.unitId))),
-						enumClasses.get(a.aaName)))
+						units.get(Long.toString(ODSConverter.fromODSLong(a.unitId))), enumObjs.get(a.aaName)))
 				.collect(toMap(Attribute::getName, Function.identity()));
 	}
 
@@ -166,8 +167,8 @@
 	 */
 	@Override
 	public List<Relation> getParentRelations() {
-		return getRelations(Relationship.FATHER_CHILD).stream()
-				.filter(r -> ((ODSRelation) r).isOutgoing(Relationship.FATHER_CHILD)).collect(Collectors.toList());
+		return getRelations(RelationType.FATHER_CHILD).stream()
+				.filter(r -> ((ODSRelation) r).isOutgoing(RelationType.FATHER_CHILD)).collect(Collectors.toList());
 	}
 
 	/**
@@ -175,8 +176,8 @@
 	 */
 	@Override
 	public List<Relation> getChildRelations() {
-		return getRelations(Relationship.FATHER_CHILD).stream()
-				.filter(r -> ((ODSRelation) r).isIncoming(Relationship.FATHER_CHILD)).collect(Collectors.toList());
+		return getRelations(RelationType.FATHER_CHILD).stream()
+				.filter(r -> ((ODSRelation) r).isIncoming(RelationType.FATHER_CHILD)).collect(Collectors.toList());
 	}
 
 	/**
@@ -184,7 +185,7 @@
 	 */
 	@Override
 	public List<Relation> getInfoRelations() {
-		return getRelations(Relationship.INFO).stream().filter(r -> ((ODSRelation) r).isOutgoing(Relationship.INFO))
+		return getRelations(RelationType.INFO).stream().filter(r -> ((ODSRelation) r).isOutgoing(RelationType.INFO))
 				.collect(Collectors.toList());
 	}
 
@@ -192,8 +193,8 @@
 	 * {@inheritDoc}
 	 */
 	@Override
-	public List<Relation> getRelations(Relationship relationship) {
-		List<Relation> result = relationsByType.get(relationship);
+	public List<Relation> getRelations(RelationType relationType) {
+		List<Relation> result = relationsByType.get(relationType);
 		return result == null ? Collections.emptyList() : Collections.unmodifiableList(result);
 	}
 
@@ -315,7 +316,7 @@
 	 *            {@code Relation} which will be added.
 	 */
 	private void addRelation(Relation relation) {
-		relationsByType.computeIfAbsent(relation.getRelationship(), k -> new ArrayList<>()).add(relation);
+		relationsByType.computeIfAbsent(relation.getRelationType(), k -> new ArrayList<>()).add(relation);
 		relations.add(relation);
 	}
 
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSModelManager.java b/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSModelManager.java
index 9588363..4d26e93 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSModelManager.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSModelManager.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

@@ -28,9 +28,11 @@
 import org.asam.ods.ApplElem;

 import org.asam.ods.ApplElemAccess;

 import org.asam.ods.ApplRel;

+import org.asam.ods.ApplicationStructure;

 import org.asam.ods.ApplicationStructureValue;

 import org.asam.ods.ElemResultSetExt;

 import org.asam.ods.EnumerationAttributeStructure;

+import org.asam.ods.EnumerationDefinition;

 import org.asam.ods.JoinDef;

 import org.asam.ods.QueryStructureExt;

 import org.asam.ods.SelAIDNameUnitId;

@@ -44,6 +46,8 @@
 import org.eclipse.mdm.api.base.model.ContextSensor;

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

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

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

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

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

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

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

@@ -78,6 +82,7 @@
 import org.eclipse.mdm.api.odsadapter.lookup.config.EntityConfig.Key;

 import org.eclipse.mdm.api.odsadapter.lookup.config.EntityConfigRepository;

 import org.eclipse.mdm.api.odsadapter.utils.ODSConverter;

+import org.eclipse.mdm.api.odsadapter.utils.ODSEnum;

 import org.eclipse.mdm.api.odsadapter.utils.ODSEnumerations;

 import org.eclipse.mdm.api.odsadapter.utils.ODSUtils;

 import org.omg.CORBA.ORB;

@@ -426,11 +431,25 @@
 		LOGGER.debug("Reading the application model...");

 		long start = System.currentTimeMillis();

 		// enumeration mappings (aeID -> (aaName -> enumClass))

-		Map<String, Map<String, Class<? extends Enum<?>>>> enumClassMap = new HashMap<>();

+		Map<String, Map<String, Enumeration<?>>> enumClassMap = new HashMap<>();

+		EnumRegistry er = EnumRegistry.getInstance();

+		ApplicationStructure applicationStructure = aoSession.getApplicationStructure();

 		for (EnumerationAttributeStructure eas : aoSession.getEnumerationAttributes()) {

+			// make sure the enumeration is found

+			if (ODSEnumerations.getEnumObj(eas.enumName) == null) {

+				Enumeration<ODSEnum> enumdyn = new Enumeration<>(ODSEnum.class, eas.enumName);

+				EnumerationDefinition enumdef = applicationStructure.getEnumerationDefinition(eas.enumName);

+				String[] listItemNames = enumdef.listItemNames();

+				int ordinal = 0;

+				for (String item : listItemNames) {

+					enumdyn.addValue(new ODSEnum(item, ordinal));

+					ordinal++;

+				}

+				er.add(eas.enumName, enumdyn);

+			}

+

 			enumClassMap.computeIfAbsent(Long.toString(ODSConverter.fromODSLong(eas.aid)), k -> new HashMap<>())

-					.put(eas.aaName,

-					ODSEnumerations.getEnumClass(eas.enumName));

+					.put(eas.aaName, ODSEnumerations.getEnumObj(eas.enumName));

 		}

 

 		ApplicationStructureValue applicationStructureValue = aoSession.getApplicationStructureValue();

@@ -441,7 +460,7 @@
 		String sourceName = aoSession.getName();

 		for (ApplElem applElem : applicationStructureValue.applElems) {

 			String odsID = Long.toString(ODSConverter.fromODSLong(applElem.aid));

-			Map<String, Class<? extends Enum<?>>> entityEnumMap = enumClassMap.getOrDefault(odsID, new HashMap<>());

+			Map<String, Enumeration<?>> entityEnumMap = enumClassMap.getOrDefault(odsID, new HashMap<>());

 

 			ODSEntityType entityType = new ODSEntityType(sourceName, applElem, units, entityEnumMap);

 			entityTypesByName.put(applElem.aeName, entityType);

diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSQuery.java b/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSQuery.java
index 2f5b018..0571d24 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSQuery.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSQuery.java
@@ -42,7 +42,7 @@
 import org.eclipse.mdm.api.base.query.EntityType;
 import org.eclipse.mdm.api.base.query.Filter;
 import org.eclipse.mdm.api.base.query.FilterItem;
-import org.eclipse.mdm.api.base.query.Join;
+import org.eclipse.mdm.api.base.query.JoinType;
 import org.eclipse.mdm.api.base.query.Query;
 import org.eclipse.mdm.api.base.query.Record;
 import org.eclipse.mdm.api.base.query.Relation;
@@ -125,7 +125,7 @@
 	 * {@inheritDoc}
 	 */
 	@Override
-	public Query join(Relation relation, Join join) {
+	public Query join(Relation relation, JoinType join) {
 		queriedEntityTypes.add(relation.getSource());
 		queriedEntityTypes.add(relation.getTarget());
 		joinSeq.add(createJoin(relation, join));
@@ -189,8 +189,10 @@
 				SelItem selItem = new SelItem();
 				if (conditionItem.isCondition()) {
 					selItem.value(createCondition(conditionItem.getCondition()));
-				} else if (conditionItem.isOperator()) {
-					selItem._operator(ODSUtils.OPERATORS.convert(conditionItem.getOperator()));
+				} else if (conditionItem.isBracketOperator()){
+					selItem._operator(ODSUtils.BRACKETOPERATORS.convert(conditionItem.getBracketOperator()));
+				} else if (conditionItem.isBooleanOperator()) {
+					selItem._operator(ODSUtils.OPERATORS.convert(conditionItem.getBooleanOperator()));
 					condCount++;
 				} else {
 					throw new IllegalArgumentException("Passed filter item is neither an operator nor a condition.");
@@ -257,7 +259,7 @@
 	private SelValueExt createCondition(Condition condition) throws DataAccessException {
 		SelValueExt sve = new SelValueExt();
 
-		sve.oper = ODSUtils.OPERATIONS.convert(condition.getOperation());
+		sve.oper = ODSUtils.OPERATIONS.convert(condition.getComparisonOperator());
 		sve.attr = new AIDNameUnitId();
 		sve.attr.unitId = new T_LONGLONG();
 		sve.attr.attr = createAIDName(condition.getAttribute());
@@ -267,16 +269,16 @@
 	}
 
 	/**
-	 * Converts given {@link Relation} and {@link Join} to an ODS
+	 * Converts given {@link Relation} and {@link JoinType} to an ODS
 	 * {@link JoinDef}.
 	 *
 	 * @param relation
 	 *            The {@code Relation}.
-	 * @param join
-	 *            The {@code Join}.
+	 * @param joinType
+	 *            The {@code JoinType}.
 	 * @return The corresponding {@code JoinDef} is returned.
 	 */
-	private JoinDef createJoin(Relation relation, Join join) {
+	private JoinDef createJoin(Relation relation, JoinType join) {
 		JoinDef joinDef = new JoinDef();
 
 		joinDef.fromAID = ((ODSEntityType) relation.getSource()).getODSID();
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSRelation.java b/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSRelation.java
index b90ced7..e200a1a 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSRelation.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSRelation.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 @@
 import org.eclipse.mdm.api.base.query.Attribute;
 import org.eclipse.mdm.api.base.query.EntityType;
 import org.eclipse.mdm.api.base.query.Relation;
-import org.eclipse.mdm.api.base.query.Relationship;
+import org.eclipse.mdm.api.base.query.RelationType;
 import org.eclipse.mdm.api.odsadapter.utils.ODSUtils;
 
 /**
@@ -31,7 +31,7 @@
 	// Instance variables
 	// ======================================================================
 
-	private final Relationship relationship;
+	private final RelationType relationType;
 	private final EntityType source;
 	private final EntityType target;
 	private final String name;
@@ -58,7 +58,7 @@
 		this.source = source;
 		this.target = target;
 		name = applRel.arName;
-		relationship = ODSUtils.RELATIONSHIPS.revert(applRel.arRelationType);
+		relationType = ODSUtils.RELATIONSHIPS.revert(applRel.arRelationType);
 		rangeMax = applRel.arRelationRange.max;
 	}
 
@@ -94,8 +94,8 @@
 	 * {@inheritDoc}
 	 */
 	@Override
-	public Relationship getRelationship() {
-		return relationship;
+	public RelationType getRelationType() {
+		return relationType;
 	}
 
 	/**
@@ -141,36 +141,21 @@
 		return getName();
 	}
 
-	// ======================================================================
-	// Package methods
-	// ======================================================================
-
+	
 	/**
-	 * Checks whether this relation is of the same {@link Relationship} as the
-	 * given one and whether the foreign key is in the table of the source
-	 * entity type.
-	 *
-	 * @param relationship
-	 *            The {@code Relationship}.
-	 * @return Returns {@code true} this relation's {@code Relationship} is
-	 *         equal with the given one and it is is an outgoing relation.
+	 * {@inheritDoc}
 	 */
-	boolean isOutgoing(Relationship relationship) {
-		return relationship.equals(getRelationship()) && rangeMax == 1;
+	@Override
+	public boolean isOutgoing(RelationType relationType) {
+		return relationType.equals(getRelationType()) && rangeMax == 1;
 	}
 
 	/**
-	 * Checks whether this relation is of the same {@link Relationship} as the
-	 * given one and whether the foreign key is in the table of the target
-	 * entity type.
-	 *
-	 * @param relationship
-	 *            The {@code Relationship}.
-	 * @return Returns {@code true} this relation's {@code Relationship} is
-	 *         equal with the given one and it is is an incoming relation.
+	 * {@inheritDoc}
 	 */
-	boolean isIncoming(Relationship relationship) {
-		return relationship.equals(getRelationship()) && rangeMax == -1;
+	@Override
+	public boolean isIncoming(RelationType relationType) {
+		return relationType.equals(getRelationType()) && rangeMax == -1;
 	}
 
 }
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/search/BaseEntitySearchQuery.java b/src/main/java/org/eclipse/mdm/api/odsadapter/search/BaseEntitySearchQuery.java
index 28cddaa..b0e74f8 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/search/BaseEntitySearchQuery.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/search/BaseEntitySearchQuery.java
@@ -31,7 +31,7 @@
 import org.eclipse.mdm.api.base.query.EntityType;
 import org.eclipse.mdm.api.base.query.Filter;
 import org.eclipse.mdm.api.base.query.FilterItem;
-import org.eclipse.mdm.api.base.query.Join;
+import org.eclipse.mdm.api.base.query.JoinType;
 import org.eclipse.mdm.api.base.query.Query;
 import org.eclipse.mdm.api.base.query.Relation;
 import org.eclipse.mdm.api.base.query.Result;
@@ -85,11 +85,11 @@
 		EntityType source = entityConfig.getEntityType();
 
 		entityConfig.getOptionalConfigs().stream().map(EntityConfig::getEntityType).forEach(entityType -> {
-			joinTree.addNode(source, entityType, true, Join.OUTER);
+			joinTree.addNode(source, entityType, true, JoinType.OUTER);
 		});
 
 		entityConfig.getMandatoryConfigs().stream().map(EntityConfig::getEntityType).forEach(entityType -> {
-			joinTree.addNode(source, entityType, true, Join.INNER);
+			joinTree.addNode(source, entityType, true, JoinType.INNER);
 		});
 	}
 
@@ -188,16 +188,16 @@
 		EntityType target = targetEntityConfig.getEntityType();
 
 		// add dependency source to target
-		joinTree.addNode(modelManager.getEntityType(joinConfig.source), target, joinConfig.viaParent, Join.INNER);
+		joinTree.addNode(modelManager.getEntityType(joinConfig.source), target, joinConfig.viaParent, JoinType.INNER);
 
 		// add target's optional dependencies
 		targetEntityConfig.getOptionalConfigs().stream().map(EntityConfig::getEntityType).forEach(entityType -> {
-			joinTree.addNode(target, entityType, true, Join.OUTER);
+			joinTree.addNode(target, entityType, true, JoinType.OUTER);
 		});
 
 		// add target's mandatory dependencies
 		targetEntityConfig.getMandatoryConfigs().stream().map(EntityConfig::getEntityType).forEach(entityType -> {
-			joinTree.addNode(target, entityType, true, Join.INNER);
+			joinTree.addNode(target, entityType, true, JoinType.INNER);
 		});
 	}
 
@@ -217,14 +217,14 @@
 		for (ContextType contextType : ContextType.values()) {
 			EntityType rootEntityType = modelManager.getEntityType(ContextRoot.class, contextType);
 			for (Relation componentRelation : rootEntityType.getChildRelations()) {
-				joinTree.addNode(componentRelation.getSource(), componentRelation.getTarget(), true, Join.OUTER);
+				joinTree.addNode(componentRelation.getSource(), componentRelation.getTarget(), true, JoinType.OUTER);
 
 				for (Relation sensorRelation : componentRelation.getTarget().getChildRelations()) {
-					joinTree.addNode(sensorRelation.getSource(), sensorRelation.getTarget(), true, Join.OUTER);
+					joinTree.addNode(sensorRelation.getSource(), sensorRelation.getTarget(), true, JoinType.OUTER);
 				}
 			}
 
-			joinTree.addNode(modelManager.getEntityType(source), rootEntityType, true, Join.OUTER);
+			joinTree.addNode(modelManager.getEntityType(source), rootEntityType, true, JoinType.OUTER);
 		}
 	}
 
@@ -273,7 +273,7 @@
 		JoinNode joinNode = joinTree.getJoinNode(entityType.getName());
 		EntityType sourceEntityType = modelManager.getEntityType(joinNode.source);
 		addJoins(query, sourceEntityType);
-		query.join(sourceEntityType.getRelation(entityType), joinNode.join);
+		query.join(sourceEntityType.getRelation(entityType), joinNode.joinType);
 	}
 
 }
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/search/JoinTree.java b/src/main/java/org/eclipse/mdm/api/odsadapter/search/JoinTree.java
index 8c35182..8c8e885 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/search/JoinTree.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/search/JoinTree.java
@@ -10,7 +10,7 @@
 
 import org.eclipse.mdm.api.base.model.Entity;
 import org.eclipse.mdm.api.base.query.EntityType;
-import org.eclipse.mdm.api.base.query.Join;
+import org.eclipse.mdm.api.base.query.JoinType;
 import org.eclipse.mdm.api.base.query.SearchQuery;
 
 /**
@@ -82,17 +82,17 @@
 	 *            The target entity type name.
 	 * @param viaParent
 	 *            If true, then source is the considered parent of the target.
-	 * @param join
-	 *            Either inner or outer join.
+	 * @param joinType
+	 *            Either inner or outer joinType.
 	 * @throws IllegalArgumentException
 	 *             Thrown if given setup overrides an existing one (a target
 	 *             entity type is allowed to be joined only once).
 	 */
-	public void addNode(EntityType source, EntityType target, boolean viaParent, Join join) {
+	public void addNode(EntityType source, EntityType target, boolean viaParent, JoinType joinType) {
 		String sourceName = source.getName();
 		String targetName = target.getName();
 
-		if (joinNodes.put(targetName, new JoinNode(sourceName, targetName, join)) != null) {
+		if (joinNodes.put(targetName, new JoinNode(sourceName, targetName, joinType)) != null) {
 			throw new IllegalArgumentException("It is not allowed to override join nodes.");
 		}
 
@@ -111,7 +111,7 @@
 	// ======================================================================
 
 	/**
-	 * A simple join node setup.
+	 * A simple joinType node setup.
 	 */
 	static final class JoinNode {
 
@@ -121,7 +121,7 @@
 
 		final String source;
 		final String target;
-		final Join join;
+		final JoinType joinType;
 
 		// ======================================================================
 		// Constructors
@@ -134,19 +134,19 @@
 		 *            The source entity type name.
 		 * @param target
 		 *            The target entity type name.
-		 * @param join
-		 *            Either inner or outer {@link Join}.
+		 * @param joinType
+		 *            Either inner or outer {@link JoinType}.
 		 */
-		private JoinNode(String source, String target, Join join) {
+		private JoinNode(String source, String target, JoinType joinType) {
 			this.source = source;
 			this.target = target;
-			this.join = join;
+			this.joinType = joinType;
 		}
 
 	}
 
 	/**
-	 * A simple join configuration setup.
+	 * A simple joinType configuration setup.
 	 */
 	static final class JoinConfig {
 
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/CatalogManager.java b/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/CatalogManager.java
index fd338bd..6d688ed 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/CatalogManager.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/CatalogManager.java
@@ -32,7 +32,7 @@
 import org.eclipse.mdm.api.base.query.DataAccessException;
 import org.eclipse.mdm.api.base.query.EntityType;
 import org.eclipse.mdm.api.base.query.Filter;
-import org.eclipse.mdm.api.base.query.Operation;
+import org.eclipse.mdm.api.base.query.ComparisonOperator;
 import org.eclipse.mdm.api.base.query.Query;
 import org.eclipse.mdm.api.base.query.Result;
 import org.eclipse.mdm.api.dflt.model.CatalogAttribute;
@@ -233,7 +233,7 @@
 				applicationAttribute.setName(catalogAttribute.getName());
 				if (dataType == DataType.DT_ENUM) {
 					applicationAttribute.setEnumerationDefinition(getApplicationStructure().getEnumerationDefinition(
-							ODSEnumerations.getEnumName(catalogAttribute.getEnumerationClass())));
+							ODSEnumerations.getEnumName(catalogAttribute.getEnumerationObject())));
 				}
 				Optional<Unit> unit = catalogAttribute.getUnit();
 				if (unit.isPresent()) {
@@ -539,7 +539,7 @@
 			Query query = transaction.getModelManager().createQuery().selectID(target).join(source, target);
 
 			List<Result> results = query.fetch(Filter.and()
-					.add(Operation.IN_SET.create(source.getIDAttribute(), collectInstanceIDs(entry.getValue()))));
+					.add(ComparisonOperator.IN_SET.create(source.getIDAttribute(), collectInstanceIDs(entry.getValue()))));
 			if (results.size() > 0) {
 				return true;
 			}
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/DeleteStatement.java b/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/DeleteStatement.java
index addd473..12ae06e 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/DeleteStatement.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/DeleteStatement.java
@@ -35,7 +35,7 @@
 import org.eclipse.mdm.api.base.query.DataAccessException;
 import org.eclipse.mdm.api.base.query.EntityType;
 import org.eclipse.mdm.api.base.query.Filter;
-import org.eclipse.mdm.api.base.query.Join;
+import org.eclipse.mdm.api.base.query.JoinType;
 import org.eclipse.mdm.api.base.query.Query;
 import org.eclipse.mdm.api.base.query.Relation;
 import org.eclipse.mdm.api.base.query.Result;
@@ -135,7 +135,7 @@
 			}
 
 			if (!relation.getTarget().equals(relation.getSource())) {
-				query.join(relation, Join.OUTER).selectID(relation.getTarget());
+				query.join(relation, JoinType.OUTER).selectID(relation.getTarget());
 			}
 		}
 
@@ -161,16 +161,16 @@
 
 		// join context roots
 		if (measurement.equals(entityType) || testStep.equals(entityType)) {
-			query.join(entityType.getRelation(unitUnderTest), Join.OUTER).selectID(unitUnderTest);
-			query.join(entityType.getRelation(testSequence), Join.OUTER).selectID(testSequence);
-			query.join(entityType.getRelation(testEquipment), Join.OUTER).selectID(testEquipment);
+			query.join(entityType.getRelation(unitUnderTest), JoinType.OUTER).selectID(unitUnderTest);
+			query.join(entityType.getRelation(testSequence), JoinType.OUTER).selectID(testSequence);
+			query.join(entityType.getRelation(testEquipment), JoinType.OUTER).selectID(testEquipment);
 			delayedDelete.addAll(Arrays.asList(unitUnderTest, testSequence, testEquipment));
 		}
 
 		// join parameter sets
 		if (measurement.equals(entityType) || channel.equals(entityType)) {
 			EntityType parameterSet = getModelManager().getEntityType(ParameterSet.class);
-			query.join(entityType.getRelation(parameterSet), Join.OUTER).selectID(parameterSet);
+			query.join(entityType.getRelation(parameterSet), JoinType.OUTER).selectID(parameterSet);
 		}
 
 		Filter filter = Filter.or().ids(entityType, instanceIDs);
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/WriteRequestHandler.java b/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/WriteRequestHandler.java
index 035b906..ba7810a 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/WriteRequestHandler.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/WriteRequestHandler.java
@@ -127,7 +127,7 @@
 		values.get(AE_LC_ATTR_PARAMETERS).set(writeRequest.getGenerationParameters());
 
 		if (writeRequest.hasValues()) {
-			ValueType valueType = writeRequest.getRawScalarType().toValueType();
+			ValueType<?> valueType = writeRequest.getRawScalarType().toValueType();
 			String unitName = writeRequest.getChannel().getUnit().getName();
 			values.put(AE_LC_ATTR_VALUES,
 					valueType.create(AE_LC_ATTR_VALUES, unitName, true, writeRequest.getValues()));
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/utils/ODSConverter.java b/src/main/java/org/eclipse/mdm/api/odsadapter/utils/ODSConverter.java
index 57cea37..ed53910 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/utils/ODSConverter.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/utils/ODSConverter.java
@@ -250,13 +250,13 @@
 			int[] odsValues = odsValueSeq.u.enumVal();
 			for (int i = 0; i < flags.length; i++) {
 				values.add(attribute.createValue(unit, flags[i] == 15,
-						ODSEnumerations.fromODSEnum(attribute.getEnumClass(), odsValues[i])));
+						ODSEnumerations.fromODSEnum(attribute.getEnumObj(), odsValues[i])));
 			}
 		} else if (DataType.DS_ENUM == dataType) {
 			int[][] odsValues = odsValueSeq.u.enumSeq();
 			for (int i = 0; i < flags.length; i++) {
 				values.add(attribute.createValue(unit, flags[i] == 15,
-						ODSEnumerations.fromODSEnumSeq(attribute.getEnumClass(), odsValues[i])));
+						ODSEnumerations.fromODSEnumSeq(attribute.getEnumObj(), odsValues[i])));
 			}
 		} else if (DataType.DT_EXTERNALREFERENCE == dataType) {
 			T_ExternalReference[] odsValues = odsValueSeq.u.extRefVal();
@@ -307,7 +307,7 @@
 			return odsValueSeq;
 		}
 
-		ValueType type = values.get(0).getValueType();
+		ValueType<?> type = values.get(0).getValueType();
 		if (ValueType.STRING == type) {
 			String[] odsValues = new String[size];
 			for (int i = 0; i < size; i++) {
@@ -674,7 +674,7 @@
 	 */
 	public static TS_Value toODSValue(Attribute attribute, Value value) throws DataAccessException {
 		TS_Value odsValue = new TS_Value(new TS_Union(), toODSValidFlag(value.isValid()));
-		ValueType type = value.getValueType();
+		ValueType<?> type = value.getValueType();
 
 		if (ValueType.STRING == type) {
 			if (((ODSAttribute) attribute).isIdAttribute()) {
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/utils/ODSEnum.java b/src/main/java/org/eclipse/mdm/api/odsadapter/utils/ODSEnum.java
new file mode 100755
index 0000000..8739c5f
--- /dev/null
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/utils/ODSEnum.java
@@ -0,0 +1,29 @@
+/*
+ * 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.odsadapter.utils;
+
+import org.eclipse.mdm.api.base.model.EnumerationValue;
+
+/**
+ * Special enumeration class for ODS enumerations
+ *
+ */
+public class ODSEnum extends EnumerationValue {
+	/**
+	 * Constructor
+	 * 
+	 * @param name: the text representation of the enumeration value
+	 * @param ordinal: the numeric representation of the enumeration value 
+	 */
+	public ODSEnum (String name, int ordinal)
+	{
+		super(name,ordinal);
+	}
+
+}
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/utils/ODSEnumerations.java b/src/main/java/org/eclipse/mdm/api/odsadapter/utils/ODSEnumerations.java
index 7c0a266..6479fac 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/utils/ODSEnumerations.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/utils/ODSEnumerations.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
@@ -13,6 +13,9 @@
 import java.util.List;
 
 import org.eclipse.mdm.api.base.model.AxisType;
+import org.eclipse.mdm.api.base.model.EnumRegistry;
+import org.eclipse.mdm.api.base.model.EnumerationValue;
+import org.eclipse.mdm.api.base.model.Enumeration;
 import org.eclipse.mdm.api.base.model.Interpolation;
 import org.eclipse.mdm.api.base.model.ScalarType;
 import org.eclipse.mdm.api.base.model.SequenceRepresentation;
@@ -63,23 +66,24 @@
 	 * @throws IllegalArgumentException
 	 *             Thrown if ODS enumeration name is unknown.
 	 */
-	@SuppressWarnings("unchecked")
-	public static <E extends Enum<?>> Class<E> getEnumClass(String name) {
+	// FIXME (Florian Schmitt): can we do this simpler?
+	public static Enumeration<? extends EnumerationValue> getEnumObj(String name) {
+		EnumRegistry er=EnumRegistry.getInstance();
 		if (SCALAR_TYPE_NAME.equals(name)) {
-			return (Class<E>) ScalarType.class;
+			return (er.get(EnumRegistry.SCALAR_TYPE));
 		} else if (STATE_NAME.equals(name)) {
-			return (Class<E>) VersionState.class;
+			return (er.get(EnumRegistry.VERSION_STATE));
 		} else if (INTERPOLATION_NAME.equals(name)) {
-			return (Class<E>) Interpolation.class;
+			return (er.get(EnumRegistry.INTERPOLATION));
 		} else if (AXIS_TYPE_NAME.equals(name)) {
-			return (Class<E>) AxisType.class;
+			return (er.get(EnumRegistry.AXIS_TYPE));
 		} else if (TYPE_SPECIFICATION_NAME.equals(name)) {
-			return (Class<E>) TypeSpecification.class;
+			return (er.get(EnumRegistry.TYPE_SPECIFICATION));
 		} else if (SEQUENCE_REPRESENTATION_NAME.equals(name)) {
-			return (Class<E>) SequenceRepresentation.class;
+			return (er.get(EnumRegistry.SEQUENCE_REPRESENTATION));
+		} else {
+		   return er.get(name);
 		}
-
-		throw new IllegalArgumentException("Enumeration mapping for name '" + name + "' does not exist.");
 	}
 
 	/**
@@ -91,25 +95,24 @@
 	 * @throws IllegalArgumentException
 	 *             Thrown if enumeration class is unknown.
 	 */
-	public static String getEnumName(Class<? extends Enum<?>> enumClass) {
-		if (enumClass == null) {
-			throw new IllegalArgumentException("Enumeration class is not allowed to be null.");
-		} else if (ScalarType.class == enumClass) {
+	public static String getEnumName(Enumeration<?> enumObj) {
+		if (enumObj == null) {
+			throw new IllegalArgumentException("EnumerationValue class is not allowed to be null.");
+		} else if (EnumRegistry.SCALAR_TYPE.equals(enumObj.getName())) {
 			return SCALAR_TYPE_NAME;
-		} else if (VersionState.class == enumClass) {
+		} else if (EnumRegistry.VERSION_STATE.equals(enumObj.getName())) {
 			return STATE_NAME;
-		} else if (Interpolation.class == enumClass) {
+		} else if (EnumRegistry.INTERPOLATION.equals(enumObj.getName())) {
 			return INTERPOLATION_NAME;
-		} else if (AxisType.class == enumClass) {
+		} else if (EnumRegistry.AXIS_TYPE.equals(enumObj.getName())) {
 			return AXIS_TYPE_NAME;
-		} else if (TypeSpecification.class == enumClass) {
+		} else if (EnumRegistry.TYPE_SPECIFICATION.equals(enumObj.getName())) {
 			return TYPE_SPECIFICATION_NAME;
-		} else if (SequenceRepresentation.class == enumClass) {
+		} else if (EnumRegistry.SEQUENCE_REPRESENTATION.equals(enumObj.getName())) {
 			return SEQUENCE_REPRESENTATION_NAME;
+		} else {
+			return enumObj.getName();
 		}
-
-		throw new IllegalArgumentException(
-				"Enumeration mapping for enumeration class '" + enumClass.getSimpleName() + "' does not exist.");
 	}
 
 	// ======================================================================
@@ -131,25 +134,17 @@
 	 *             Thrown if conversion not possible.
 	 */
 	@SuppressWarnings("unchecked")
-	static <E extends Enum<?>> E fromODSEnum(Class<E> enumClass, int value) {
-		if (enumClass == null) {
-			throw new IllegalArgumentException("Enumeration class is not allowed to be null.");
-		} else if (ScalarType.class == enumClass) {
+	//FIXME: cant we have this easier?
+	static <E extends EnumerationValue> E fromODSEnum(Enumeration<E> enumObj, int value) {
+		if (enumObj == null) {
+			throw new IllegalArgumentException("EnumerationValue class is not allowed to be null.");
+		} else if (EnumRegistry.SCALAR_TYPE.equals(enumObj.getName())) {
 			return (E) fromODSScalarType(value);
-		} else if (VersionState.class == enumClass) {
-			return (E) fromODSEnumByOrdinal(VersionState.class, value);
-		} else if (Interpolation.class == enumClass) {
-			return (E) fromODSEnumByOrdinal(Interpolation.class, value);
-		} else if (AxisType.class == enumClass) {
-			return (E) fromODSEnumByOrdinal(AxisType.class, value);
-		} else if (TypeSpecification.class == enumClass) {
-			return (E) fromODSEnumByOrdinal(TypeSpecification.class, value);
-		} else if (SequenceRepresentation.class == enumClass) {
+		} else if (EnumRegistry.SEQUENCE_REPRESENTATION.equals(enumObj.getName())) {
 			return (E) fromODSSequenceRepresentation(value);
+		} else {
+			return (E) fromODSEnumByOrdinal(enumObj, value);
 		}
-
-		throw new IllegalArgumentException(
-				"Enumeration mapping for type '" + enumClass.getSimpleName() + "' does not exist.");
 	}
 
 	/**
@@ -167,33 +162,24 @@
 	 *             Thrown if conversion not possible.
 	 */
 	@SuppressWarnings("unchecked")
-	static <E extends Enum<?>> E[] fromODSEnumSeq(Class<E> enumClass, int[] values) {
-		if (enumClass == null) {
-			throw new IllegalArgumentException("Enumeration class is not allowed to be null.");
-		} else if (ScalarType.class == enumClass) {
+	static <E extends EnumerationValue> E[] fromODSEnumSeq(Enumeration<?> enumObj, int[] values) {
+		if (enumObj == null) {
+			throw new IllegalArgumentException("EnumerationValue class is not allowed to be null.");
+		} else if (EnumRegistry.SCALAR_TYPE.equals(enumObj.getName())) {
 			List<E> scalarTypes = new ArrayList<>(values.length);
 			for (int value : values) {
 				scalarTypes.add((E) fromODSScalarType(value));
 			}
 			return (E[]) scalarTypes.toArray(new ScalarType[values.length]);
-		} else if (VersionState.class == enumClass) {
-			return (E[]) fromODSEnumSeqByOrdinal(VersionState.class, values);
-		} else if (Interpolation.class == enumClass) {
-			return (E[]) fromODSEnumSeqByOrdinal(Interpolation.class, values);
-		} else if (AxisType.class == enumClass) {
-			return (E[]) fromODSEnumSeqByOrdinal(AxisType.class, values);
-		} else if (TypeSpecification.class == enumClass) {
-			return (E[]) fromODSEnumSeqByOrdinal(TypeSpecification.class, values);
-		} else if (SequenceRepresentation.class == enumClass) {
+		} else if (EnumRegistry.SEQUENCE_REPRESENTATION.equals(enumObj.getName())) {
 			List<E> sequenceRepresentations = new ArrayList<>(values.length);
 			for (int value : values) {
 				sequenceRepresentations.add((E) fromODSSequenceRepresentation(value));
 			}
 			return (E[]) sequenceRepresentations.toArray(new SequenceRepresentation[values.length]);
+		} else {
+			return (E[]) fromODSEnumSeqByOrdinal(enumObj, values);
 		}
-
-		throw new IllegalArgumentException(
-				"Enumeration mapping for type '" + enumClass.getSimpleName() + "' does not exist.");
 	}
 
 	/**
@@ -208,7 +194,7 @@
 	 * @throws IllegalArgumentException
 	 *             Thrown if conversion not possible.
 	 */
-	static <E extends Enum<?>> int toODSEnum(E constant) {
+	static <E extends EnumerationValue> int toODSEnum(E constant) {
 		if (constant == null) {
 			return 0;
 		} else if (constant instanceof ScalarType) {
@@ -217,13 +203,13 @@
 				|| constant instanceof TypeSpecification) {
 			// NOTE: Ordinal numbers map directly to the corresponding ODS
 			// enumeration constant value.
-			return ((Enum<?>) constant).ordinal();
+			return constant.ordinal();
 		} else if (constant instanceof SequenceRepresentation) {
 			return toODSSequenceRepresentation((SequenceRepresentation) constant);
 		}
 
 		throw new IllegalArgumentException(
-				"Enumeration mapping for type '" + constant.getClass().getSimpleName() + "' does not exist.");
+				"EnumerationValue mapping for type '" + constant.getClass().getSimpleName() + "' does not exist.");
 	}
 
 	/**
@@ -238,7 +224,7 @@
 	 * @throws IllegalArgumentException
 	 *             Thrown if conversion not possible.
 	 */
-	static <E extends Enum<?>> int[] toODSEnumSeq(E[] constants) {
+	static <E extends EnumerationValue> int[] toODSEnumSeq(E[] constants) {
 		if (constants == null) {
 			return new int[0];
 		}
@@ -253,14 +239,15 @@
 			for (int i = 0; i < values.length; i++) {
 				// NOTE: Ordinal numbers directly map to the corresponding ODS
 				// enumeration constant value.
-				values[i] = ((Enum<?>) constants[i]).ordinal();
+				// FIXME: do we really want this?
+				values[i] = ((EnumerationValue) constants[i]).ordinal();
 			}
 		} else if (constants instanceof SequenceRepresentation[]) {
 			for (int i = 0; i < values.length; i++) {
 				values[i] = toODSSequenceRepresentation((SequenceRepresentation) constants[i]);
 			}
 		} else {
-			throw new IllegalArgumentException("Enumeration mapping for type '"
+			throw new IllegalArgumentException("EnumerationValue mapping for type '"
 					+ constants.getClass().getComponentType().getSimpleName() + "' does not exist.");
 		}
 
@@ -463,16 +450,14 @@
 	 * @throws IllegalArgumentException
 	 *             Thrown if conversion not possible.
 	 */
-	private static <E extends Enum<?>> E fromODSEnumByOrdinal(Class<E> enumClass, int value) {
-		E[] constants = enumClass.getEnumConstants();
-		if (value < 0 || value > constants.length) {
-			throw new IllegalArgumentException("Unable to map ODS enumeration vaue '" + value
-					+ "' to constant of type '" + enumClass.getSimpleName() + "'.");
-		}
-
+	private static <E extends EnumerationValue> E fromODSEnumByOrdinal(Enumeration<E> enumObj, int value) {
 		// NOTE: Ordinal numbers directly map to the corresponding ODS
 		// enumeration constant value.
-		return constants[value];
+		E enumvalue = enumObj.valueOf(value);
+		if (enumvalue==null) {
+			throw new IllegalArgumentException();
+		}
+		return enumvalue;
 	}
 
 	/**
@@ -491,22 +476,20 @@
 	 *             Thrown if conversion not possible.
 	 */
 	@SuppressWarnings("unchecked")
-	private static <E extends Enum<?>> E[] fromODSEnumSeqByOrdinal(Class<E> enumClass, int[] values) {
+	private static <E extends EnumerationValue> E[] fromODSEnumSeqByOrdinal(Enumeration<E> enumObj, int[] values) {
 		List<E> enumValues = new ArrayList<>(values.length);
-		E[] constants = enumClass.getEnumConstants();
 
 		for (int value : values) {
-			if (value < 0 || value > constants.length) {
-				throw new IllegalArgumentException("Unable to map ODS enumeration vaue '" + value
-						+ "' to constant of type '" + enumClass.getSimpleName() + "'.");
-			}
-
 			// NOTE: Ordinal numbers directly map to the corresponding ODS
 			// enumeration constant value.
-			enumValues.add(constants[value]);
+			E enumvalue = enumObj.valueOf(value);
+			if (enumvalue==null) {
+				throw new IllegalArgumentException();
+			}
+			enumValues.add(enumvalue);
 		}
 
-		return enumValues.toArray((E[]) Array.newInstance(enumClass, values.length));
+		return enumValues.toArray((E[]) Array.newInstance(enumObj.getClass(), values.length));
 	}
 
 }
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/utils/ODSUtils.java b/src/main/java/org/eclipse/mdm/api/odsadapter/utils/ODSUtils.java
index df5b335..1185c66 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/utils/ODSUtils.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/utils/ODSUtils.java
@@ -10,17 +10,16 @@
 
 import org.asam.ods.AggrFunc;
 import org.asam.ods.DataType;
-import org.asam.ods.JoinType;
-import org.asam.ods.RelationType;
 import org.asam.ods.SelOpcode;
 import org.asam.ods.SelOperator;
 import org.eclipse.mdm.api.base.model.ContextType;
 import org.eclipse.mdm.api.base.model.ValueType;
 import org.eclipse.mdm.api.base.query.Aggregation;
-import org.eclipse.mdm.api.base.query.Join;
-import org.eclipse.mdm.api.base.query.Operation;
-import org.eclipse.mdm.api.base.query.Operator;
-import org.eclipse.mdm.api.base.query.Relationship;
+import org.eclipse.mdm.api.base.query.BracketOperator;
+import org.eclipse.mdm.api.base.query.JoinType;
+import org.eclipse.mdm.api.base.query.ComparisonOperator;
+import org.eclipse.mdm.api.base.query.BooleanOperator;
+import org.eclipse.mdm.api.base.query.RelationType;
 
 /**
  * Utility class provides bidirectional mappings for ODS types
@@ -35,9 +34,9 @@
 	// ======================================================================
 
 	/**
-	 * Maps {@link Relationship} to the corresponding ODS {@link RelationType}.
+	 * Maps {@link RelationType} to the corresponding ODS {@link RelationType}.
 	 */
-	public static final BiDiMapper<Relationship, RelationType> RELATIONSHIPS = new BiDiMapper<>();
+	public static final BiDiMapper<RelationType, org.asam.ods.RelationType> RELATIONSHIPS = new BiDiMapper<>();
 
 	/**
 	 * Maps {@link Aggregation} to the corresponding ODS {@link AggrFunc}.
@@ -50,29 +49,34 @@
 	public static final BiDiMapper<ContextType, String> CONTEXTTYPES = new BiDiMapper<>();
 
 	/**
-	 * Maps {@link Operation} to the corresponding ODS {@link SelOpcode}.
+	 * Maps {@link ComparisonOperator} to the corresponding ODS {@link SelOpcode}.
 	 */
-	public static final BiDiMapper<Operation, SelOpcode> OPERATIONS = new BiDiMapper<>();
+	public static final BiDiMapper<ComparisonOperator, SelOpcode> OPERATIONS = new BiDiMapper<>();
 
 	/**
-	 * Maps {@link Operator} to the corresponding ODS {@link SelOperator}.
+	 * Maps {@link BooleanOperator} to the corresponding ODS {@link SelOperator}.
 	 */
-	public static final BiDiMapper<Operator, SelOperator> OPERATORS = new BiDiMapper<>();
+	public static final BiDiMapper<BooleanOperator, SelOperator> OPERATORS = new BiDiMapper<>();
+	
+	/**
+	 * Maps {@link BracketOperator} to the corresponding ODS {@link SelOperator}.
+	 */
+	public static final BiDiMapper<BracketOperator, SelOperator> BRACKETOPERATORS = new BiDiMapper<>();
 
 	/**
 	 * Maps {@link ValueType} to the corresponding ODS {@link DataType}.
 	 */
-	public static final BiDiMapper<ValueType, DataType> VALUETYPES = new BiDiMapper<>();
+	public static final BiDiMapper<ValueType<?>, DataType> VALUETYPES = new BiDiMapper<>();
 
 	/**
-	 * Maps {@link Join} to the corresponding ODS {@link JoinType}.
+	 * Maps {@link JoinType} to the corresponding ODS {@link org.asam.ods.JoinType}.
 	 */
-	public static final BiDiMapper<Join, JoinType> JOINS = new BiDiMapper<>();
+	public static final BiDiMapper<JoinType, org.asam.ods.JoinType> JOINS = new BiDiMapper<>();
 
 	static {
-		RELATIONSHIPS.addMappings(Relationship.FATHER_CHILD, RelationType.FATHER_CHILD);
-		RELATIONSHIPS.addMappings(Relationship.INFO, RelationType.INFO);
-		RELATIONSHIPS.addMappings(Relationship.INHERITANCE, RelationType.INHERITANCE);
+		RELATIONSHIPS.addMappings(RelationType.FATHER_CHILD, org.asam.ods.RelationType.FATHER_CHILD);
+		RELATIONSHIPS.addMappings(RelationType.INFO, org.asam.ods.RelationType.INFO);
+		RELATIONSHIPS.addMappings(RelationType.INHERITANCE, org.asam.ods.RelationType.INHERITANCE);
 
 		AGGREGATIONS.addMappings(Aggregation.NONE, AggrFunc.NONE);
 		AGGREGATIONS.addMappings(Aggregation.COUNT, AggrFunc.COUNT);
@@ -88,35 +92,36 @@
 		CONTEXTTYPES.addMappings(ContextType.TESTSEQUENCE, "TestSequence");
 		CONTEXTTYPES.addMappings(ContextType.TESTEQUIPMENT, "TestEquipment");
 
-		OPERATIONS.addMappings(Operation.LIKE, SelOpcode.LIKE);
-		OPERATIONS.addMappings(Operation.CASE_INSENSITIVE_LIKE, SelOpcode.CI_LIKE);
-		OPERATIONS.addMappings(Operation.NOT_LIKE, SelOpcode.NOTLIKE);
-		OPERATIONS.addMappings(Operation.CASE_INSENSITIVE_NOT_LIKE, SelOpcode.CI_NOTLIKE);
-		OPERATIONS.addMappings(Operation.EQUAL, SelOpcode.EQ);
-		OPERATIONS.addMappings(Operation.CASE_INSENSITIVE_EQUAL, SelOpcode.CI_EQ);
-		OPERATIONS.addMappings(Operation.NOT_EQUAL, SelOpcode.NEQ);
-		OPERATIONS.addMappings(Operation.CASE_INSENSITIVE_NOT_EQUAL, SelOpcode.CI_NEQ);
-		OPERATIONS.addMappings(Operation.GREATER_THAN, SelOpcode.GT);
-		OPERATIONS.addMappings(Operation.CASE_INSENSITIVE_GREATER_THAN, SelOpcode.CI_GT);
-		OPERATIONS.addMappings(Operation.GREATER_THAN_OR_EQUAL, SelOpcode.GTE);
-		OPERATIONS.addMappings(Operation.CASE_INSENSITIVE_GREATER_THAN_OR_EQUAL, SelOpcode.CI_GTE);
-		OPERATIONS.addMappings(Operation.LESS_THAN, SelOpcode.LT);
-		OPERATIONS.addMappings(Operation.CASE_INSENSITIVE_LESS_THAN, SelOpcode.CI_LT);
-		OPERATIONS.addMappings(Operation.LESS_THAN_OR_EQUAL, SelOpcode.LTE);
-		OPERATIONS.addMappings(Operation.CASE_INSENSITIVE_LESS_THAN_OR_EQUAL, SelOpcode.CI_LTE);
-		OPERATIONS.addMappings(Operation.IS_NULL, SelOpcode.IS_NULL);
-		OPERATIONS.addMappings(Operation.IS_NOT_NULL, SelOpcode.IS_NOT_NULL);
-		OPERATIONS.addMappings(Operation.IN_SET, SelOpcode.INSET);
-		OPERATIONS.addMappings(Operation.CASE_INSENSITIVE_IN_SET, SelOpcode.CI_INSET);
-		OPERATIONS.addMappings(Operation.NOT_IN_SET, SelOpcode.NOTINSET);
-		OPERATIONS.addMappings(Operation.CASE_INSENSITIVE_NOT_IN_SET, SelOpcode.CI_NOTINSET);
-		OPERATIONS.addMappings(Operation.BETWEEN, SelOpcode.BETWEEN);
+		OPERATIONS.addMappings(ComparisonOperator.LIKE, SelOpcode.LIKE);
+		OPERATIONS.addMappings(ComparisonOperator.CASE_INSENSITIVE_LIKE, SelOpcode.CI_LIKE);
+		OPERATIONS.addMappings(ComparisonOperator.NOT_LIKE, SelOpcode.NOTLIKE);
+		OPERATIONS.addMappings(ComparisonOperator.CASE_INSENSITIVE_NOT_LIKE, SelOpcode.CI_NOTLIKE);
+		OPERATIONS.addMappings(ComparisonOperator.EQUAL, SelOpcode.EQ);
+		OPERATIONS.addMappings(ComparisonOperator.CASE_INSENSITIVE_EQUAL, SelOpcode.CI_EQ);
+		OPERATIONS.addMappings(ComparisonOperator.NOT_EQUAL, SelOpcode.NEQ);
+		OPERATIONS.addMappings(ComparisonOperator.CASE_INSENSITIVE_NOT_EQUAL, SelOpcode.CI_NEQ);
+		OPERATIONS.addMappings(ComparisonOperator.GREATER_THAN, SelOpcode.GT);
+		OPERATIONS.addMappings(ComparisonOperator.CASE_INSENSITIVE_GREATER_THAN, SelOpcode.CI_GT);
+		OPERATIONS.addMappings(ComparisonOperator.GREATER_THAN_OR_EQUAL, SelOpcode.GTE);
+		OPERATIONS.addMappings(ComparisonOperator.CASE_INSENSITIVE_GREATER_THAN_OR_EQUAL, SelOpcode.CI_GTE);
+		OPERATIONS.addMappings(ComparisonOperator.LESS_THAN, SelOpcode.LT);
+		OPERATIONS.addMappings(ComparisonOperator.CASE_INSENSITIVE_LESS_THAN, SelOpcode.CI_LT);
+		OPERATIONS.addMappings(ComparisonOperator.LESS_THAN_OR_EQUAL, SelOpcode.LTE);
+		OPERATIONS.addMappings(ComparisonOperator.CASE_INSENSITIVE_LESS_THAN_OR_EQUAL, SelOpcode.CI_LTE);
+		OPERATIONS.addMappings(ComparisonOperator.IS_NULL, SelOpcode.IS_NULL);
+		OPERATIONS.addMappings(ComparisonOperator.IS_NOT_NULL, SelOpcode.IS_NOT_NULL);
+		OPERATIONS.addMappings(ComparisonOperator.IN_SET, SelOpcode.INSET);
+		OPERATIONS.addMappings(ComparisonOperator.CASE_INSENSITIVE_IN_SET, SelOpcode.CI_INSET);
+		OPERATIONS.addMappings(ComparisonOperator.NOT_IN_SET, SelOpcode.NOTINSET);
+		OPERATIONS.addMappings(ComparisonOperator.CASE_INSENSITIVE_NOT_IN_SET, SelOpcode.CI_NOTINSET);
+		OPERATIONS.addMappings(ComparisonOperator.BETWEEN, SelOpcode.BETWEEN);
 
-		OPERATORS.addMappings(Operator.AND, SelOperator.AND);
-		OPERATORS.addMappings(Operator.OR, SelOperator.OR);
-		OPERATORS.addMappings(Operator.NOT, SelOperator.NOT);
-		OPERATORS.addMappings(Operator.OPEN, SelOperator.OPEN);
-		OPERATORS.addMappings(Operator.CLOSE, SelOperator.CLOSE);
+		OPERATORS.addMappings(BooleanOperator.AND, SelOperator.AND);
+		OPERATORS.addMappings(BooleanOperator.OR, SelOperator.OR);
+		OPERATORS.addMappings(BooleanOperator.NOT, SelOperator.NOT);
+		
+		BRACKETOPERATORS.addMappings(BracketOperator.OPEN, SelOperator.OPEN);
+		BRACKETOPERATORS.addMappings(BracketOperator.CLOSE, SelOperator.CLOSE);
 
 		VALUETYPES.addMappings(ValueType.UNKNOWN, DataType.DT_UNKNOWN);
 		VALUETYPES.addMappings(ValueType.STRING, DataType.DT_STRING);
@@ -149,8 +154,8 @@
 		VALUETYPES.addMappings(ValueType.FILE_LINK_SEQUENCE, DataType.DS_EXTERNALREFERENCE);
 		VALUETYPES.addMappings(ValueType.BLOB, DataType.DT_BLOB);
 
-		JOINS.addMappings(Join.INNER, org.asam.ods.JoinType.JTDEFAULT);
-		JOINS.addMappings(Join.OUTER, org.asam.ods.JoinType.JTOUTER);
+		JOINS.addMappings(JoinType.INNER, org.asam.ods.JoinType.JTDEFAULT);
+		JOINS.addMappings(JoinType.OUTER, org.asam.ods.JoinType.JTOUTER);
 	}
 
 	public static boolean isValidID(String instanceID) {
diff --git a/src/test/java/org/eclipse/mdm/api/odsadapter/JoinTest.java b/src/test/java/org/eclipse/mdm/api/odsadapter/JoinTest.java
index ad64fa6..a4694d9 100644
--- a/src/test/java/org/eclipse/mdm/api/odsadapter/JoinTest.java
+++ b/src/test/java/org/eclipse/mdm/api/odsadapter/JoinTest.java
@@ -38,7 +38,7 @@
 import org.slf4j.LoggerFactory;

 

 /**

- * Join test

+ * JoinType test

  *

  * @since 1.0.0

  * @author jst, Peak Solution GmbH

diff --git a/src/test/java/org/eclipse/mdm/api/odsadapter/search/ODSSearchServiceTest.java b/src/test/java/org/eclipse/mdm/api/odsadapter/search/ODSSearchServiceTest.java
index b6b848a..af37982 100644
--- a/src/test/java/org/eclipse/mdm/api/odsadapter/search/ODSSearchServiceTest.java
+++ b/src/test/java/org/eclipse/mdm/api/odsadapter/search/ODSSearchServiceTest.java
@@ -20,8 +20,9 @@
 import org.eclipse.mdm.api.base.query.Filter;

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

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

-import org.eclipse.mdm.api.base.query.Operation;

-import org.eclipse.mdm.api.base.query.Operator;

+import org.eclipse.mdm.api.base.query.BracketOperator;

+import org.eclipse.mdm.api.base.query.ComparisonOperator;

+import org.eclipse.mdm.api.base.query.BooleanOperator;

 import org.eclipse.mdm.api.dflt.EntityManager;

 import org.eclipse.mdm.api.odsadapter.ODSEntityManagerFactory;

 import org.junit.AfterClass;

@@ -94,10 +95,11 @@
 

 		@Override

 		public Tuple extract(FilterItem f) {

-			return tuple(f.isOperator() ? f.getOperator() : null,

+			return tuple(f.isBooleanOperator() ? f.getBooleanOperator() : null,

 					f.isCondition() ? f.getCondition().getAttribute().getName() : null,

-					f.isCondition() ? f.getCondition().getOperation() : null,

-					f.isCondition() ? f.getCondition().getValue().extract() : null);

+					f.isCondition() ? f.getCondition().getComparisonOperator() : null,

+					f.isCondition() ? f.getCondition().getValue().extract() : null,

+					f.isBracketOperator() ?f.getBracketOperator() : null);

 		}

 	};

 

@@ -113,11 +115,13 @@
 		EntityType testStep = modelManager.getEntityType(TestStep.class);

 

 		assertThat(service.getMergedFilter(Filter.idOnly(testStep, "11"), "query")).hasSize(7)

-				.extracting(filterExtractors).containsExactly(tuple(Operator.OPEN, null, null, null),

-						tuple(null, "Id", Operation.EQUAL, "10"), tuple(Operator.CLOSE, null, null, null),

-						tuple(Operator.AND, null, null, null), tuple(Operator.OPEN, null, null, null),

-						tuple(null, "Id", Operation.IN_SET, new String[] { "10" }),

-						tuple(Operator.CLOSE, null, null, null));

+				.extracting(filterExtractors).containsExactly(tuple(null, null, null, null, BracketOperator.OPEN),

+						tuple(null, "Id", ComparisonOperator.EQUAL, "10"),

+						tuple(null, null, null, null, BracketOperator.CLOSE),

+						tuple(BooleanOperator.AND, null, null, null, null),

+						tuple(null, null, null, null, BracketOperator.OPEN),

+						tuple(null, "Id", ComparisonOperator.IN_SET, new String[] { "10" }, null),

+						tuple(null, null, null, null, BracketOperator.CLOSE));

 	}

 

 	@Test

@@ -128,7 +132,7 @@
 				.fetchIds(Mockito.anyString());

 

 		assertThat(service.getMergedFilter(Filter.and(), "query")).extracting(filterExtractors)

-				.containsExactly(tuple(null, "Id", Operation.IN_SET, new String[] { "10" }));

+				.containsExactly(tuple(null, "Id", ComparisonOperator.IN_SET, new String[] { "10" }));

 	}

 

 	@Test

@@ -140,7 +144,7 @@
 		EntityType testStep = modelManager.getEntityType(TestStep.class);

 

 		assertThat(service.getMergedFilter(Filter.idOnly(testStep, "11"), "")).extracting(filterExtractors)

-				.containsExactly(tuple(null, "Id", Operation.EQUAL, "11"));

+				.containsExactly(tuple(null, "Id", ComparisonOperator.EQUAL, "11"));

 	}

 

 	@Test