Adds code that is needed to enable roles/permission delegation to backends

Replace BiDiMappter contraption with ImmutableBiMap

OMR-15: created ods session passing for_user for which session shall be created.

Refactored and fixed creation of session parameters as for_user is not mandatory

JIRA: OMR-15

Add logging to creating the session parameters string

JIRA: OMR-15

Add last changes

Signed-off-by: Silvio Heuberger <silvio.heuberger@gmail.com>
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/ODSContext.java b/src/main/java/org/eclipse/mdm/api/odsadapter/ODSContext.java
index d924057..c9a3dda 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/ODSContext.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/ODSContext.java
@@ -7,17 +7,12 @@
  */
 package org.eclipse.mdm.api.odsadapter;
 
-import java.util.Map;
-import java.util.Optional;
-
+import com.highqsoft.corbafileserver.generated.CORBAFileServerIF;
 import org.asam.ods.AoException;
 import org.asam.ods.AoSession;
-import org.asam.ods.ElemId;
-import org.asam.ods.InstanceElement;
 import org.eclipse.mdm.api.base.ConnectionException;
 import org.eclipse.mdm.api.base.adapter.ModelManager;
 import org.eclipse.mdm.api.base.file.FileService;
-import org.eclipse.mdm.api.base.model.Entity;
 import org.eclipse.mdm.api.base.notification.NotificationService;
 import org.eclipse.mdm.api.base.query.DataAccessException;
 import org.eclipse.mdm.api.base.query.QueryService;
@@ -30,16 +25,15 @@
 import org.eclipse.mdm.api.odsadapter.lookup.EntityLoader;
 import org.eclipse.mdm.api.odsadapter.notification.ODSNotificationServiceFactory;
 import org.eclipse.mdm.api.odsadapter.query.ODSEntityFactory;
-import org.eclipse.mdm.api.odsadapter.query.ODSEntityType;
 import org.eclipse.mdm.api.odsadapter.query.ODSModelManager;
 import org.eclipse.mdm.api.odsadapter.query.ODSQueryService;
 import org.eclipse.mdm.api.odsadapter.search.ODSSearchService;
-import org.eclipse.mdm.api.odsadapter.utils.ODSConverter;
 import org.omg.CORBA.ORB;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.highqsoft.corbafileserver.generated.CORBAFileServerIF;
+import java.util.Map;
+import java.util.Optional;
 
 /**
  * ODSContext encapsulates a session to the ASAM ODS CORBA API and 
@@ -69,7 +63,7 @@
 	 * @param parameters
 	 * @throws AoException
 	 */
-	ODSContext(ORB orb, AoSession aoSession, CORBAFileServerIF fileServer, Map<String, String> parameters) throws AoException {
+	public ODSContext(ORB orb, AoSession aoSession, CORBAFileServerIF fileServer, Map<String, String> parameters) throws AoException {
 		this.fileServer = fileServer;
 		this.parameters = parameters;
 		
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/ODSContextFactory.java b/src/main/java/org/eclipse/mdm/api/odsadapter/ODSContextFactory.java
index 308e591..ed59726 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/ODSContextFactory.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/ODSContextFactory.java
@@ -11,6 +11,9 @@
 import java.util.HashMap;
 import java.util.Map;
 
+import com.google.common.base.Joiner;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableMap;
 import org.asam.ods.AoException;
 import org.asam.ods.AoFactory;
 import org.asam.ods.AoFactoryHelper;
@@ -52,9 +55,9 @@
 
 	public static final String PARAM_PASSWORD = "password";
 
-	public static final String PARAM_ELASTIC_SEARCH_URL = "elasticsearch.url";
+	private static final String PARAM_FOR_USER = "for_user";
 
-	private static final String AUTH_TEMPLATE = "USER=%s,PASSWORD=%s,CREATE_COSESSION_ALLOWED=TRUE";
+	private static final String AUTH_TEMPLATE = "USER=%s,PASSWORD=%s,CREATE_COSESSION_ALLOWED=TRUE,FOR_USER=%s";
 
 	private static final Logger LOGGER = LoggerFactory.getLogger(ODSContextFactory.class);
 
@@ -84,7 +87,6 @@
 	 * <li>{@value #PARAM_SERVICENAME}</li>
 	 * <li>{@value #PARAM_USER}</li>
 	 * <li>{@value #PARAM_PASSWORD}</li>
-	 * <li>{@value #PARAM_ELASTIC_SEARCH_URL}</li>
 	 * </ul>
 	 *
 	 * Listed names are available via public fields of this class.
@@ -95,31 +97,50 @@
 		try (ServiceLocator serviceLocator = new ServiceLocator(orb, getParameter(parameters, PARAM_NAMESERVICE))) {
 			String nameOfService = getParameter(parameters, PARAM_SERVICENAME).replace(".ASAM-ODS", "");
 
+
+
 			AoFactory aoFactory = serviceLocator.resolveFactory(nameOfService);
 			LOGGER.info("Connecting to ODS Server ...");
 
+			LOGGER.info("Connecting to ODS Server ...");
+
 			LOGGER.info("AoFactory name: {}", aoFactory.getName());
 			LOGGER.info("AoFactory description: {}", aoFactory.getDescription());
 			LOGGER.info("AoFactory interface version: {}", aoFactory.getInterfaceVersion());
 			LOGGER.info("AoFactory type: {}", aoFactory.getType());
 
-			aoSession = aoFactory.newSession(String.format(AUTH_TEMPLATE, getParameter(parameters, PARAM_USER),
-					getParameter(parameters, PARAM_PASSWORD)));
+			aoSession = aoFactory.newSession(sessionParametersAsString(parameters));
+
 			LOGGER.info("Connection to ODS server established.");
 
 			CORBAFileServerIF fileServer = serviceLocator.resolveFileServer(nameOfService);
-		
+
 			// Create a parameters map without password (which should not be visible from this point onwards),
 			// leaving the original map untouched:
 			Map<String, String> mapParams = new HashMap<>(parameters);
 			mapParams.remove(PARAM_PASSWORD);
-			return new ODSContext(orb, aoSession, fileServer, mapParams); 
+			return new ODSContext(orb, aoSession, fileServer, mapParams);
 		} catch (AoException e) {
 			closeSession(aoSession);
 			throw new ConnectionException("Unable to connect to ODS server due to: " + e.reason, e);
 		}
 	}
 
+	private String sessionParametersAsString(Map<String, String> parameters) throws ConnectionException {
+		ImmutableMap.Builder<String, String> builder = ImmutableMap.<String, String>builder()
+				.put("USER", getParameter(parameters, PARAM_USER))
+				.put("PASSWORD", getParameter(parameters, PARAM_PASSWORD))
+				.put("CREATE_COSESSION_ALLOWED", "TRUE");
+
+		String forUserName = parameters.get(PARAM_FOR_USER);
+		if(!Strings.isNullOrEmpty(forUserName)) {
+			builder.put("FOR_USER", forUserName);
+		}
+		String result = Joiner.on(",").withKeyValueSeparator("=").join(builder.build());
+		LOGGER.debug("Connecting to ODS using the connection parameters: {}", result);
+		return result;
+	}
+
 	// ======================================================================
 	// Private methods
 	// ======================================================================
@@ -260,4 +281,4 @@
 
 	}
 
-}
+}
\ No newline at end of file
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 769aaef..430f06b 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
@@ -53,7 +53,7 @@
 	 *            The ODS meta data for this attribute.
 	 * @param unit
 	 *            The unit name.
-	 * @param enumClass
+	 * @param enumObj
 	 *            The enumeration class, may be null.
 	 */
 	ODSAttribute(EntityType entityType, ApplAttr applAttr, String unit, Enumeration<?> enumObj) {
@@ -65,7 +65,7 @@
 			valueType = ValueType.STRING;
 			isIdAttribute = true;
 		} else {
-			valueType = ODSUtils.VALUETYPES.revert(applAttr.dType);
+			valueType = ODSUtils.VALUETYPES.inverse().get(applAttr.dType);
 			isIdAttribute = false;
 		}
 
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 4a2df93..b4d8194 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,719 +1,738 @@
-/*

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

- * http://www.eclipse.org/legal/epl-v10.html

- */

-

-package org.eclipse.mdm.api.odsadapter.query;

-

-import static java.util.stream.Collectors.groupingBy;

-

-import java.util.ArrayList;

-import java.util.Collections;

-import java.util.HashMap;

-import java.util.List;

-import java.util.Locale;

-import java.util.Map;

-import java.util.Optional;

-import java.util.concurrent.locks.Lock;

-import java.util.concurrent.locks.ReentrantReadWriteLock;

-import java.util.stream.Stream;

-

-import org.asam.ods.AIDName;

-import org.asam.ods.AggrFunc;

-import org.asam.ods.AoException;

-import org.asam.ods.AoSession;

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

-import org.asam.ods.SelItem;

-import org.asam.ods.SelOrder;

-import org.asam.ods.T_LONGLONG;

-import org.eclipse.mdm.api.base.adapter.EntityType;

-import org.eclipse.mdm.api.base.adapter.ModelManager;

-import org.eclipse.mdm.api.base.adapter.Relation;

-import org.eclipse.mdm.api.base.model.Channel;

-import org.eclipse.mdm.api.base.model.ChannelGroup;

-import org.eclipse.mdm.api.base.model.ContextComponent;

-import org.eclipse.mdm.api.base.model.ContextRoot;

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

-import org.eclipse.mdm.api.base.model.ParameterSet;

-import org.eclipse.mdm.api.base.model.PhysicalDimension;

-import org.eclipse.mdm.api.base.model.Quantity;

-import org.eclipse.mdm.api.base.model.Sortable;

-import org.eclipse.mdm.api.base.model.Test;

-import org.eclipse.mdm.api.base.model.TestStep;

-import org.eclipse.mdm.api.base.model.Unit;

-import org.eclipse.mdm.api.base.model.User;

-import org.eclipse.mdm.api.dflt.model.CatalogAttribute;

-import org.eclipse.mdm.api.dflt.model.CatalogComponent;

-import org.eclipse.mdm.api.dflt.model.CatalogSensor;

-import org.eclipse.mdm.api.dflt.model.Pool;

-import org.eclipse.mdm.api.dflt.model.Project;

-import org.eclipse.mdm.api.dflt.model.TemplateAttribute;

-import org.eclipse.mdm.api.dflt.model.TemplateComponent;

-import org.eclipse.mdm.api.dflt.model.TemplateRoot;

-import org.eclipse.mdm.api.dflt.model.TemplateSensor;

-import org.eclipse.mdm.api.dflt.model.TemplateTest;

-import org.eclipse.mdm.api.dflt.model.TemplateTestStep;

-import org.eclipse.mdm.api.dflt.model.TemplateTestStepUsage;

-import org.eclipse.mdm.api.dflt.model.ValueList;

-import org.eclipse.mdm.api.dflt.model.ValueListValue;

-import org.eclipse.mdm.api.dflt.model.Versionable;

-import org.eclipse.mdm.api.odsadapter.lookup.config.EntityConfig;

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

-import org.slf4j.Logger;

-import org.slf4j.LoggerFactory;

-

-/**

- * ODS implementation of the {@link ModelManager} interface.

- *

- * @since 1.0.0

- * @author Viktor Stoehr, Gigatronik Ingolstadt GmbH

- */

-public class ODSModelManager implements ModelManager {

-

-	private static final Logger LOGGER = LoggerFactory.getLogger(ODSModelManager.class);

-

-	private final Map<String, EntityType> entityTypesByName = new HashMap<>();

-

-	

-	private final ORB orb;

-

-	private final Lock write;

-	private final Lock read;

-

-	private EntityConfigRepository entityConfigRepository;

-

-	private ApplElemAccess applElemAccess;

-	private AoSession aoSession;

-

-	/**

-	 * Constructor.

-	 *

-	 * @param orb

-	 *            Used to activate CORBA service objects.

-	 * @param aoSession

-	 *            The underlying ODS session.

-	 * @throws AoException

-	 *             Thrown on errors.

-	 */

-	public ODSModelManager(ORB orb, AoSession aoSession) throws AoException {

-		this.aoSession = aoSession;

-		this.orb = orb;

-		applElemAccess = aoSession.getApplElemAccess();

-

-		// setup locks

-		ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();

-		write = reentrantReadWriteLock.writeLock();

-		read = reentrantReadWriteLock.readLock();

-

-		initialize();

-	}

-

-	/**

-	 * Returns the {@link ORB}.

-	 *

-	 * @return The {@code ORB} is returned.

-	 */

-	public ORB getORB() {

-		return orb;

-	}

-

-	/**

-	 * Returns the non root {@link EntityConfig} for given {@link Key}.

-	 *

-	 * @param <T>

-	 *            The concrete entity type.

-	 * @param key

-	 *            Used as identifier.

-	 * @return The non root {@code EntityConfig} is returned.

-	 */

-	public <T extends Entity> EntityConfig<T> findEntityConfig(Key<T> key) {

-		read.lock();

-

-		try {

-			return entityConfigRepository.find(key);

-		} finally {

-			read.unlock();

-		}

-	}

-

-	/**

-	 * Returns the root {@link EntityConfig} for given {@link Key}.

-	 *

-	 * @param <T>

-	 *            The concrete entity type.

-	 * @param key

-	 *            Used as identifier.

-	 * @return The root {@code EntityConfig} is returned.

-	 */

-	public <T extends Entity> EntityConfig<T> getEntityConfig(Key<T> key) {

-		read.lock();

-

-		try {

-			return entityConfigRepository.findRoot(key);

-		} finally {

-			read.unlock();

-		}

-	}

-

-	/**

-	 * Returns the {@link EntityConfig} associated with given

-	 * {@link EntityType}.

-	 *

-	 * @param entityType

-	 *            Used as identifier.

-	 * @return The {@code EntityConfig} is returned.

-	 */

-	public EntityConfig<?> getEntityConfig(EntityType entityType) {

-		read.lock();

-

-		try {

-			return entityConfigRepository.find(entityType);

-		} finally {

-			read.unlock();

-		}

-	}

-

-	/**

-	 * {@inheritDoc}

-	 */

-	@Override

-	public List<EntityType> listEntityTypes() {

-		read.lock();

-

-		try {

-			return Collections.unmodifiableList(new ArrayList<>(entityTypesByName.values()));

-		} finally {

-			read.unlock();

-		}

-	}

-

-	/**

-	 * {@inheritDoc}

-	 */

-	@Override

-	public EntityType getEntityType(Class<? extends Entity> entityClass) {

-		read.lock();

-

-		try {

-			return getEntityConfig(new Key<>(entityClass)).getEntityType();

-		} finally {

-			read.unlock();

-		}

-	}

-

-	/**

-	 * {@inheritDoc}

-	 */

-	@Override

-	public EntityType getEntityType(Class<? extends Entity> entityClass, ContextType contextType) {

-		read.lock();

-

-		try {

-			return getEntityConfig(new Key<>(entityClass, contextType)).getEntityType();

-		} finally {

-			read.unlock();

-		}

-	}

-

-	/**

-	 * {@inheritDoc}

-	 */

-	@Override

-	public EntityType getEntityType(String name) {

-		read.lock();

-

-		try {

-			EntityType entityType = entityTypesByName.get(name);

-			if (entityType == null) {

-				throw new IllegalArgumentException("Entity with name '" + name + "' not found.");

-			}

-

-			return entityType;

-		} finally {

-			read.unlock();

-		}

-	}

-

-	@Override

-	public EntityType getEntityTypeById(String id) {

-		Optional<EntityType> entityType = listEntityTypes().stream().filter(et -> et.getId().equals(id)).findFirst();

-		if (!entityType.isPresent()) {

-			throw new IllegalArgumentException("Entity with id '" + id + "' not found.");

-		}

-

-		return entityType.get();

-	}

-

-	/**

-	 * Returns the {@link AoSession} of this model manager.

-	 *

-	 * @return The {@code AoSession} is returned.

-	 */

-	public AoSession getAoSession() {

-		write.lock();

-

-		try {

-			return aoSession;

-		} finally {

-			write.unlock();

-		}

-	}

-

-	/**

-	 * Returns the {@link ApplElemAccess} of this model manager.

-	 *

-	 * @return The {@code ApplElemAccess} is returned.

-	 */

-	public ApplElemAccess getApplElemAccess() {

-		read.lock();

-

-		try {

-			return applElemAccess;

-		} finally {

-			read.unlock();

-		}

-	}

-

-	/**

-	 * Closes the ODS connection.

-	 *

-	 * @throws AoException

-	 *             Thrown on errors.

-	 */

-	public void close() throws AoException {

-		read.lock();

-

-		try {

-			applElemAccess._release();

-			aoSession.close();

-		} finally {

-			read.unlock();

-			aoSession._release();

-		}

-	}

-

-	/**

-	 * Reloads the complete session context.

-	 */

-	public void reloadApplicationModel() {

-		write.lock();

-

-		AoSession aoSessionOld = aoSession;

-		ApplElemAccess applElemAccessOld = applElemAccess;

-		try {

-			entityTypesByName.clear();

-

-			aoSession = aoSession.createCoSession();

-			applElemAccess = aoSession.getApplElemAccess();

-			initialize();

-		} catch (AoException e) {

-			LOGGER.error("Unable to reload the application model due to: " + e.reason, e);

-		} finally {

-			write.unlock();

-		}

-

-		try {

-			applElemAccessOld._release();

-			aoSessionOld.close();

-		} catch (AoException e) {

-			LOGGER.debug("Unable to close replaced session due to: " + e.reason, e);

-		} finally {

-			aoSessionOld._release();

-		}

-	}

-

-	/**

-	 * Initializes this model manager by caching the application model and

-	 * loading the {@link EntityConfig}s.

-	 *

-	 * @throws AoException

-	 *             Thrown on errors.

-	 */

-	private void initialize() throws AoException {

-		loadApplicationModel();

-		loadEntityConfigurations();

-	}

-

-	/**

-	 * Caches the whole application model as provided by the ODS session.

-	 *

-	 * @throws AoException

-	 *             Thrown on errors.

-	 */

-	private void loadApplicationModel() throws AoException {

-		LOGGER.debug("Reading the application model...");

-		long start = System.currentTimeMillis();

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

-		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();

-				for (String item : listItemNames) {

-					int ordinal=enumdef.getItem(item);

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

-				}

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

-			}

-

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

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

-		}

-

-		ApplicationStructureValue applicationStructureValue = aoSession.getApplicationStructureValue();

-		Map<String, String> units = getUnitMapping(applicationStructureValue.applElems);

-

-		// create entity types (incl. attributes)

-		Map<String, ODSEntityType> entityTypesByID = new HashMap<>();

-		String sourceName = aoSession.getName();

-		for (ApplElem applElem : applicationStructureValue.applElems) {

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

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

-

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

-			entityTypesByName.put(applElem.aeName, entityType);

-			entityTypesByID.put(odsID, entityType);

-		}

-

-		// create relations

-		List<Relation> relations = new ArrayList<>();

-		for (ApplRel applRel : applicationStructureValue.applRels) {

-			EntityType source = entityTypesByID.get(Long.toString(ODSConverter.fromODSLong(applRel.elem1)));

-			EntityType target = entityTypesByID.get(Long.toString(ODSConverter.fromODSLong(applRel.elem2)));

-			relations.add(new ODSRelation(applRel, source, target));

-		}

-

-		// assign relations to their source entity types

-		relations.stream().collect(groupingBy(Relation::getSource))

-				.forEach((e, r) -> ((ODSEntityType) e).setRelations(r));

-

-		long stop = System.currentTimeMillis();

-		LOGGER.debug("{} entity types with {} relations found in {} ms.", entityTypesByName.size(), relations.size(),

-				stop - start);

-	}

-

-	/**

-	 * Loads all available {@link Unit} names mapped by their instance IDs.

-	 *

-	 * @param applElems

-	 *            The application element meta data instances.

-	 * @return The unit names mapped by the corresponding instance IDs.

-	 * @throws AoException

-	 *             Thrown if unable to load the unit mappings.

-	 */

-	private Map<String, String> getUnitMapping(ApplElem[] applElems) throws AoException {

-		ApplElem unitElem = Stream.of(applElems).filter(ae -> ae.beName.equals("AoUnit")).findAny()

-				.orElseThrow(() -> new IllegalStateException("Application element 'Unit' is not defined."));

-

-		QueryStructureExt qse = new QueryStructureExt();

-		qse.anuSeq = new SelAIDNameUnitId[] {

-				new SelAIDNameUnitId(new AIDName(unitElem.aid, "Id"), new T_LONGLONG(), AggrFunc.NONE),

-				new SelAIDNameUnitId(new AIDName(unitElem.aid, "Name"), new T_LONGLONG(), AggrFunc.NONE) };

-		qse.condSeq = new SelItem[0];

-		qse.groupBy = new AIDName[0];

-		qse.joinSeq = new JoinDef[0];

-		qse.orderBy = new SelOrder[0];

-

-		Map<String, String> units = new HashMap<>();

-		ElemResultSetExt unitResultSetExt = getApplElemAccess().getInstancesExt(qse, 0)[0].firstElems[0];

-		for (int i = 0; i < unitResultSetExt.values[0].value.flag.length; i++) {

-			String unitID = Long

-					.toString(ODSConverter.fromODSLong(unitResultSetExt.values[0].value.u.longlongVal()[i]));

-			String unitName = unitResultSetExt.values[1].value.u.stringVal()[i];

-			units.put(unitID, unitName);

-		}

-

-		return units;

-	}

-

-	/**

-	 * Loads the {@link EntityConfig}s.

-	 */

-	private void loadEntityConfigurations() {

-		LOGGER.debug("Loading entity configurations...");

-		long start = System.currentTimeMillis();

-

-		entityConfigRepository = new EntityConfigRepository();

-

-		// Environment | Project | Pool | PhysicalDimension | User | Measurement

-		// | ChannelGroup

-		entityConfigRepository.register(create(new Key<>(Environment.class), "Environment", false));

-		entityConfigRepository.register(create(new Key<>(Project.class), "Project", false));

-		entityConfigRepository.register(create(new Key<>(Pool.class), "StructureLevel", true));

-		entityConfigRepository.register(create(new Key<>(PhysicalDimension.class), "PhysDimension", false));

-		entityConfigRepository.register(create(new Key<>(User.class), "User", false));

-		entityConfigRepository.register(create(new Key<>(Measurement.class), "MeaResult", false));

-		entityConfigRepository.register(create(new Key<>(ChannelGroup.class), "SubMatrix", false));

-

-		// Unit

-		EntityConfig<Unit> unitConfig = create(new Key<>(Unit.class), "Unit", false);

-		unitConfig.addMandatory(entityConfigRepository.findRoot(new Key<>(PhysicalDimension.class)));

-		entityConfigRepository.register(unitConfig);

-

-		// Quantity

-		EntityConfig<Quantity> quantityConfig = create(new Key<>(Quantity.class), "Quantity", false);

-		quantityConfig.addMandatory(entityConfigRepository.findRoot(new Key<>(Unit.class)));

-		entityConfigRepository.register(quantityConfig);

-

-		// Channel

-		EntityConfig<Channel> channelConfig = create(new Key<>(Channel.class), "MeaQuantity", false);

-		channelConfig.addMandatory(entityConfigRepository.findRoot(new Key<>(Unit.class)));

-		channelConfig.addMandatory(entityConfigRepository.findRoot(new Key<>(Quantity.class)));

-		entityConfigRepository.register(channelConfig);

-

-		// ValueList

-		EntityConfig<ValueListValue> valueListValueConfig = create(new Key<>(ValueListValue.class), "ValueListValue",

-				true);

-		valueListValueConfig.setComparator(Sortable.COMPARATOR);

-		EntityConfig<ValueList> valueListConfig = create(new Key<>(ValueList.class), "ValueList", true);

-		valueListConfig.addChild(valueListValueConfig);

-		entityConfigRepository.register(valueListConfig);

-

-		// ParameterSet

-		EntityConfig<Parameter> parameterConfig = create(new Key<>(Parameter.class), "ResultParameter", true);

-		parameterConfig.addOptional(entityConfigRepository.findRoot(new Key<>(Unit.class)));

-		EntityConfig<ParameterSet> parameterSetConfig = create(new Key<>(ParameterSet.class), "ResultParameterSet",

-				true);

-		parameterSetConfig.addChild(parameterConfig);

-		entityConfigRepository.register(parameterSetConfig);

-

-		// CatalogComponents

-		registerCatalogComponent(ContextType.UNITUNDERTEST);

-		registerCatalogComponent(ContextType.TESTSEQUENCE);

-		registerCatalogComponent(ContextType.TESTEQUIPMENT);

-

-		// TemplateRoots

-		registerTemplateRoot(ContextType.UNITUNDERTEST);

-		registerTemplateRoot(ContextType.TESTSEQUENCE);

-		registerTemplateRoot(ContextType.TESTEQUIPMENT);

-

-		// TemplateTestStep

-		EntityConfig<TemplateTestStep> templateTestStepConfig = create(new Key<>(TemplateTestStep.class), "TplTestStep",

-				true);

-		templateTestStepConfig

-				.addOptional(entityConfigRepository.findRoot(new Key<>(TemplateRoot.class, ContextType.UNITUNDERTEST)));

-		templateTestStepConfig

-				.addOptional(entityConfigRepository.findRoot(new Key<>(TemplateRoot.class, ContextType.TESTSEQUENCE)));

-		templateTestStepConfig

-				.addOptional(entityConfigRepository.findRoot(new Key<>(TemplateRoot.class, ContextType.TESTEQUIPMENT)));

-		templateTestStepConfig.setComparator(Versionable.COMPARATOR);

-		entityConfigRepository.register(templateTestStepConfig);

-

-		// Status TestStep

-		// TODO check MIME type genration

-		// entityConfigRepository.register(create(new Key<>(Status.class,

-		// TestStep.class), "StatusTestStep", true));

-

-		// TestStep

-		EntityConfig<TestStep> testStepConfig = create(new Key<>(TestStep.class), "TestStep", true);

-		// testStepConfig.addMandatory(entityConfigRepository.findRoot(new

-		// Key<>(Status.class, TestStep.class)));

-		testStepConfig.addOptional(entityConfigRepository.findRoot(new Key<>(TemplateTestStep.class)));

-		testStepConfig.setComparator(Sortable.COMPARATOR);

-		entityConfigRepository.register(testStepConfig);

-

-		// TemplateTest

-		EntityConfig<TemplateTestStepUsage> templateTestStepUsageConfig = create(new Key<>(TemplateTestStepUsage.class),

-				"TplTestStepUsage", true);

-		templateTestStepUsageConfig.addMandatory(templateTestStepConfig);

-		templateTestStepUsageConfig.setComparator(Sortable.COMPARATOR);

-		EntityConfig<TemplateTest> templateTestConfig = create(new Key<>(TemplateTest.class), "TplTest", true);

-		templateTestConfig.addChild(templateTestStepUsageConfig);

-		templateTestConfig.setComparator(Versionable.COMPARATOR);

-		entityConfigRepository.register(templateTestConfig);

-

-		// Status Test

-		// TODO check MIME type genration

-		// entityConfigRepository.register(create(new Key<>(Status.class,

-		// Test.class), "StatusTest", true));

-

-		// Test

-		EntityConfig<Test> testConfig = create(new Key<>(Test.class), "Test", true);

-		testConfig.addMandatory(entityConfigRepository.findRoot(new Key<>(User.class)));

-		// testConfig.addMandatory(entityConfigRepository.findRoot(new

-		// Key<>(Status.class, Test.class)));

-		testConfig.addOptional(entityConfigRepository.findRoot(new Key<>(TemplateTest.class)));

-		entityConfigRepository.register(testConfig);

-

-		// ContextRoots

-		registerContextRoot(ContextType.UNITUNDERTEST);

-		registerContextRoot(ContextType.TESTSEQUENCE);

-		registerContextRoot(ContextType.TESTEQUIPMENT);

-

-		LOGGER.debug("Entity configurations loaded in {} ms.", System.currentTimeMillis() - start);

-	}

-

-	/**

-	 * Loads the {@link EntityConfig}s required for {@link ContextRoot} with

-	 * given {@link ContextType}.

-	 *

-	 * @param contextType

-	 *            The {@code ContextType}.

-	 */

-	private void registerContextRoot(ContextType contextType) {

-		EntityConfig<ContextRoot> contextRootConfig = create(new Key<>(ContextRoot.class, contextType),

-				ODSUtils.CONTEXTTYPES.convert(contextType), true);

-		contextRootConfig.addMandatory(entityConfigRepository.findRoot(new Key<>(TemplateRoot.class, contextType)));

-		for (Relation contextComponentRelation : contextRootConfig.getEntityType().getChildRelations()) {

-			EntityType contextComponentEntityType = contextComponentRelation.getTarget();

-			EntityConfig<ContextComponent> contextComponentConfig = create(

-					new Key<>(ContextComponent.class, contextType), contextComponentEntityType.getName(), true);

-			contextComponentConfig

-					.addInherited(entityConfigRepository.findImplicit(new Key<>(TemplateComponent.class, contextType)));

-			contextRootConfig.addChild(contextComponentConfig);

-			if (contextType.isTestEquipment()) {

-				for (Relation contextSensorRelation : contextComponentEntityType.getChildRelations()) {

-					EntityType contextSensorEntityType = contextSensorRelation.getTarget();

-					EntityConfig<ContextSensor> contextSensorConfig = create(new Key<>(ContextSensor.class),

-							contextSensorEntityType.getName(), true);

-					contextSensorConfig

-							.addInherited(entityConfigRepository.findImplicit(new Key<>(TemplateSensor.class)));

-					contextComponentConfig.addChild(contextSensorConfig);

-				}

-			}

-		}

-		entityConfigRepository.register(contextRootConfig);

-	}

-

-	/**

-	 * Loads the {@link EntityConfig}s required for {@link TemplateRoot} with

-	 * given {@link ContextType}.

-	 *

-	 * @param contextType

-	 *            The {@code ContextType}.

-	 */

-	private void registerTemplateRoot(ContextType contextType) {

-		String odsName = ODSUtils.CONTEXTTYPES.convert(contextType);

-		EntityConfig<TemplateAttribute> templateAttributeConfig = create(

-				new Key<>(TemplateAttribute.class, contextType), "Tpl" + odsName + "Attr", true);

-		templateAttributeConfig

-				.addInherited(entityConfigRepository.findImplicit(new Key<>(CatalogAttribute.class, contextType)));

-		templateAttributeConfig.setComparator(TemplateAttribute.COMPARATOR);

-		EntityConfig<TemplateComponent> templateComponentConfig = create(

-				new Key<>(TemplateComponent.class, contextType), "Tpl" + odsName + "Comp", true);

-		templateComponentConfig.addChild(templateAttributeConfig);

-		templateComponentConfig

-				.addMandatory(entityConfigRepository.findRoot(new Key<>(CatalogComponent.class, contextType)));

-		templateComponentConfig.addChild(templateComponentConfig);

-		templateComponentConfig.setComparator(Sortable.COMPARATOR);

-		if (contextType.isTestEquipment()) {

-			EntityConfig<TemplateAttribute> templateSensorAttributeConfig = create(new Key<>(TemplateAttribute.class),

-					"TplSensorAttr", true);

-			templateSensorAttributeConfig.setComparator(TemplateAttribute.COMPARATOR);

-			templateSensorAttributeConfig

-					.addInherited(entityConfigRepository.findImplicit(new Key<>(CatalogAttribute.class)));

-			EntityConfig<TemplateSensor> templateSensorConfig = create(new Key<>(TemplateSensor.class), "TplSensor",

-					true);

-			templateSensorConfig.addChild(templateSensorAttributeConfig);

-			templateSensorConfig.addMandatory(entityConfigRepository.findRoot(new Key<>(Quantity.class)));

-			templateSensorConfig.addInherited(entityConfigRepository.findImplicit(new Key<>(CatalogSensor.class)));

-			templateSensorConfig.setComparator(Sortable.COMPARATOR);

-			templateComponentConfig.addChild(templateSensorConfig);

-		}

-		EntityConfig<TemplateRoot> templateRootConfig = create(new Key<>(TemplateRoot.class, contextType),

-				"Tpl" + odsName + "Root", true);

-		templateRootConfig.addChild(templateComponentConfig);

-		templateRootConfig.setComparator(Versionable.COMPARATOR);

-		entityConfigRepository.register(templateRootConfig);

-	}

-

-	/**

-	 * Loads the {@link EntityConfig}s required for {@link CatalogComponent}

-	 * with given {@link ContextType}.

-	 *

-	 * @param contextType

-	 *            The {@code ContextType}.

-	 */

-	private void registerCatalogComponent(ContextType contextType) {

-		String odsName = ODSUtils.CONTEXTTYPES.convert(contextType);

-		EntityConfig<CatalogAttribute> catalogAttributeConfig = create(new Key<>(CatalogAttribute.class, contextType),

-				"Cat" + odsName + "Attr", true);

-		catalogAttributeConfig.addOptional(entityConfigRepository.findRoot(new Key<>(ValueList.class)));

-		catalogAttributeConfig.setComparator(Sortable.COMPARATOR);

-		EntityConfig<CatalogComponent> catalogComponentConfig = create(new Key<>(CatalogComponent.class, contextType),

-				"Cat" + odsName + "Comp", true);

-		catalogComponentConfig.addChild(catalogAttributeConfig);

-		if (contextType.isTestEquipment()) {

-			EntityConfig<CatalogAttribute> catalogSensorAttributeConfig = create(new Key<>(CatalogAttribute.class),

-					"CatSensorAttr", true);

-			catalogSensorAttributeConfig.addOptional(entityConfigRepository.findRoot(new Key<>(ValueList.class)));

-			EntityConfig<CatalogSensor> catalogSensorConfig = create(new Key<>(CatalogSensor.class), "CatSensor", true);

-			catalogSensorConfig.addChild(catalogSensorAttributeConfig);

-			catalogComponentConfig.addChild(catalogSensorConfig);

-		}

-		entityConfigRepository.register(catalogComponentConfig);

-	}

-

-	/**

-	 * Creates a new {@link EntityConfig}.

-	 *

-	 * @param <T>

-	 *            The entity type.

-	 * @param key

-	 *            Used as identifier.

-	 * @param typeName

-	 *            Name of the associated {@link EntityType}.

-	 * @param appendName

-	 *            Flag indicates whether to append the entity types base name to

-	 *            the MIME type.

-	 * @return The created {@code EntityConfig} is returned.

-	 */

-	private <T extends Entity> EntityConfig<T> create(Key<T> key, String typeName, boolean appendName) {

-		EntityConfig<T> entityConfig = new EntityConfig<>(key);

-		ODSEntityType entityType = (ODSEntityType) getEntityType(typeName);

-		entityConfig.setEntityType(entityType);

-		entityConfig.setMimeType(buildDefaultMimeType(entityType, appendName));

-		return entityConfig;

-	}

-

-	/**

-	 * Creates a default MIME type for given {@link EntityType}.

-	 *

-	 * @param entityType

-	 *            The {@code EntityType}.

-	 * @param appendName

-	 *            Flag indicates whether to append the entity types base name to

-	 *            the MIME type.

-	 * @return The created MIME type {@code String} is returned.

-	 */

-	private String buildDefaultMimeType(ODSEntityType entityType, boolean appendName) {

-		StringBuilder sb = new StringBuilder();

-		sb.append("application/x-asam.");

-		sb.append(entityType.getBaseName().toLowerCase(Locale.ROOT));

-		if (appendName) {

-			sb.append('.').append(entityType.getName().toLowerCase(Locale.ROOT));

-		}

-		return sb.toString();

-	}

-

-}

+/*
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.eclipse.mdm.api.odsadapter.query;
+
+import static java.util.stream.Collectors.groupingBy;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.stream.Stream;
+
+import com.google.common.base.Stopwatch;
+import org.apache.commons.lang3.time.StopWatch;
+import org.asam.ods.AIDName;
+import org.asam.ods.AggrFunc;
+import org.asam.ods.AoException;
+import org.asam.ods.AoSession;
+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;
+import org.asam.ods.SelItem;
+import org.asam.ods.SelOrder;
+import org.asam.ods.T_LONGLONG;
+import org.eclipse.mdm.api.base.adapter.EntityType;
+import org.eclipse.mdm.api.base.adapter.ModelManager;
+import org.eclipse.mdm.api.base.adapter.Relation;
+import org.eclipse.mdm.api.base.model.Channel;
+import org.eclipse.mdm.api.base.model.ChannelGroup;
+import org.eclipse.mdm.api.base.model.ContextComponent;
+import org.eclipse.mdm.api.base.model.ContextRoot;
+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;
+import org.eclipse.mdm.api.base.model.ParameterSet;
+import org.eclipse.mdm.api.base.model.PhysicalDimension;
+import org.eclipse.mdm.api.base.model.Quantity;
+import org.eclipse.mdm.api.base.model.Sortable;
+import org.eclipse.mdm.api.base.model.Test;
+import org.eclipse.mdm.api.base.model.TestStep;
+import org.eclipse.mdm.api.base.model.Unit;
+import org.eclipse.mdm.api.base.model.User;
+import org.eclipse.mdm.api.dflt.model.CatalogAttribute;
+import org.eclipse.mdm.api.dflt.model.CatalogComponent;
+import org.eclipse.mdm.api.dflt.model.CatalogSensor;
+import org.eclipse.mdm.api.dflt.model.Pool;
+import org.eclipse.mdm.api.dflt.model.Project;
+import org.eclipse.mdm.api.dflt.model.TemplateAttribute;
+import org.eclipse.mdm.api.dflt.model.TemplateComponent;
+import org.eclipse.mdm.api.dflt.model.TemplateRoot;
+import org.eclipse.mdm.api.dflt.model.TemplateSensor;
+import org.eclipse.mdm.api.dflt.model.TemplateTest;
+import org.eclipse.mdm.api.dflt.model.TemplateTestStep;
+import org.eclipse.mdm.api.dflt.model.TemplateTestStepUsage;
+import org.eclipse.mdm.api.dflt.model.ValueList;
+import org.eclipse.mdm.api.dflt.model.ValueListValue;
+import org.eclipse.mdm.api.dflt.model.Versionable;
+import org.eclipse.mdm.api.odsadapter.lookup.config.EntityConfig;
+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;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * ODS implementation of the {@link ModelManager} interface.
+ *
+ * @since 1.0.0
+ * @author Viktor Stoehr, Gigatronik Ingolstadt GmbH
+ */
+public class ODSModelManager implements ModelManager {
+
+	private static final Logger LOGGER = LoggerFactory.getLogger(ODSModelManager.class);
+
+	private final Map<String, EntityType> entityTypesByName = new HashMap<>();
+
+	
+	private final ORB orb;
+
+	private final Lock write;
+	private final Lock read;
+
+	private EntityConfigRepository entityConfigRepository;
+
+	private ApplElemAccess applElemAccess;
+	private AoSession aoSession;
+
+	/**
+	 * Constructor.
+	 *
+	 * @param orb
+	 *            Used to activate CORBA service objects.
+	 * @param aoSession
+	 *            The underlying ODS session.
+	 * @throws AoException
+	 *             Thrown on errors.
+	 */
+	public ODSModelManager(ORB orb, AoSession aoSession) throws AoException {
+		this.aoSession = aoSession;
+		this.orb = orb;
+		applElemAccess = aoSession.getApplElemAccess();
+
+		// setup locks
+		ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
+		write = reentrantReadWriteLock.writeLock();
+		read = reentrantReadWriteLock.readLock();
+
+		initialize();
+	}
+
+	/**
+	 * Returns the {@link ORB}.
+	 *
+	 * @return The {@code ORB} is returned.
+	 */
+	public ORB getORB() {
+		return orb;
+	}
+
+	/**
+	 * Returns the non root {@link EntityConfig} for given {@link Key}.
+	 *
+	 * @param <T>
+	 *            The concrete entity type.
+	 * @param key
+	 *            Used as identifier.
+	 * @return The non root {@code EntityConfig} is returned.
+	 */
+	public <T extends Entity> EntityConfig<T> findEntityConfig(Key<T> key) {
+		read.lock();
+
+		try {
+			return entityConfigRepository.find(key);
+		} finally {
+			read.unlock();
+		}
+	}
+
+	/**
+	 * Returns the root {@link EntityConfig} for given {@link Key}.
+	 *
+	 * @param <T>
+	 *            The concrete entity type.
+	 * @param key
+	 *            Used as identifier.
+	 * @return The root {@code EntityConfig} is returned.
+	 */
+	public <T extends Entity> EntityConfig<T> getEntityConfig(Key<T> key) {
+		read.lock();
+
+		try {
+			return entityConfigRepository.findRoot(key);
+		} finally {
+			read.unlock();
+		}
+	}
+
+	/**
+	 * Returns the {@link EntityConfig} associated with given
+	 * {@link EntityType}.
+	 *
+	 * @param entityType
+	 *            Used as identifier.
+	 * @return The {@code EntityConfig} is returned.
+	 */
+	public EntityConfig<?> getEntityConfig(EntityType entityType) {
+		read.lock();
+
+		try {
+			return entityConfigRepository.find(entityType);
+		} finally {
+			read.unlock();
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public List<EntityType> listEntityTypes() {
+		read.lock();
+
+		try {
+			return Collections.unmodifiableList(new ArrayList<>(entityTypesByName.values()));
+		} finally {
+			read.unlock();
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public EntityType getEntityType(Class<? extends Entity> entityClass) {
+		read.lock();
+
+		try {
+			return getEntityConfig(new Key<>(entityClass)).getEntityType();
+		} finally {
+			read.unlock();
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public EntityType getEntityType(Class<? extends Entity> entityClass, ContextType contextType) {
+		read.lock();
+
+		try {
+			return getEntityConfig(new Key<>(entityClass, contextType)).getEntityType();
+		} finally {
+			read.unlock();
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public EntityType getEntityType(String name) {
+		read.lock();
+
+		try {
+			EntityType entityType = entityTypesByName.get(name);
+			if (entityType == null) {
+				throw new IllegalArgumentException("Entity with name '" + name + "' not found.");
+			}
+
+			return entityType;
+		} finally {
+			read.unlock();
+		}
+	}
+
+	@Override
+	public EntityType getEntityTypeById(String id) {
+		Optional<EntityType> entityType = listEntityTypes().stream().filter(et -> et.getId().equals(id)).findFirst();
+		if (!entityType.isPresent()) {
+			throw new IllegalArgumentException("Entity with id '" + id + "' not found.");
+		}
+
+		return entityType.get();
+	}
+
+	/**
+	 * Returns the {@link AoSession} of this model manager.
+	 *
+	 * @return The {@code AoSession} is returned.
+	 */
+	public AoSession getAoSession() {
+		write.lock();
+
+		try {
+			return aoSession;
+		} finally {
+			write.unlock();
+		}
+	}
+
+	/**
+	 * Returns the {@link ApplElemAccess} of this model manager.
+	 *
+	 * @return The {@code ApplElemAccess} is returned.
+	 */
+	public ApplElemAccess getApplElemAccess() {
+		read.lock();
+
+		try {
+			return applElemAccess;
+		} finally {
+			read.unlock();
+		}
+	}
+
+	/**
+	 * Closes the ODS connection.
+	 *
+	 * @throws AoException
+	 *             Thrown on errors.
+	 */
+	public void close() throws AoException {
+		read.lock();
+
+		try {
+			applElemAccess._release();
+			aoSession.close();
+		} finally {
+			read.unlock();
+			aoSession._release();
+		}
+	}
+
+	/**
+	 * Reloads the complete session context.
+	 */
+	public void reloadApplicationModel() {
+		write.lock();
+
+		AoSession aoSessionOld = aoSession;
+		ApplElemAccess applElemAccessOld = applElemAccess;
+		try {
+			entityTypesByName.clear();
+
+			aoSession = aoSession.createCoSession();
+			applElemAccess = aoSession.getApplElemAccess();
+			initialize();
+		} catch (AoException e) {
+			LOGGER.error("Unable to reload the application model due to: " + e.reason, e);
+		} finally {
+			write.unlock();
+		}
+
+		try {
+			applElemAccessOld._release();
+			aoSessionOld.close();
+		} catch (AoException e) {
+			LOGGER.debug("Unable to close replaced session due to: " + e.reason, e);
+		} finally {
+			aoSessionOld._release();
+		}
+	}
+
+	/**
+	 * Initializes this model manager by caching the application model and
+	 * loading the {@link EntityConfig}s.
+	 *
+	 * @throws AoException
+	 *             Thrown on errors.
+	 */
+	private void initialize() throws AoException {
+		loadApplicationModel();
+		loadEntityConfigurations();
+	}
+
+	/**
+	 * Caches the whole application model as provided by the ODS session.
+	 *
+	 * @throws AoException
+	 *             Thrown on errors.
+	 */
+	private void loadApplicationModel() throws AoException {
+		LOGGER.debug("Reading the application model...");
+
+		Map<String, Map<String, Enumeration<?>>> enumClassMap = loadODSEnumerations();
+
+		long start = System.currentTimeMillis();
+		ApplicationStructureValue applicationStructureValue = aoSession.getApplicationStructureValue();
+		Map<String, String> units = getUnitMapping(applicationStructureValue.applElems);
+
+		// create entity types (incl. attributes)
+		Map<String, ODSEntityType> entityTypesByID = new HashMap<>();
+		String sourceName = aoSession.getName();
+		for (ApplElem applElem : applicationStructureValue.applElems) {
+			String odsID = Long.toString(ODSConverter.fromODSLong(applElem.aid));
+			Map<String, Enumeration<?>> entityEnumMap = enumClassMap.getOrDefault(odsID, new HashMap<>());
+
+			ODSEntityType entityType = new ODSEntityType(sourceName, applElem, units, entityEnumMap);
+			entityTypesByName.put(applElem.aeName, entityType);
+			entityTypesByID.put(odsID, entityType);
+		}
+
+		// create relations
+		List<Relation> relations = new ArrayList<>();
+		for (ApplRel applRel : applicationStructureValue.applRels) {
+			EntityType source = entityTypesByID.get(Long.toString(ODSConverter.fromODSLong(applRel.elem1)));
+			EntityType target = entityTypesByID.get(Long.toString(ODSConverter.fromODSLong(applRel.elem2)));
+			relations.add(new ODSRelation(applRel, source, target));
+		}
+
+		// assign relations to their source entity types
+		relations.stream().collect(groupingBy(Relation::getSource))
+				.forEach((e, r) -> ((ODSEntityType) e).setRelations(r));
+
+		long stop = System.currentTimeMillis();
+		LOGGER.debug("{} entity types with {} relations found in {} ms.", entityTypesByName.size(), relations.size(),
+				stop - start);
+	}
+
+	private Map<String, Map<String, Enumeration<?>>> loadODSEnumerations() throws AoException {
+		LOGGER.debug("Loading ODS enumerations...");
+		long t1 = System.currentTimeMillis();
+
+		// enumeration mappings (aeID -> (aaName -> enumClass))
+		Map<String, Map<String, Enumeration<?>>> enumClassMap = new HashMap<>();
+		EnumRegistry er = EnumRegistry.getInstance();
+		ApplicationStructure applicationStructure = aoSession.getApplicationStructure();
+		for (EnumerationAttributeStructure eas : aoSession.getEnumerationAttributes()) {
+
+			EnumerationDefinition bubu = applicationStructure.getEnumerationDefinition(eas.enumName);
+			for (String itemName : bubu.listItemNames()) {
+				final int intValue = bubu.getItem(itemName);
+				LOGGER.debug("{}:{}:{}", eas.enumName, itemName, intValue);
+			}
+
+			// 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);
+				for (String itemName : enumdef.listItemNames()) {
+					final int intValue = enumdef.getItem(itemName);
+					enumdyn.addValue(new ODSEnum(itemName, intValue));
+				}
+				er.add(eas.enumName, enumdyn);
+			}
+
+			enumClassMap.computeIfAbsent(Long.toString(ODSConverter.fromODSLong(eas.aid)), k -> new HashMap<>())
+					.put(eas.aaName, ODSEnumerations.getEnumObj(eas.enumName));
+		}
+		LOGGER.debug("Loading enumerations took {}ms", System.currentTimeMillis() - t1);
+		return enumClassMap;
+	}
+
+	/**
+	 * Loads all available {@link Unit} names mapped by their instance IDs.
+	 *
+	 * @param applElems
+	 *            The application element meta data instances.
+	 * @return The unit names mapped by the corresponding instance IDs.
+	 * @throws AoException
+	 *             Thrown if unable to load the unit mappings.
+	 */
+	private Map<String, String> getUnitMapping(ApplElem[] applElems) throws AoException {
+		ApplElem unitElem = Stream.of(applElems).filter(ae -> ae.beName.equals("AoUnit")).findAny()
+				.orElseThrow(() -> new IllegalStateException("Application element 'Unit' is not defined."));
+
+		QueryStructureExt qse = new QueryStructureExt();
+		qse.anuSeq = new SelAIDNameUnitId[] {
+				new SelAIDNameUnitId(new AIDName(unitElem.aid, "Id"), new T_LONGLONG(), AggrFunc.NONE),
+				new SelAIDNameUnitId(new AIDName(unitElem.aid, "Name"), new T_LONGLONG(), AggrFunc.NONE) };
+		qse.condSeq = new SelItem[0];
+		qse.groupBy = new AIDName[0];
+		qse.joinSeq = new JoinDef[0];
+		qse.orderBy = new SelOrder[0];
+
+		Map<String, String> units = new HashMap<>();
+		ElemResultSetExt unitResultSetExt = getApplElemAccess().getInstancesExt(qse, 0)[0].firstElems[0];
+		for (int i = 0; i < unitResultSetExt.values[0].value.flag.length; i++) {
+			String unitID = Long
+					.toString(ODSConverter.fromODSLong(unitResultSetExt.values[0].value.u.longlongVal()[i]));
+			String unitName = unitResultSetExt.values[1].value.u.stringVal()[i];
+			units.put(unitID, unitName);
+		}
+
+		return units;
+	}
+
+	/**
+	 * Loads the {@link EntityConfig}s.
+	 */
+	private void loadEntityConfigurations() {
+		LOGGER.debug("Loading entity configurations...");
+		long start = System.currentTimeMillis();
+
+		entityConfigRepository = new EntityConfigRepository();
+
+		// Environment | Project | Pool | PhysicalDimension | User | Measurement
+		// | ChannelGroup
+		entityConfigRepository.register(create(new Key<>(Environment.class), "Environment", false));
+		entityConfigRepository.register(create(new Key<>(Project.class), "Project", false));
+		entityConfigRepository.register(create(new Key<>(Pool.class), "StructureLevel", true));
+		entityConfigRepository.register(create(new Key<>(PhysicalDimension.class), "PhysDimension", false));
+		entityConfigRepository.register(create(new Key<>(User.class), "User", false));
+		entityConfigRepository.register(create(new Key<>(Measurement.class), "MeaResult", false));
+		entityConfigRepository.register(create(new Key<>(ChannelGroup.class), "SubMatrix", false));
+
+		// Unit
+		EntityConfig<Unit> unitConfig = create(new Key<>(Unit.class), "Unit", false);
+		unitConfig.addMandatory(entityConfigRepository.findRoot(new Key<>(PhysicalDimension.class)));
+		entityConfigRepository.register(unitConfig);
+
+		// Quantity
+		EntityConfig<Quantity> quantityConfig = create(new Key<>(Quantity.class), "Quantity", false);
+		quantityConfig.addMandatory(entityConfigRepository.findRoot(new Key<>(Unit.class)));
+		entityConfigRepository.register(quantityConfig);
+
+		// Channel
+		EntityConfig<Channel> channelConfig = create(new Key<>(Channel.class), "MeaQuantity", false);
+		channelConfig.addMandatory(entityConfigRepository.findRoot(new Key<>(Unit.class)));
+		channelConfig.addMandatory(entityConfigRepository.findRoot(new Key<>(Quantity.class)));
+		entityConfigRepository.register(channelConfig);
+
+		// ValueList
+		EntityConfig<ValueListValue> valueListValueConfig = create(new Key<>(ValueListValue.class), "ValueListValue",
+				true);
+		valueListValueConfig.setComparator(Sortable.COMPARATOR);
+		EntityConfig<ValueList> valueListConfig = create(new Key<>(ValueList.class), "ValueList", true);
+		valueListConfig.addChild(valueListValueConfig);
+		entityConfigRepository.register(valueListConfig);
+
+		// ParameterSet
+		EntityConfig<Parameter> parameterConfig = create(new Key<>(Parameter.class), "ResultParameter", true);
+		parameterConfig.addOptional(entityConfigRepository.findRoot(new Key<>(Unit.class)));
+		EntityConfig<ParameterSet> parameterSetConfig = create(new Key<>(ParameterSet.class), "ResultParameterSet",
+				true);
+		parameterSetConfig.addChild(parameterConfig);
+		entityConfigRepository.register(parameterSetConfig);
+
+		// CatalogComponents
+		registerCatalogComponent(ContextType.UNITUNDERTEST);
+		registerCatalogComponent(ContextType.TESTSEQUENCE);
+		registerCatalogComponent(ContextType.TESTEQUIPMENT);
+
+		// TemplateRoots
+		registerTemplateRoot(ContextType.UNITUNDERTEST);
+		registerTemplateRoot(ContextType.TESTSEQUENCE);
+		registerTemplateRoot(ContextType.TESTEQUIPMENT);
+
+		// TemplateTestStep
+		EntityConfig<TemplateTestStep> templateTestStepConfig = create(new Key<>(TemplateTestStep.class), "TplTestStep",
+				true);
+		templateTestStepConfig
+				.addOptional(entityConfigRepository.findRoot(new Key<>(TemplateRoot.class, ContextType.UNITUNDERTEST)));
+		templateTestStepConfig
+				.addOptional(entityConfigRepository.findRoot(new Key<>(TemplateRoot.class, ContextType.TESTSEQUENCE)));
+		templateTestStepConfig
+				.addOptional(entityConfigRepository.findRoot(new Key<>(TemplateRoot.class, ContextType.TESTEQUIPMENT)));
+		templateTestStepConfig.setComparator(Versionable.COMPARATOR);
+		entityConfigRepository.register(templateTestStepConfig);
+
+		// Status TestStep
+		// TODO check MIME type genration
+		// entityConfigRepository.register(create(new Key<>(Status.class,
+		// TestStep.class), "StatusTestStep", true));
+
+		// TestStep
+		EntityConfig<TestStep> testStepConfig = create(new Key<>(TestStep.class), "TestStep", true);
+		// testStepConfig.addMandatory(entityConfigRepository.findRoot(new
+		// Key<>(Status.class, TestStep.class)));
+		testStepConfig.addOptional(entityConfigRepository.findRoot(new Key<>(TemplateTestStep.class)));
+		testStepConfig.setComparator(Sortable.COMPARATOR);
+		entityConfigRepository.register(testStepConfig);
+
+		// TemplateTest
+		EntityConfig<TemplateTestStepUsage> templateTestStepUsageConfig = create(new Key<>(TemplateTestStepUsage.class),
+				"TplTestStepUsage", true);
+		templateTestStepUsageConfig.addMandatory(templateTestStepConfig);
+		templateTestStepUsageConfig.setComparator(Sortable.COMPARATOR);
+		EntityConfig<TemplateTest> templateTestConfig = create(new Key<>(TemplateTest.class), "TplTest", true);
+		templateTestConfig.addChild(templateTestStepUsageConfig);
+		templateTestConfig.setComparator(Versionable.COMPARATOR);
+		entityConfigRepository.register(templateTestConfig);
+
+		// Status Test
+		// TODO check MIME type genration
+		// entityConfigRepository.register(create(new Key<>(Status.class,
+		// Test.class), "StatusTest", true));
+
+		// Test
+		EntityConfig<Test> testConfig = create(new Key<>(Test.class), "Test", true);
+		testConfig.addMandatory(entityConfigRepository.findRoot(new Key<>(User.class)));
+		// testConfig.addMandatory(entityConfigRepository.findRoot(new
+		// Key<>(Status.class, Test.class)));
+		testConfig.addOptional(entityConfigRepository.findRoot(new Key<>(TemplateTest.class)));
+		entityConfigRepository.register(testConfig);
+
+		// ContextRoots
+		registerContextRoot(ContextType.UNITUNDERTEST);
+		registerContextRoot(ContextType.TESTSEQUENCE);
+		registerContextRoot(ContextType.TESTEQUIPMENT);
+
+		LOGGER.debug("Entity configurations loaded in {} ms.", System.currentTimeMillis() - start);
+	}
+
+	/**
+	 * Loads the {@link EntityConfig}s required for {@link ContextRoot} with
+	 * given {@link ContextType}.
+	 *
+	 * @param contextType
+	 *            The {@code ContextType}.
+	 */
+	private void registerContextRoot(ContextType contextType) {
+		EntityConfig<ContextRoot> contextRootConfig = create(new Key<>(ContextRoot.class, contextType),
+				ODSUtils.CONTEXTTYPES.get(contextType), true);
+		contextRootConfig.addMandatory(entityConfigRepository.findRoot(new Key<>(TemplateRoot.class, contextType)));
+		for (Relation contextComponentRelation : contextRootConfig.getEntityType().getChildRelations()) {
+			EntityType contextComponentEntityType = contextComponentRelation.getTarget();
+			EntityConfig<ContextComponent> contextComponentConfig = create(
+					new Key<>(ContextComponent.class, contextType), contextComponentEntityType.getName(), true);
+			contextComponentConfig
+					.addInherited(entityConfigRepository.findImplicit(new Key<>(TemplateComponent.class, contextType)));
+			contextRootConfig.addChild(contextComponentConfig);
+			if (contextType.isTestEquipment()) {
+				for (Relation contextSensorRelation : contextComponentEntityType.getChildRelations()) {
+					EntityType contextSensorEntityType = contextSensorRelation.getTarget();
+					EntityConfig<ContextSensor> contextSensorConfig = create(new Key<>(ContextSensor.class),
+							contextSensorEntityType.getName(), true);
+					contextSensorConfig
+							.addInherited(entityConfigRepository.findImplicit(new Key<>(TemplateSensor.class)));
+					contextComponentConfig.addChild(contextSensorConfig);
+				}
+			}
+		}
+		entityConfigRepository.register(contextRootConfig);
+	}
+
+	/**
+	 * Loads the {@link EntityConfig}s required for {@link TemplateRoot} with
+	 * given {@link ContextType}.
+	 *
+	 * @param contextType
+	 *            The {@code ContextType}.
+	 */
+	private void registerTemplateRoot(ContextType contextType) {
+		String odsName = ODSUtils.CONTEXTTYPES.get(contextType);
+		EntityConfig<TemplateAttribute> templateAttributeConfig = create(
+				new Key<>(TemplateAttribute.class, contextType), "Tpl" + odsName + "Attr", true);
+		templateAttributeConfig
+				.addInherited(entityConfigRepository.findImplicit(new Key<>(CatalogAttribute.class, contextType)));
+		templateAttributeConfig.setComparator(TemplateAttribute.COMPARATOR);
+		EntityConfig<TemplateComponent> templateComponentConfig = create(
+				new Key<>(TemplateComponent.class, contextType), "Tpl" + odsName + "Comp", true);
+		templateComponentConfig.addChild(templateAttributeConfig);
+		templateComponentConfig
+				.addMandatory(entityConfigRepository.findRoot(new Key<>(CatalogComponent.class, contextType)));
+		templateComponentConfig.addChild(templateComponentConfig);
+		templateComponentConfig.setComparator(Sortable.COMPARATOR);
+		if (contextType.isTestEquipment()) {
+			EntityConfig<TemplateAttribute> templateSensorAttributeConfig = create(new Key<>(TemplateAttribute.class),
+					"TplSensorAttr", true);
+			templateSensorAttributeConfig.setComparator(TemplateAttribute.COMPARATOR);
+			templateSensorAttributeConfig
+					.addInherited(entityConfigRepository.findImplicit(new Key<>(CatalogAttribute.class)));
+			EntityConfig<TemplateSensor> templateSensorConfig = create(new Key<>(TemplateSensor.class), "TplSensor",
+					true);
+			templateSensorConfig.addChild(templateSensorAttributeConfig);
+			templateSensorConfig.addMandatory(entityConfigRepository.findRoot(new Key<>(Quantity.class)));
+			templateSensorConfig.addInherited(entityConfigRepository.findImplicit(new Key<>(CatalogSensor.class)));
+			templateSensorConfig.setComparator(Sortable.COMPARATOR);
+			templateComponentConfig.addChild(templateSensorConfig);
+		}
+		EntityConfig<TemplateRoot> templateRootConfig = create(new Key<>(TemplateRoot.class, contextType),
+				"Tpl" + odsName + "Root", true);
+		templateRootConfig.addChild(templateComponentConfig);
+		templateRootConfig.setComparator(Versionable.COMPARATOR);
+		entityConfigRepository.register(templateRootConfig);
+	}
+
+	/**
+	 * Loads the {@link EntityConfig}s required for {@link CatalogComponent}
+	 * with given {@link ContextType}.
+	 *
+	 * @param contextType
+	 *            The {@code ContextType}.
+	 */
+	private void registerCatalogComponent(ContextType contextType) {
+		String odsName = ODSUtils.CONTEXTTYPES.get(contextType);
+		EntityConfig<CatalogAttribute> catalogAttributeConfig = create(new Key<>(CatalogAttribute.class, contextType),
+				"Cat" + odsName + "Attr", true);
+		catalogAttributeConfig.addOptional(entityConfigRepository.findRoot(new Key<>(ValueList.class)));
+		catalogAttributeConfig.setComparator(Sortable.COMPARATOR);
+		EntityConfig<CatalogComponent> catalogComponentConfig = create(new Key<>(CatalogComponent.class, contextType),
+				"Cat" + odsName + "Comp", true);
+		catalogComponentConfig.addChild(catalogAttributeConfig);
+		if (contextType.isTestEquipment()) {
+			EntityConfig<CatalogAttribute> catalogSensorAttributeConfig = create(new Key<>(CatalogAttribute.class),
+					"CatSensorAttr", true);
+			catalogSensorAttributeConfig.addOptional(entityConfigRepository.findRoot(new Key<>(ValueList.class)));
+			EntityConfig<CatalogSensor> catalogSensorConfig = create(new Key<>(CatalogSensor.class), "CatSensor", true);
+			catalogSensorConfig.addChild(catalogSensorAttributeConfig);
+			catalogComponentConfig.addChild(catalogSensorConfig);
+		}
+		entityConfigRepository.register(catalogComponentConfig);
+	}
+
+	/**
+	 * Creates a new {@link EntityConfig}.
+	 *
+	 * @param <T>
+	 *            The entity type.
+	 * @param key
+	 *            Used as identifier.
+	 * @param typeName
+	 *            Name of the associated {@link EntityType}.
+	 * @param appendName
+	 *            Flag indicates whether to append the entity types base name to
+	 *            the MIME type.
+	 * @return The created {@code EntityConfig} is returned.
+	 */
+	private <T extends Entity> EntityConfig<T> create(Key<T> key, String typeName, boolean appendName) {
+		EntityConfig<T> entityConfig = new EntityConfig<>(key);
+		ODSEntityType entityType = (ODSEntityType) getEntityType(typeName);
+		entityConfig.setEntityType(entityType);
+		entityConfig.setMimeType(buildDefaultMimeType(entityType, appendName));
+		return entityConfig;
+	}
+
+	/**
+	 * Creates a default MIME type for given {@link EntityType}.
+	 *
+	 * @param entityType
+	 *            The {@code EntityType}.
+	 * @param appendName
+	 *            Flag indicates whether to append the entity types base name to
+	 *            the MIME type.
+	 * @return The created MIME type {@code String} is returned.
+	 */
+	private String buildDefaultMimeType(ODSEntityType entityType, boolean appendName) {
+		StringBuilder sb = new StringBuilder();
+		sb.append("application/x-asam.");
+		sb.append(entityType.getBaseName().toLowerCase(Locale.ROOT));
+		if (appendName) {
+			sb.append('.').append(entityType.getName().toLowerCase(Locale.ROOT));
+		}
+		return sb.toString();
+	}
+
+}
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 05db375..7b552b7 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
@@ -194,9 +194,9 @@
 				if (conditionItem.isCondition()) {
 					selItem.value(createCondition(conditionItem.getCondition()));
 				} else if (conditionItem.isBracketOperator()){
-					selItem._operator(ODSUtils.BRACKETOPERATORS.convert(conditionItem.getBracketOperator()));
+					selItem._operator(ODSUtils.BRACKETOPERATORS.get(conditionItem.getBracketOperator()));
 				} else if (conditionItem.isBooleanOperator()) {
-					selItem._operator(ODSUtils.OPERATORS.convert(conditionItem.getBooleanOperator()));
+					selItem._operator(ODSUtils.OPERATORS.get(conditionItem.getBooleanOperator()));
 					condCount++;
 				} else {
 					throw new IllegalArgumentException("Passed filter item is neither an operator nor a condition.");
@@ -244,7 +244,7 @@
 	private SelAIDNameUnitId createSelect(Attribute attribute, Aggregation aggregation) {
 		SelAIDNameUnitId sanu = new SelAIDNameUnitId();
 
-		sanu.aggregate = ODSUtils.AGGREGATIONS.convert(aggregation);
+		sanu.aggregate = ODSUtils.AGGREGATIONS.get(aggregation);
 		sanu.attr = createAIDName(attribute);
 		sanu.unitId = new T_LONGLONG();
 
@@ -263,7 +263,7 @@
 	private SelValueExt createCondition(Condition condition) throws DataAccessException {
 		SelValueExt sve = new SelValueExt();
 
-		sve.oper = ODSUtils.OPERATIONS.convert(condition.getComparisonOperator());
+		sve.oper = ODSUtils.OPERATIONS.get(condition.getComparisonOperator());
 		sve.attr = new AIDNameUnitId();
 		sve.attr.unitId = new T_LONGLONG();
 		sve.attr.attr = createAIDName(condition.getAttribute());
@@ -278,7 +278,7 @@
 	 *
 	 * @param relation
 	 *            The {@code Relation}.
-	 * @param joinType
+	 * @param join
 	 *            The {@code JoinType}.
 	 * @return The corresponding {@code JoinDef} is returned.
 	 */
@@ -288,7 +288,7 @@
 		joinDef.fromAID = ((ODSEntityType) relation.getSource()).getODSID();
 		joinDef.toAID = ((ODSEntityType) relation.getTarget()).getODSID();
 		joinDef.refName = relation.getName();
-		joinDef.joiningType = ODSUtils.JOINS.convert(join);
+		joinDef.joiningType = ODSUtils.JOINS.get(join);
 
 		return joinDef;
 	}
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 4da0adc..2ceac1d 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
@@ -58,7 +58,7 @@
 		this.source = source;
 		this.target = target;
 		name = applRel.arName;
-		relationType = ODSUtils.RELATIONSHIPS.revert(applRel.arRelationType);
+		relationType = ODSUtils.RELATIONSHIPS.inverse().get(applRel.arRelationType);
 		rangeMax = applRel.arRelationRange.max;
 	}
 
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 af8b2ee..e02fe0c 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
@@ -95,7 +95,7 @@
 				.collect(Collectors.groupingBy(CatalogComponent::getContextType));
 
 		for (Entry<ContextType, List<CatalogComponent>> entry : catalogComponentsByContextType.entrySet()) {
-			String odsContextTypeName = ODSUtils.CONTEXTTYPES.convert(entry.getKey());
+			String odsContextTypeName = ODSUtils.CONTEXTTYPES.get(entry.getKey());
 			ApplicationElement contextRootApplicationElement = getApplicationStructure()
 					.getElementByName(odsContextTypeName);
 			BaseElement contextRootBaseElement = contextRootApplicationElement.getBaseElement();
@@ -230,7 +230,7 @@
 			for (CatalogAttribute catalogAttribute : entry.getValue()) {
 
 				ApplicationAttribute applicationAttribute = applicationElement.createAttribute();
-				DataType dataType = ODSUtils.VALUETYPES.convert(catalogAttribute.getValueType());
+				DataType dataType = ODSUtils.VALUETYPES.get(catalogAttribute.getValueType());
 				applicationAttribute.setDataType(dataType);
 				applicationAttribute.setName(catalogAttribute.getName());
 				if (dataType == DataType.DT_ENUM) {
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/utils/BiDiMapper.java b/src/main/java/org/eclipse/mdm/api/odsadapter/utils/BiDiMapper.java
deleted file mode 100644
index ac47195..0000000
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/utils/BiDiMapper.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * 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
- */
-
-package org.eclipse.mdm.api.odsadapter.utils;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Bidirectional mapping of configured values.
- *
- * @param <T>
- *            Mapped object type one.
- * @param <S>
- *            Mapped object type two.
- * @since 1.0.0
- * @author Viktor Stoehr, Gigatronik Ingolstadt GmbH
- */
-public final class BiDiMapper<T, S> {
-
-	// ======================================================================
-	// Instance variables
-	// ======================================================================
-
-	private final Map<Object, Object> map = new HashMap<>();
-
-	// ======================================================================
-	// Public methods
-	// ======================================================================
-
-	/**
-	 * Returns the mapping for given value.
-	 *
-	 * @param input
-	 *            The value.
-	 * @return The corresponding mapped value is returned.
-	 */
-	@SuppressWarnings("unchecked")
-	public S convert(T input) {
-		return (S) map.get(input);
-	}
-
-	/**
-	 * Returns the mapping for given value.
-	 *
-	 * @param input
-	 *            The value.
-	 * @return The corresponding mapped value is returned.
-	 */
-	@SuppressWarnings("unchecked")
-	public T revert(S input) {
-		return (T) map.get(input);
-	}
-
-	// ======================================================================
-	// Package methods
-	// ======================================================================
-
-	/**
-	 * Adds a new bidirectional mapping for given values.
-	 *
-	 * @param t
-	 *            Not allowed to be null.
-	 * @param s
-	 *            Not allowed to be null.
-	 */
-	void addMappings(T t, S s) {
-		map.put(t, s);
-		map.put(s, t);
-	}
-
-}
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 c62c05f..339deae 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
@@ -322,7 +322,7 @@
 		if (Aggregation.NONE == aggregation) {
 			return attribute.createValue(unit, valid, input);
 		} else {
-			ValueType<?> valueType = ODSUtils.VALUETYPES.revert(dataType);
+			ValueType<?> valueType = ODSUtils.VALUETYPES.inverse().get(dataType);
 			if (valueType.isEnumerationType()
 					&& attribute.getValueType().isEnumerationType()
 					&& Sets.immutableEnumSet(Aggregation.MINIMUM, Aggregation.MAXIMUM, Aggregation.DISTINCT)
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 6479fac..095c479 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
@@ -45,7 +45,7 @@
 	// Constructors
 	// ======================================================================
 
-	/**
+	/*o*
 	 * Constructor.
 	 */
 	private ODSEnumerations() {
@@ -58,7 +58,6 @@
 	/**
 	 * Returns the enumeration class identified by given name.
 	 *
-	 * @param <E>
 	 *            The enumeration type.
 	 * @param name
 	 *            The ODS name of the requested enumeration class.
@@ -89,8 +88,8 @@
 	/**
 	 * Returns the ODS enumeration name for given enumeration class.
 	 *
-	 * @param enumClass
-	 *            The enumeration class name.
+	 * @param enumObj
+	 *            The enumeration object.
 	 * @return The corresponding ODS enumeration name is returned.
 	 * @throws IllegalArgumentException
 	 *             Thrown if enumeration class is unknown.
@@ -297,7 +296,7 @@
 			return ScalarType.FLOAT_COMPLEX;
 		} else if (value == 14) {
 			return ScalarType.DOUBLE_COMPLEX;
-		} else if (value == 28) {
+			} else if (value == 28) {
 			return ScalarType.FILE_LINK;
 		} else if (value == 30) {
 			return ScalarType.ENUMERATION;
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 1f69761..5650866 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
@@ -8,6 +8,7 @@
 
 package org.eclipse.mdm.api.odsadapter.utils;
 
+import com.google.common.collect.ImmutableBiMap;
 import org.asam.ods.AggrFunc;
 import org.asam.ods.DataType;
 import org.asam.ods.SelOpcode;
@@ -24,141 +25,142 @@
 /**
  * Utility class provides bidirectional mappings for ODS types
  *
- * @since 1.0.0
  * @author Viktor Stoehr, Gigatronik Ingolstadt GmbH
+ * @since 1.0.0
  */
 public abstract class ODSUtils {
+    /**
+     * Maps {@link RelationType} to the corresponding ODS {@link RelationType}.
+     */
+    public static final ImmutableBiMap<RelationType, org.asam.ods.RelationType> RELATIONSHIPS =
+            ImmutableBiMap.<RelationType, org.asam.ods.RelationType>builder()
+                    .put(RelationType.FATHER_CHILD, org.asam.ods.RelationType.FATHER_CHILD)
+                    .put(RelationType.INFO, org.asam.ods.RelationType.INFO)
+                    .put(RelationType.INHERITANCE, org.asam.ods.RelationType.INHERITANCE)
+                    .build();
 
-	// ======================================================================
-	// Class variables
-	// ======================================================================
+    /**
+     * Maps {@link Aggregation} to the corresponding ODS {@link AggrFunc}.
+     */
+    public static final ImmutableBiMap<Aggregation, AggrFunc> AGGREGATIONS =
+            ImmutableBiMap.<Aggregation, AggrFunc>builder()
+                    .put(Aggregation.NONE, AggrFunc.NONE)
+                    .put(Aggregation.COUNT, AggrFunc.COUNT)
+                    .put(Aggregation.DISTINCT_COUNT, AggrFunc.DCOUNT)
+                    .put(Aggregation.MINIMUM, AggrFunc.MIN)
+                    .put(Aggregation.MAXIMUM, AggrFunc.MAX)
+                    .put(Aggregation.AVERAGE, AggrFunc.AVG)
+                    .put(Aggregation.DEVIATION, AggrFunc.STDDEV)
+                    .put(Aggregation.SUM, AggrFunc.SUM)
+                    .put(Aggregation.DISTINCT, AggrFunc.DISTINCT)
+                    .build();
 
-	/**
-	 * Maps {@link RelationType} to the corresponding ODS {@link RelationType}.
-	 */
-	public static final BiDiMapper<RelationType, org.asam.ods.RelationType> RELATIONSHIPS = new BiDiMapper<>();
+    /**
+     * Maps {@link ContextType} to the corresponding ODS {@link String}.
+     */
+    public static final ImmutableBiMap<ContextType, String> CONTEXTTYPES =
+            ImmutableBiMap.<ContextType, String>builder()
+                    .put(ContextType.UNITUNDERTEST, "UnitUnderTest")
+                    .put(ContextType.TESTSEQUENCE, "TestSequence")
+                    .put(ContextType.TESTEQUIPMENT, "TestEquipment")
+                    .build();
 
-	/**
-	 * Maps {@link Aggregation} to the corresponding ODS {@link AggrFunc}.
-	 */
-	public static final BiDiMapper<Aggregation, AggrFunc> AGGREGATIONS = new BiDiMapper<>();
+    /**
+     * Maps {@link ComparisonOperator} to the corresponding ODS {@link SelOpcode}.
+     */
+    public static final ImmutableBiMap<ComparisonOperator, SelOpcode> OPERATIONS =
+            ImmutableBiMap.<ComparisonOperator, SelOpcode>builder()
+                    .put(ComparisonOperator.LIKE, SelOpcode.LIKE)
+                    .put(ComparisonOperator.CASE_INSENSITIVE_LIKE, SelOpcode.CI_LIKE)
+                    .put(ComparisonOperator.NOT_LIKE, SelOpcode.NOTLIKE)
+                    .put(ComparisonOperator.CASE_INSENSITIVE_NOT_LIKE, SelOpcode.CI_NOTLIKE)
+                    .put(ComparisonOperator.EQUAL, SelOpcode.EQ)
+                    .put(ComparisonOperator.CASE_INSENSITIVE_EQUAL, SelOpcode.CI_EQ)
+                    .put(ComparisonOperator.NOT_EQUAL, SelOpcode.NEQ)
+                    .put(ComparisonOperator.CASE_INSENSITIVE_NOT_EQUAL, SelOpcode.CI_NEQ)
+                    .put(ComparisonOperator.GREATER_THAN, SelOpcode.GT)
+                    .put(ComparisonOperator.CASE_INSENSITIVE_GREATER_THAN, SelOpcode.CI_GT)
+                    .put(ComparisonOperator.GREATER_THAN_OR_EQUAL, SelOpcode.GTE)
+                    .put(ComparisonOperator.CASE_INSENSITIVE_GREATER_THAN_OR_EQUAL, SelOpcode.CI_GTE)
+                    .put(ComparisonOperator.LESS_THAN, SelOpcode.LT)
+                    .put(ComparisonOperator.CASE_INSENSITIVE_LESS_THAN, SelOpcode.CI_LT)
+                    .put(ComparisonOperator.LESS_THAN_OR_EQUAL, SelOpcode.LTE)
+                    .put(ComparisonOperator.CASE_INSENSITIVE_LESS_THAN_OR_EQUAL, SelOpcode.CI_LTE)
+                    .put(ComparisonOperator.IS_NULL, SelOpcode.IS_NULL)
+                    .put(ComparisonOperator.IS_NOT_NULL, SelOpcode.IS_NOT_NULL)
+                    .put(ComparisonOperator.IN_SET, SelOpcode.INSET)
+                    .put(ComparisonOperator.CASE_INSENSITIVE_IN_SET, SelOpcode.CI_INSET)
+                    .put(ComparisonOperator.NOT_IN_SET, SelOpcode.NOTINSET)
+                    .put(ComparisonOperator.CASE_INSENSITIVE_NOT_IN_SET, SelOpcode.CI_NOTINSET)
+                    .put(ComparisonOperator.BETWEEN, SelOpcode.BETWEEN)
+                    .build();
 
-	/**
-	 * Maps {@link ContextType} to the corresponding ODS {@link String}.
-	 */
-	public static final BiDiMapper<ContextType, String> CONTEXTTYPES = new BiDiMapper<>();
+    /**
+     * Maps {@link BooleanOperator} to the corresponding ODS {@link SelOperator}.
+     */
+    public static final ImmutableBiMap<BooleanOperator, SelOperator> OPERATORS =
+            ImmutableBiMap.<BooleanOperator, SelOperator>builder()
+                    .put(BooleanOperator.AND, SelOperator.AND)
+                    .put(BooleanOperator.OR, SelOperator.OR)
+                    .put(BooleanOperator.NOT, SelOperator.NOT)
+                    .build();
 
-	/**
-	 * Maps {@link ComparisonOperator} to the corresponding ODS {@link SelOpcode}.
-	 */
-	public static final BiDiMapper<ComparisonOperator, SelOpcode> OPERATIONS = new BiDiMapper<>();
+    /**
+     * Maps {@link BracketOperator} to the corresponding ODS {@link SelOperator}.
+     */
+    public static final ImmutableBiMap<BracketOperator, SelOperator> BRACKETOPERATORS =
+            ImmutableBiMap.<BracketOperator, SelOperator>builder()
+                    .put(BracketOperator.OPEN, SelOperator.OPEN)
+                    .put(BracketOperator.CLOSE, SelOperator.CLOSE)
+                    .build();
 
-	/**
-	 * Maps {@link BooleanOperator} to the corresponding ODS {@link SelOperator}.
-	 */
-	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 ImmutableBiMap<ValueType<?>, DataType> VALUETYPES =
+            ImmutableBiMap.<ValueType<?>, DataType> builder()
+                    .put(ValueType.UNKNOWN, DataType.DT_UNKNOWN)
+                    .put(ValueType.STRING, DataType.DT_STRING)
+                    .put(ValueType.STRING_SEQUENCE, DataType.DS_STRING)
+                    .put(ValueType.DATE, DataType.DT_DATE)
+                    .put(ValueType.DATE_SEQUENCE, DataType.DS_DATE)
+                    .put(ValueType.BOOLEAN, DataType.DT_BOOLEAN)
+                    .put(ValueType.BOOLEAN_SEQUENCE, DataType.DS_BOOLEAN)
+                    .put(ValueType.BYTE, DataType.DT_BYTE)
+                    .put(ValueType.BYTE_SEQUENCE, DataType.DS_BYTE)
+                    .put(ValueType.SHORT, DataType.DT_SHORT)
+                    .put(ValueType.SHORT_SEQUENCE, DataType.DS_SHORT)
+                    .put(ValueType.INTEGER, DataType.DT_LONG)
+                    .put(ValueType.INTEGER_SEQUENCE, DataType.DS_LONG)
+                    .put(ValueType.LONG, DataType.DT_LONGLONG)
+                    .put(ValueType.LONG_SEQUENCE, DataType.DS_LONGLONG)
+                    .put(ValueType.FLOAT, DataType.DT_FLOAT)
+                    .put(ValueType.FLOAT_SEQUENCE, DataType.DS_FLOAT)
+                    .put(ValueType.DOUBLE, DataType.DT_DOUBLE)
+                    .put(ValueType.DOUBLE_SEQUENCE, DataType.DS_DOUBLE)
+                    .put(ValueType.BYTE_STREAM, DataType.DT_BYTESTR)
+                    .put(ValueType.BYTE_STREAM_SEQUENCE, DataType.DS_BYTESTR)
+                    .put(ValueType.FLOAT_COMPLEX, DataType.DT_COMPLEX)
+                    .put(ValueType.FLOAT_COMPLEX_SEQUENCE, DataType.DS_COMPLEX)
+                    .put(ValueType.DOUBLE_COMPLEX, DataType.DT_DCOMPLEX)
+                    .put(ValueType.DOUBLE_COMPLEX_SEQUENCE, DataType.DS_DCOMPLEX)
+                    .put(ValueType.ENUMERATION, DataType.DT_ENUM)
+                    .put(ValueType.ENUMERATION_SEQUENCE, DataType.DS_ENUM)
+                    .put(ValueType.FILE_LINK, DataType.DT_EXTERNALREFERENCE)
+                    .put(ValueType.FILE_LINK_SEQUENCE, DataType.DS_EXTERNALREFERENCE)
+                    .put(ValueType.BLOB, DataType.DT_BLOB)
+                    .build();
 
-	/**
-	 * Maps {@link ValueType} to the corresponding ODS {@link DataType}.
-	 */
-	public static final BiDiMapper<ValueType<?>, DataType> VALUETYPES = new BiDiMapper<>();
+    /**
+     * Maps {@link JoinType} to the corresponding ODS {@link org.asam.ods.JoinType}.
+     */
+    public static final ImmutableBiMap<JoinType, org.asam.ods.JoinType> JOINS =
+            ImmutableBiMap.<JoinType, org.asam.ods.JoinType>builder()
+                    .put(JoinType.INNER, org.asam.ods.JoinType.JTDEFAULT)
+                    .put(JoinType.OUTER, org.asam.ods.JoinType.JTOUTER)
+                    .build();
 
-	/**
-	 * Maps {@link JoinType} to the corresponding ODS {@link org.asam.ods.JoinType}.
-	 */
-	public static final BiDiMapper<JoinType, org.asam.ods.JoinType> JOINS = new BiDiMapper<>();
-
-	static {
-		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);
-		AGGREGATIONS.addMappings(Aggregation.DISTINCT_COUNT, AggrFunc.DCOUNT);
-		AGGREGATIONS.addMappings(Aggregation.MINIMUM, AggrFunc.MIN);
-		AGGREGATIONS.addMappings(Aggregation.MAXIMUM, AggrFunc.MAX);
-		AGGREGATIONS.addMappings(Aggregation.AVERAGE, AggrFunc.AVG);
-		AGGREGATIONS.addMappings(Aggregation.DEVIATION, AggrFunc.STDDEV);
-		AGGREGATIONS.addMappings(Aggregation.SUM, AggrFunc.SUM);
-		AGGREGATIONS.addMappings(Aggregation.DISTINCT, AggrFunc.DISTINCT);
-
-		CONTEXTTYPES.addMappings(ContextType.UNITUNDERTEST, "UnitUnderTest");
-		CONTEXTTYPES.addMappings(ContextType.TESTSEQUENCE, "TestSequence");
-		CONTEXTTYPES.addMappings(ContextType.TESTEQUIPMENT, "TestEquipment");
-
-		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(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);
-		VALUETYPES.addMappings(ValueType.STRING_SEQUENCE, DataType.DS_STRING);
-		VALUETYPES.addMappings(ValueType.DATE, DataType.DT_DATE);
-		VALUETYPES.addMappings(ValueType.DATE_SEQUENCE, DataType.DS_DATE);
-		VALUETYPES.addMappings(ValueType.BOOLEAN, DataType.DT_BOOLEAN);
-		VALUETYPES.addMappings(ValueType.BOOLEAN_SEQUENCE, DataType.DS_BOOLEAN);
-		VALUETYPES.addMappings(ValueType.BYTE, DataType.DT_BYTE);
-		VALUETYPES.addMappings(ValueType.BYTE_SEQUENCE, DataType.DS_BYTE);
-		VALUETYPES.addMappings(ValueType.SHORT, DataType.DT_SHORT);
-		VALUETYPES.addMappings(ValueType.SHORT_SEQUENCE, DataType.DS_SHORT);
-		VALUETYPES.addMappings(ValueType.INTEGER, DataType.DT_LONG);
-		VALUETYPES.addMappings(ValueType.INTEGER_SEQUENCE, DataType.DS_LONG);
-		VALUETYPES.addMappings(ValueType.LONG, DataType.DT_LONGLONG);
-		VALUETYPES.addMappings(ValueType.LONG_SEQUENCE, DataType.DS_LONGLONG);
-		VALUETYPES.addMappings(ValueType.FLOAT, DataType.DT_FLOAT);
-		VALUETYPES.addMappings(ValueType.FLOAT_SEQUENCE, DataType.DS_FLOAT);
-		VALUETYPES.addMappings(ValueType.DOUBLE, DataType.DT_DOUBLE);
-		VALUETYPES.addMappings(ValueType.DOUBLE_SEQUENCE, DataType.DS_DOUBLE);
-		VALUETYPES.addMappings(ValueType.BYTE_STREAM, DataType.DT_BYTESTR);
-		VALUETYPES.addMappings(ValueType.BYTE_STREAM_SEQUENCE, DataType.DS_BYTESTR);
-		VALUETYPES.addMappings(ValueType.FLOAT_COMPLEX, DataType.DT_COMPLEX);
-		VALUETYPES.addMappings(ValueType.FLOAT_COMPLEX_SEQUENCE, DataType.DS_COMPLEX);
-		VALUETYPES.addMappings(ValueType.DOUBLE_COMPLEX, DataType.DT_DCOMPLEX);
-		VALUETYPES.addMappings(ValueType.DOUBLE_COMPLEX_SEQUENCE, DataType.DS_DCOMPLEX);
-		VALUETYPES.addMappings(ValueType.ENUMERATION, DataType.DT_ENUM);
-		VALUETYPES.addMappings(ValueType.ENUMERATION_SEQUENCE, DataType.DS_ENUM);
-		VALUETYPES.addMappings(ValueType.FILE_LINK, DataType.DT_EXTERNALREFERENCE);
-		VALUETYPES.addMappings(ValueType.FILE_LINK_SEQUENCE, DataType.DS_EXTERNALREFERENCE);
-		VALUETYPES.addMappings(ValueType.BLOB, DataType.DT_BLOB);
-
-		JOINS.addMappings(JoinType.INNER, org.asam.ods.JoinType.JTDEFAULT);
-		JOINS.addMappings(JoinType.OUTER, org.asam.ods.JoinType.JTOUTER);
-	}
-
-	public static boolean isValidID(String instanceID) {
-		return instanceID != null && !instanceID.isEmpty() && !"0".equals(instanceID);
-	}
+    public static boolean isValidID(String instanceID) {
+        return instanceID != null && !instanceID.isEmpty() && !"0".equals(instanceID);
+    }
 }