Merge branch 'dev'

Signed-off-by: Matthias Koller <m.koller@peak-solution.de>
diff --git a/build.gradle b/build.gradle
index a77eb3d..ab393f7 100644
--- a/build.gradle
+++ b/build.gradle
@@ -8,7 +8,7 @@
 
 description = 'MDM API - Default Model'
 group = 'org.eclipse.mdm'
-version = '5.0.0M2'
+version = '5.0.0M3-SNAPSHOT'
 
 apply plugin: 'java'
 apply plugin: 'maven'
diff --git a/src/main/java/org/eclipse/mdm/api/dflt/model/EntityFactory.java b/src/main/java/org/eclipse/mdm/api/dflt/model/EntityFactory.java
index 2d8af76..5fc119e 100644
--- a/src/main/java/org/eclipse/mdm/api/dflt/model/EntityFactory.java
+++ b/src/main/java/org/eclipse/mdm/api/dflt/model/EntityFactory.java
@@ -1,978 +1,1030 @@
-/*

- * 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.dflt.model;

-

-import java.lang.reflect.Constructor;

-import java.lang.reflect.InvocationTargetException;

-import java.time.LocalDateTime;

-import java.util.Arrays;

-import java.util.HashSet;

-import java.util.List;

-import java.util.Locale;

-import java.util.Optional;

-import java.util.Set;

-

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

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

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

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

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

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

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

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

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

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

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

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

-

-/**

- * Creates new entities of the default application model.

- *

- * @since 1.0.0

- * @author Viktor Stoehr, Gigatronik Ingolstadt GmbH

- */

-public abstract class EntityFactory extends BaseEntityFactory {

-

-	// ======================================================================

-	// Public methods

-	// ======================================================================

-

-	/**

-	 * Always throws an UnsupportedOperationException since in a default model

-	 * each {@link Test} has a parent {@link Pool}.

-	 *

-	 * @throws UnsupportedOperationException

-	 *             Is always thrown.

-	 */

-	@Override

-	public Test createTest(String name) {

-		throw new UnsupportedOperationException("Test requires a parent Pool.");

-	}

-

-	/**

-	 * Creates a new {@link Project}.

-	 *

-	 * @param name

-	 *            Name of the created {@code Project}.

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

-	 */

-	public Project createProject(String name) {

-		Project project = new Project(createCore(Project.class));

-

-		// properties

-		project.setName(name);

-

-		return project;

-	}

-

-	/**

-	 * Creates a new {@link Pool} for given {@link Project}.

-	 *

-	 * @param name

-	 *            Name of the created {@code Pool}.

-	 * @param project

-	 *            The parent {@code Project}.

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

-	 */

-	public Pool createPool(String name, Project project) {

-		Pool pool = new Pool(createCore(Pool.class));

-

-		// relations

-		getCore(pool).getPermanentStore().set(project);

-		getCore(project).getChildrenStore().add(pool);

-

-		// properties

-		pool.setName(name);

-

-		return pool;

-	}

-

-	/**

-	 * Creates a new {@link Test} for given {@link Pool} using given

-	 * {@link TemplateTest}.

-	 *

-	 * @param name

-	 *            Name of the created {@code Test}.

-	 * @param pool

-	 *            The parent {@code Pool}.

-	 * @param templateTest

-	 *            The template the returned {@code Test} will be derived from.

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

-	 */

-	// TODO make a decision: status in or out!

-	public Test createTest(String name, Pool pool, TemplateTest templateTest) {

-		return createTest(name, pool, null, null, templateTest);

-	}

-

-	/**

-	 * Creates a new {@link ContextRoot} for given {@link TestStep} using given

-	 * {@link TemplateRoot}.

-	 *

-	 * @param testStep

-	 *            The parent {@code TestStep}.

-	 * @param templateRoot

-	 *            The template the returned {@code ContextRoot} will be derived

-	 *            from.

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

-	 */

-	public ContextRoot createContextRoot(TestStep testStep, TemplateRoot templateRoot) {

-		ContextRoot contextRoot = createContextRoot(templateRoot);

-

-		// relations

-		getCore(testStep).getMutableStore().set(contextRoot, templateRoot.getContextType());

-

-		return contextRoot;

-	}

-

-	/**

-	 * Creates a new {@link ContextRoot} for given {@link Measurement} using

-	 * given {@link TemplateRoot}.

-	 *

-	 * @param measurement

-	 *            The parent {@code Measurement}.

-	 * @param templateRoot

-	 *            The template the returned {@code ContextRoot} will be derived

-	 *            from.

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

-	 */

-	public ContextRoot createContextRoot(Measurement measurement, TemplateRoot templateRoot) {

-		ContextRoot contextRoot = createContextRoot(templateRoot);

-

-		// relations

-		getCore(measurement).getMutableStore().set(contextRoot, templateRoot.getContextType());

-

-		return contextRoot;

-	}

-

-	/**

-	 * Creates a new {@link ContextRoot} using given {@link TemplateRoot}.

-	 *

-	 * @param templateRoot

-	 *            The template the returned {@code ContextRoot} will be derived

-	 *            from.

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

-	 */

-	public ContextRoot createContextRoot(TemplateRoot templateRoot) {

-		ContextRoot contextRoot = createContextRoot(templateRoot.getName(), templateRoot.getContextType());

-

-		// relations

-		getCore(contextRoot).getMutableStore().set(templateRoot);

-

-		// create default active and mandatory context components

-		templateRoot.getTemplateComponents().stream()

-				.filter(TemplateComponent.IS_DEFAULT_ACTIVE.or(TemplateComponent.IS_MANDATORY))

-				.forEach(templateComponent -> {

-					createContextComponent(templateComponent.getName(), contextRoot);

-				});

-

-		return contextRoot;

-	}

-

-	/**

-	 * @throws IllegalArgumentException

-	 *             Thrown if given name is already in use or

-	 *             {@link TemplateComponent} with given name does not exist.

-	 */

-	@Override

-	public ContextComponent createContextComponent(String name, ContextRoot contextRoot) {

-		if (contextRoot.getContextComponent(name).isPresent()) {

-			throw new IllegalArgumentException("Context component with name '" + name + "' already exists.");

-		}

-

-		TemplateRoot templateRoot = TemplateRoot.of(contextRoot)

-				.orElseThrow(() -> new IllegalArgumentException("Template root is not available."));

-

-		Optional<TemplateComponent> templateComponent = templateRoot.getTemplateComponent(name);

-		if (templateComponent.isPresent()) {

-			// recursively create missing parent context components

-			templateComponent.get().getParentTemplateComponent()

-					.filter(tc -> !contextRoot.getContextComponent(tc.getName()).isPresent())

-					.ifPresent(tc -> createContextComponent(tc.getName(), contextRoot));

-

-			// create context component if not already done

-			if (!contextRoot.getContextComponent(name).isPresent()) {

-				ContextComponent contextComponent = super.createContextComponent(

-						templateComponent.get().getCatalogComponent().getName(), contextRoot);

-

-				// relations

-				getCore(contextComponent).getMutableStore().set(templateComponent.get());

-

-				// properties

-				contextComponent.setName(name);

-				contextComponent

-						.setMimeType(contextComponent.getMimeType().addSubType(templateComponent.get().getName()));

-				hideValues(getCore(contextComponent), templateComponent.get().getTemplateAttributes());

-				templateComponent.get().getTemplateAttributes().forEach(ta -> {

-					contextComponent.getValue(ta.getName()).set(ta.getDefaultValue().extract());

-				});

-

-				// create default active and mandatory child context components

-				templateComponent.get().getTemplateComponents().stream().filter(TemplateComponent.IS_IMPLICIT_CREATE)

-						.forEach(childTemplateComponent -> {

-							createContextComponent(childTemplateComponent.getName(), contextRoot);

-						});

-

-				// create default active and mandatory context sensors

-				templateComponent.get().getTemplateSensors().stream().filter(TemplateSensor.IS_IMPLICIT_CREATE)

-						.forEach(templateSensor -> {

-							createContextSensor(templateSensor.getName(), contextComponent);

-						});

-

-				return contextComponent;

-			}

-		}

-

-		throw new IllegalArgumentException("Template component with name '" + name + "' does not exist.");

-	}

-

-	/**

-	 * {@inheritDoc}

-	 */

-	@Override

-	public ContextSensor createContextSensor(String name, ContextComponent contextComponent) {

-		if (contextComponent.getContextSensor(name).isPresent()) {

-			throw new IllegalArgumentException("Context sensor with name '" + name + "' already exists.");

-		}

-

-		TemplateComponent templateComponent = TemplateComponent.of(contextComponent)

-				.orElseThrow(() -> new IllegalArgumentException("Template component is not available."));

-

-		Optional<TemplateSensor> templateSensor = templateComponent.getTemplateSensor(name);

-		if (templateSensor.isPresent()) {

-			ContextSensor contextSensor = super.createContextSensor(templateSensor.get().getCatalogSensor().getName(),

-					contextComponent);

-

-			// relations

-			getCore(contextSensor).getMutableStore().set(templateSensor.get());

-

-			// properties

-			contextSensor.setName(name);

-			hideValues(getCore(contextSensor), templateSensor.get().getTemplateAttributes());

-			templateSensor.get().getTemplateAttributes().forEach(ta -> {

-				contextSensor.getValue(ta.getName()).set(ta.getDefaultValue().extract());

-			});

-			

-			return contextSensor;

-		}

-

-		throw new IllegalArgumentException("Template sensor with name '" + name + "' does not exist.");

-	}

-

-	/**

-	 * Creates a new {@link CatalogComponent} with given {@link ContextType} and

-	 * name.

-	 *

-	 * @param contextType

-	 *            The {@code ContextType}.

-	 * @param name

-	 *            Name of the created {@code CatalogComponent}.

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

-	 * @throws IllegalArgumentException

-	 *             Thrown if name is not allowed.

-	 */

-	public CatalogComponent createCatalogComponent(ContextType contextType, String name) {

-		validateCatalogName(name, false);

-

-		CatalogComponent catalogComponent = new CatalogComponent(createCore(CatalogComponent.class, contextType));

-

-		// properties

-		catalogComponent.setName(name);

-		catalogComponent.setDateCreated(LocalDateTime.now());

-		catalogComponent.getValue("ValidFlag").set(VersionState.VALID);

-

-		return catalogComponent;

-	}

-

-	/**

-	 * Creates a new {@link CatalogAttribute} for given

-	 * {@link CatalogComponent}. The {@link ValueType} may be one of the

-	 * following:

-	 *

-	 * <ul>

-	 * <li>{@link ValueType#STRING}</li>

-	 * <li>{@link ValueType#STRING_SEQUENCE}</li>

-	 * <li>{@link ValueType#DATE}</li>

-	 * <li>{@link ValueType#DATE_SEQUENCE}</li>

-	 * <li>{@link ValueType#BOOLEAN}</li>

-	 * <li>{@link ValueType#BOOLEAN_SEQUENCE}</li>

-	 * <li>{@link ValueType#BYTE}</li>

-	 * <li>{@link ValueType#BYTE_SEQUENCE}</li>

-	 * <li>{@link ValueType#SHORT}</li>

-	 * <li>{@link ValueType#SHORT_SEQUENCE}</li>

-	 * <li>{@link ValueType#INTEGER}</li>

-	 * <li>{@link ValueType#INTEGER_SEQUENCE}</li>

-	 * <li>{@link ValueType#LONG}</li>

-	 * <li>{@link ValueType#LONG_SEQUENCE}</li>

-	 * <li>{@link ValueType#FLOAT}</li>

-	 * <li>{@link ValueType#FLOAT_SEQUENCE}</li>

-	 * <li>{@link ValueType#DOUBLE}</li>

-	 * <li>{@link ValueType#DOUBLE_SEQUENCE}</li>

-	 * <li>{@link ValueType#BYTE_STREAM}</li>

-	 * <li>{@link ValueType#BYTE_STREAM_SEQUENCE}</li>

-	 * <li>{@link ValueType#FLOAT_COMPLEX}</li>

-	 * <li>{@link ValueType#FLOAT_COMPLEX_SEQUENCE}</li>

-	 * <li>{@link ValueType#DOUBLE_COMPLEX}</li>

-	 * <li>{@link ValueType#DOUBLE_COMPLEX_SEQUENCE}</li>

-	 * <li>{@link ValueType#FILE_LINK}</li>

-	 * <li>{@link ValueType#FILE_LINK_SEQUENCE}</li>

-	 * </ul>

-	 *

-	 *

-	 * @param name

-	 *            Name of the created {@code CatalogAttribute}.

-	 * @param valueType

-	 *            The {@code ValueType}.

-	 * @param catalogComponent

-	 *            The parent {@code CatalogComponent}.

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

-	 * @throws IllegalArgumentException

-	 *             Thrown if given name is already in use or not allowed or

-	 *             given {@code ValueType} is not supported.

-	 */

-	public CatalogAttribute createCatalogAttribute(String name, ValueType<?> valueType,

-			CatalogComponent catalogComponent) {

-		validateCatalogName(name, true);

-

-		if (catalogComponent.getCatalogAttribute(name).isPresent()) {

-			throw new IllegalArgumentException("Catalog attribute with name '" + name + "' already exists.");

-		} else if (valueType.isEnumerationType() || valueType.isByteStreamType() || valueType.isUnknown()

-				|| valueType.isBlob()) {

-			throw new IllegalArgumentException("Value type '" + valueType + "' is not allowed.");

-		}

-

-		CatalogAttribute catalogAttribute = new CatalogAttribute(

-				createCore(CatalogAttribute.class, catalogComponent.getContextType()));

-

-		// relations

-		getCore(catalogAttribute).getPermanentStore().set(catalogComponent);

-		getCore(catalogComponent).getChildrenStore().add(catalogAttribute);

-

-		// properties

-		catalogAttribute.setName(name);

-		catalogAttribute.setValueType(valueType);

-		catalogAttribute.setSortIndex(nextIndex(catalogComponent.getCatalogAttributes()));

-

-		return catalogAttribute;

-	}

-

-	/**

-	 * Creates a new {@link CatalogAttribute} for given

-	 * {@link CatalogComponent}.

-	 *

-	 * @param name

-	 *            Name of the created {@code CatalogAttribute}.

-	 * @param enumerationObject

-	 *            The enumeration.

-	 * @param catalogComponent

-	 *            The parent {@code CatalogComponent}.

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

-	 * @throws IllegalArgumentException

-	 *             Thrown if given name is already in use or not allowed or

-	 *             given enumeration class is not supported.

-	 */

-	public CatalogAttribute createCatalogAttribute(String name, Enumeration<?> enumerationObj,

-			CatalogComponent catalogComponent) {

-		validateCatalogName(name, true);

-		validateEnum(enumerationObj);

-		if (catalogComponent.getCatalogAttribute(name).isPresent()) {

-			throw new IllegalArgumentException("Catalog attribute with name '" + name + "' already exists.");

-		}

-

-		CatalogAttribute catalogAttribute = new CatalogAttribute(

-				createCore(CatalogAttribute.class, catalogComponent.getContextType()));

-

-		// relations

-		getCore(catalogAttribute).getPermanentStore().set(catalogComponent);

-		getCore(catalogComponent).getChildrenStore().add(catalogAttribute);

-

-		// properties

-		catalogAttribute.setName(name);

-		catalogAttribute.setEnumerationObj(enumerationObj);

-		catalogAttribute.setSortIndex(nextIndex(catalogComponent.getCatalogAttributes()));

-

-		return catalogAttribute;

-	}

-	

-	/**

-	 * Creates a new {@link CatalogSensor} for given

-	 * {@link CatalogComponent}.

-	 *

-	 * @param name

-	 *            Name of the created {@code CatalogSensor}.

-	 * @param enumerationObject

-	 *            The enumeration.

-	 * @param catalogComponent

-	 *            The parent {@code CatalogComponent}.

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

-	 * @throws IllegalArgumentException

-	 *             Thrown if given name is already in use or not allowed 

-	 */

-	public CatalogSensor createCatalogSensor(String name, CatalogComponent catalogComponent) {

-		validateCatalogName(name, false);

-

-		if (!catalogComponent.getContextType().isTestEquipment()) {

-			throw new IllegalArgumentException("Catalog component is not of type 'TESTEQUIPMENT'");

-		} else if (catalogComponent.getCatalogSensor(name).isPresent()) {

-			throw new IllegalArgumentException("Catalog sensor with name '" + name + "' already exists.");

-		}

-

-		CatalogSensor catalogSensor = new CatalogSensor(createCore(CatalogSensor.class));

-

-		// relations

-		getPermanentStore(catalogSensor).set(catalogComponent);

-		getChildrenStore(catalogComponent).add(catalogSensor);

-

-		// properties

-		catalogSensor.setName(name);

-		catalogSensor.setDateCreated(LocalDateTime.now());

-

-		return catalogSensor;

-	}

-

-	/**

-	 * Creates a new {@link TemplateRoot} with given {@link ContextType} and

-	 * name.

-	 *

-	 * @param contextType

-	 *            The {@code ContextType}.

-	 * @param name

-	 *            Name of the created {@code TemplateRoot}.

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

-	 */

-	public TemplateRoot createTemplateRoot(ContextType contextType, String name) {

-		TemplateRoot templateRoot = new TemplateRoot(createCore(TemplateRoot.class, contextType));

-

-		// properties

-		templateRoot.setName(name);

-		templateRoot.setDateCreated(LocalDateTime.now());

-		templateRoot.setVersionState(VersionState.EDITABLE);

-		templateRoot.setVersion(Integer.valueOf(1));

-

-		return templateRoot;

-	}

-

-	/**

-	 * Creates a new {@link TemplateComponent} for given {@link TemplateRoot}

-	 * using given {@link CatalogComponent}.

-	 *

-	 * @param name

-	 *            Name of the created {@code TemplateComponent}.

-	 * @param templateRoot

-	 *            The parent {@code TemplateRoot}.

-	 * @param catalogComponent

-	 *            The associated {@link CatalogComponent}.

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

-	 * @throws IllegalArgumentException

-	 *             Thrown if {@code ContextType} of {@code

-	 * 		TemplateRoot} and {@code CatalogComponent} do not match or given

-	 *             name is already in use.

-	 */

-	public TemplateComponent createTemplateComponent(String name, TemplateRoot templateRoot,

-			CatalogComponent catalogComponent) {

-		if (!templateRoot.getContextType().equals(catalogComponent.getContextType())) {

-			throw new IllegalArgumentException("Context type of template root and catalog component do not match.");

-		} else if (templateRoot.getTemplateComponent(name).isPresent()) {

-			throw new IllegalArgumentException("Template component with name '" + name + "' already exists.");

-		}

-

-		TemplateComponent templateComponent = new TemplateComponent(

-				createCore(TemplateComponent.class, templateRoot.getContextType()));

-

-		// relations

-		getCore(templateComponent).getPermanentStore().set(templateRoot);

-		getCore(templateComponent).getMutableStore().set(catalogComponent);

-		getCore(templateRoot).getChildrenStore().add(templateComponent);

-

-		// properties

-		templateComponent.setName(name);

-		templateComponent.setOptional(Boolean.TRUE);

-		templateComponent.setDefaultActive(Boolean.TRUE);

-		templateComponent.setSeriesConstant(Boolean.TRUE);

-		templateComponent.setSortIndex(nextIndex(templateRoot.getTemplateComponents()));

-

-		// create template attributes

-		catalogComponent.getCatalogAttributes().forEach(ca -> createTemplateAttribute(ca.getName(), templateComponent));

-

-		return templateComponent;

-	}

-

-	/**

-	 * Creates a new {@link TemplateComponent} for given

-	 * {@link TemplateComponent} using given {@link CatalogComponent}.

-	 *

-	 * @param name

-	 *            Name of the created {@code TemplateComponent}.

-	 * @param partentComponentTemplate

-	 *            The parent {@code TemplateComponent}.

-	 * @param catalogComponent

-	 *            The associated {@link CatalogComponent}.

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

-	 * @throws IllegalArgumentException

-	 *             Thrown if {@code ContextType} of {@code

-	 * 		TemplateComponent} and {@code CatalogComponent} do not match or

-	 *             given name is already in use.

-	 */

-	public TemplateComponent createTemplateComponent(String name, TemplateComponent partentComponentTemplate,

-			CatalogComponent catalogComponent) {

-		TemplateRoot templateRoot = partentComponentTemplate.getTemplateRoot();

-		if (!templateRoot.getContextType().equals(catalogComponent.getContextType())) {

-			throw new IllegalArgumentException("Context type of template root and catalog component do not match.");

-		} else if (templateRoot.getTemplateComponent(name).isPresent()) {

-			throw new IllegalArgumentException("Template component with name '" + name + "' already exists.");

-		}

-

-		TemplateComponent templateComponent = new TemplateComponent(

-				createCore(TemplateComponent.class, templateRoot.getContextType()));

-

-		// relations

-		getCore(templateComponent).getPermanentStore().set(partentComponentTemplate);

-		getCore(templateComponent).getMutableStore().set(catalogComponent);

-		getCore(partentComponentTemplate).getChildrenStore().add(templateComponent);

-

-		// properties

-		templateComponent.setName(name);

-		templateComponent.setOptional(Boolean.TRUE);

-		templateComponent.setDefaultActive(Boolean.TRUE);

-		templateComponent.setSeriesConstant(Boolean.TRUE);

-		templateComponent.setSortIndex(nextIndex(partentComponentTemplate.getTemplateComponents()));

-

-		// create template attributes

-		catalogComponent.getCatalogAttributes().forEach(ca -> createTemplateAttribute(ca.getName(), templateComponent));

-

-		return templateComponent;

-	}

-

-	/**

-	 * Creates a new {@link TemplateAttribute} for given

-	 * {@link TemplateComponent}.

-	 *

-	 * @param name

-	 *            Name of the created {@code TemplateAttribute}.

-	 * @param templateComponent

-	 *            The parent {@code TemplateComponent}.

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

-	 * @throws IllegalArgumentException

-	 *             Thrown if given name is already in use.

-	 */

-	public TemplateAttribute createTemplateAttribute(String name, TemplateComponent templateComponent) {

-		if (templateComponent.getTemplateAttribute(name).isPresent()) {

-			throw new IllegalArgumentException("Template attribute with name '" + name + "' already exists.");

-		}

-

-		CatalogComponent catalogComponent = templateComponent.getCatalogComponent();

-		Optional<CatalogAttribute> catalogAttribute = catalogComponent.getCatalogAttribute(name);

-		if (catalogAttribute.isPresent()) {

-			TemplateAttribute templateAttribute = new TemplateAttribute(

-					createCore(TemplateAttribute.class, catalogComponent.getContextType()));

-

-			// relations

-			getCore(templateAttribute).getPermanentStore().set(templateComponent);

-			getCore(templateAttribute).getMutableStore().set(catalogAttribute.get());

-			getCore(templateComponent).getChildrenStore().add(templateAttribute);

-

-			// properties

-			templateAttribute.setName(name);

-			templateAttribute.setValueReadOnly(Boolean.FALSE);

-			templateAttribute.setOptional(Boolean.TRUE);

-

-			return templateAttribute;

-		}

-

-		throw new IllegalArgumentException("Catalog attribute with name '" + name + "' does not exists.");

-	}

-

-	/**

-	 * Creates a new {@link TemplateSensor} for given {@link TemplateComponent}

-	 * based on the given {@link CatalogSensor}.

-	 *

-	 * @param name

-	 *            Name of the created {@code TemplateAttribute}.

-	 * @param templateComponent

-	 *            The parent {@code TemplateComponent}.

-	 * @param catalogSensor

-	 *            reference CatalogSensor

-	 * @param quantity

-	 *            Quantity to create {@link TemplateSensor} for

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

-	 * @throws IllegalArgumentException

-	 *             Thrown if given name is already in use.

-	 */

-	public TemplateSensor createTemplateSensor(String name, TemplateComponent templateComponent,

-			CatalogSensor catalogSensor, Quantity quantity) {

-		if (templateComponent.getTemplateSensor(name)

-				.isPresent()) {

-			throw new IllegalArgumentException("Template sensor with name '" + name + "' already exists.");

-		}

-

-		if (catalogSensor != null) {

-			TemplateSensor templateSensor = new TemplateSensor(createCore(TemplateSensor.class));

-

-			// relations

-			getPermanentStore(templateSensor).set(templateComponent);

-			getMutableStore(templateSensor).set(catalogSensor);

-			getMutableStore(templateSensor).set(quantity);

-			getChildrenStore(templateComponent).add(templateSensor);

-

-			// properties

-			templateSensor.setName(name);

-			templateSensor.setDefaultActive(true);

-			templateSensor.setOptional(Boolean.TRUE);

-

-			return templateSensor;

-		}

-

-		throw new IllegalArgumentException("Catalog attribute with name '" + name + "' does not exists.");

-	}

-

-	/**

-	 * Creates a new {@link TemplateTestStep}.

-	 *

-	 * @param name

-	 *            Name of the created {@code TemplateTestStep}.

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

-	 */

-	public TemplateTestStep createTemplateTestStep(String name) {

-		TemplateTestStep templateTestStep = new TemplateTestStep(createCore(TemplateTestStep.class));

-

-		// properties

-		templateTestStep.setName(name);

-		templateTestStep.setDateCreated(LocalDateTime.now());

-		templateTestStep.setVersionState(VersionState.EDITABLE);

-		templateTestStep.setVersion(Integer.valueOf(1));

-

-		return templateTestStep;

-	}

-

-	/**

-	 * Creates a new {@link TemplateTest}.

-	 *

-	 * @param name

-	 *            Name of the created {@code TemplateTest}.

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

-	 */

-	public TemplateTest createTemplateTest(String name) {

-		TemplateTest templateTest = new TemplateTest(createCore(TemplateTest.class));

-

-		// properties

-		templateTest.setName(name);

-		templateTest.setDateCreated(LocalDateTime.now());

-		templateTest.setVersion(Integer.valueOf(1));

-		templateTest.setVersionState(VersionState.EDITABLE);

-

-		return templateTest;

-	}

-

-	/**

-	 * Creates a new {@link TemplateTestStepUsage} for given

-	 * {@link TemplateTest} using given {@link TemplateTestStep}.

-	 *

-	 * @param name

-	 *            Name of the created {@code TemplateTestStepUsage}.

-	 * @param templateTest

-	 *            The parent {@link TemplateTest}.

-	 * @param templateTestStep

-	 *            The related {@link TemplateTestStep}.

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

-	 */

-	public TemplateTestStepUsage createTemplateTestStepUsage(String name, TemplateTest templateTest,

-			TemplateTestStep templateTestStep) {

-		if (templateTest.getTemplateTestStepUsage(name).isPresent()) {

-			throw new IllegalArgumentException("Template test step usage with name '" + name + "' already exists.");

-		}

-

-		TemplateTestStepUsage templateTestStepUsage = new TemplateTestStepUsage(

-				createCore(TemplateTestStepUsage.class));

-

-		// relations

-		getCore(templateTestStepUsage).getPermanentStore().set(templateTest);

-		getCore(templateTestStepUsage).getMutableStore().set(templateTestStep);

-		getCore(templateTest).getChildrenStore().add(templateTestStepUsage);

-

-		// properties

-		templateTestStepUsage.setName(name);

-		templateTestStepUsage.setOptional(Boolean.TRUE);

-		templateTestStepUsage.setDefaultActive(Boolean.TRUE);

-		templateTestStepUsage.setSortIndex(nextIndex(templateTest.getTemplateTestStepUsages()));

-

-		return templateTestStepUsage;

-	}

-

-	/**

-	 * Creates a new {@link ValueList}.

-	 *

-	 * @param name

-	 *            Name of the created {@code ValueList}.

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

-	 */

-	public ValueList createValueList(String name) {

-		ValueList valueList = new ValueList(createCore(ValueList.class));

-

-		// properties

-		valueList.setName(name);

-		valueList.setDateCreated(LocalDateTime.now());

-

-		return valueList;

-	}

-

-	/**

-	 * Creates a new {@link ValueListValue} for given {@link ValueList}.

-	 *

-	 * @param name

-	 *            Name of the created {@code ValueListValue}.

-	 * @param valueList

-	 *            The parent {@code ValueList}.

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

-	 */

-	public ValueListValue createValueListValue(String name, ValueList valueList) {

-		if (valueList.getValueListValue(name).isPresent()) {

-			throw new IllegalArgumentException("Value list value with name '" + name + "' already exists.");

-		}

-

-		ValueListValue valueListValue = new ValueListValue(createCore(ValueListValue.class));

-

-		// relations

-		getCore(valueListValue).getPermanentStore().set(valueList);

-		getCore(valueList).getChildrenStore().add(valueListValue);

-

-		// properties

-		valueListValue.setName(name);

-		valueListValue.setSortIndex(nextIndex(valueList.getValueListValues()));

-

-		// this property is hidden by the public API and is not allowed to be

-		// modified!

-		valueListValue.getValue(ValueListValue.ATTR_SCALAR_TYPE).set(ScalarType.STRING);

-

-		return valueListValue;

-	}

-

-	// ======================================================================

-	// Protected methods

-	// ======================================================================

-

-	/**

-	 * Creates a new {@link Test} for given {@link Pool} using given

-	 * {@link TemplateTest}.

-	 *

-	 * @param name

-	 *            Name of the created {@code Test}.

-	 * @param pool

-	 *            The parent {@code Pool}.

-	 * @param statusTest

-	 *            The related {@link Status} of the created {@code

-	 * 		Test}.

-	 * @param statusTestStep

-	 *            The related {@link Status} of the created {@code

-	 * 		TestStep}.

-	 * @param templateTest

-	 *            The template the returned {@code Test} will be derived from.

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

-	 */

-	// TODO make a decision: status in or out!

-	protected Test createTest(String name, Pool pool, Status statusTest, Status statusTestStep,

-			TemplateTest templateTest) {

-		Test test = createTest(name, pool, statusTest);

-

-		// relations

-		getCore(test).getMutableStore().set(templateTest);

-

-		// create default active and mandatory test steps according to the

-		// template

-		templateTest.getTemplateTestStepUsages().stream().filter(TemplateTestStepUsage.IS_IMPLICIT_CREATE)

-				.map(TemplateTestStepUsage::getTemplateTestStep).forEach(templateTestStep -> {

-					createTestStep(test, statusTestStep, templateTestStep);

-				});

-

-		return test;

-	}

-

-	/**

-	 * Creates a new {@link Test} for given {@link Pool}.

-	 *

-	 * @param name

-	 *            Name of the created {@code Test}.

-	 * @param pool

-	 *            The parent {@code Pool}.

-	 * @param status

-	 *            The related {@link Status}.

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

-	 */

-	// TODO make a decision: status in or out!

-	protected Test createTest(String name, Pool pool, Status status) {

-		Test test = super.createTest(name);

-

-		// relations

-		getCore(test).getPermanentStore().set(pool);

-		getCore(pool).getChildrenStore().add(test);

-

-		if (status != null) {

-			status.assign(test);

-		}

-

-		return test;

-	}

-

-	/**

-	 * Creates a new {@link TestStep} for given {@link Test} using given

-	 * {@link TemplateTestStep}.

-	 *

-	 * @param test

-	 *            The parent {@code Test}.

-	 * @param templateTestStep

-	 *            The template the returned {@code TestStep} will be derived

-	 *            from.

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

-	 */

-	protected TestStep createTestStep(Test test, TemplateTestStep templateTestStep) {

-		return createTestStep(test, null, templateTestStep);

-	}

-

-	/**

-	 * Creates a new {@link TestStep} for given {@link Test} using given

-	 * {@link TemplateTestStep}.

-	 *

-	 * @param test

-	 *            The parent {@code Test}.

-	 * @param status

-	 *            The related {@link Status}.

-	 * @param templateTestStep

-	 *            The template the returned {@code TestStep} will be derived

-	 *            from.

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

-	 */

-	// TODO make a decision: status in or out!

-	protected TestStep createTestStep(Test test, Status status, TemplateTestStep templateTestStep) {

-		TemplateTest templateTest = TemplateTest.of(test)

-				.orElseThrow(() -> new IllegalArgumentException("Template test is not available."));

-		if (!templateTest.contains(templateTestStep)) {

-			throw new IllegalArgumentException("Template test step is part of the test template.");

-		}

-

-		TestStep testStep = createTestStep(templateTestStep.getName(), test, status);

-

-		// relations

-		getCore(testStep).getMutableStore().set(templateTestStep);

-

-		// create initial context roots

-		templateTestStep.getTemplateRoots().forEach(templateRoot -> createContextRoot(testStep, templateRoot));

-

-		return testStep;

-	}

-

-	/**

-	 * Creates a new {@link TestStep} for given {@link Test}.

-	 *

-	 * @param name

-	 *            Name of the created {@code Test}.

-	 * @param test

-	 *            The parent {@code Test}.

-	 * @param status

-	 *            The related {@link Status}.

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

-	 */

-	// TODO make a decision: status in or out!

-	protected TestStep createTestStep(String name, Test test, Status status) {

-		TestStep testStep = super.createTestStep(name, test);

-

-		if (status != null) {

-			status.assign(testStep);

-		}

-

-		return testStep;

-	}

-	

-	/**

-	 * {@inheritDoc}

-	 */

-	@Override

-	protected <T extends BaseEntity> T createBaseEntity(Class<T> clazz, Core core) {

-		try {

-			Constructor<T> constructor = clazz.getDeclaredConstructor(Core.class);

-			try {

-				return constructor.newInstance(core);

-			} catch (IllegalAccessException exc) {

-				return super.createBaseEntity(clazz, core);

-			}

-		} catch (NoSuchMethodException | InvocationTargetException | InstantiationException exc) {

-			throw new IllegalStateException(exc.getMessage(), exc);

-		}

-	}

-

-	/**

-	 * Checks whether given enumeration is defined in the application

-	 * model or not.

-	 *

-	 * @param enumerationObj

-	 *            The checked enumeration class.

-	 * @throws IllegalArgumentException

-	 *             Thrown if given enumeration class is not supported.

-	 */

-	protected abstract void validateEnum(Enumeration<?> enumerationObj);

-

-	// ======================================================================

-	// Private methods

-	// ======================================================================

-

-	/**

-	 * Checks whether given catalog name is allowed or not.

-	 *

-	 * @param name

-	 *            The checked name.

-	 * @param isAttributeName

-	 *            Flag indicates whether given name is for a catalog attribute.

-	 * @throws IllegalArgumentException

-	 *             Thrown if given name is not allowed.

-	 */

-	private static void validateCatalogName(String name, boolean isAttributeName) {

-		if (!isValidCatalogName(name)) {

-			throw new IllegalArgumentException(

-					"A catalog name is not allowed to be empty and " + "must not exceed 30 characters.");

-		} else if (name.toLowerCase(Locale.ROOT).startsWith("ao")) {

-			throw new IllegalArgumentException("A catalog name is not allowed to " + "start with 'ao' (case ignored).");

-		} else if (!name.matches("^[\\w]+$")) {

-			throw new IllegalArgumentException(

-					"A calatog name may only constists of the " + "following characters: a-z, A-Z, 0-9 or _.");

-		} else if (isAttributeName && Arrays.asList("id", "name", "mimetype").contains(name.toLowerCase(Locale.ROOT))) {

-			throw new IllegalArgumentException(

-					"A catalog attribute name is not allowed to be " + "'id', 'name' or 'mimetype' (case ignored).");

-		}

-	}

-	

-	/**

-	 * Checks whether given catalog name is valid

-	 *

-	 * @param name

-	 *            The checked name.

-	 * @return Returns {@code true} if name is a valid catalog name

-	 */

-	private static boolean isValidCatalogName(String name) {

-		return name != null && !name.isEmpty() && name.length() <= 30;

-	}

-

-	/**

-	 * Hides {@link Value} containers missing in the templates.

-	 *

-	 * @param contextCore

-	 *            The {@link ContextComponent} {@link Core}.

-	 * @param templateAttributes

-	 *            The {@link TemplateAttribute}s of the template.

-	 */

-	private static void hideValues(Core contextCore, List<TemplateAttribute> templateAttributes) {

-		Set<String> names = new HashSet<>(contextCore.getValues().keySet());

-		names.remove(Entity.ATTR_NAME);

-		names.remove(Entity.ATTR_MIMETYPE);

-		templateAttributes.stream().map(Entity::getName).forEach(names::remove);

-		contextCore.hideValues(names);

-	}

-

-}

+/*
+ * 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.dflt.model;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.time.LocalDateTime;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Optional;
+import java.util.Set;
+
+import org.eclipse.mdm.api.base.adapter.Core;
+import org.eclipse.mdm.api.base.model.BaseEntity;
+import org.eclipse.mdm.api.base.model.BaseEntityFactory;
+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.Enumeration;
+import org.eclipse.mdm.api.base.model.Measurement;
+import org.eclipse.mdm.api.base.model.Quantity;
+import org.eclipse.mdm.api.base.model.ScalarType;
+import org.eclipse.mdm.api.base.model.Test;
+import org.eclipse.mdm.api.base.model.TestStep;
+import org.eclipse.mdm.api.base.model.Value;
+import org.eclipse.mdm.api.base.model.ValueType;
+import org.eclipse.mdm.api.base.model.VersionState;
+
+/**
+ * Creates new entities of the default application model.
+ *
+ * @since 1.0.0
+ * @author Viktor Stoehr, Gigatronik Ingolstadt GmbH
+ */
+public abstract class EntityFactory extends BaseEntityFactory {
+
+	// ======================================================================
+	// Public methods
+	// ======================================================================
+
+	/**
+	 * Always throws an UnsupportedOperationException since in a default model
+	 * each {@link Test} has a parent {@link Pool}.
+	 *
+	 * @throws UnsupportedOperationException
+	 *             Is always thrown.
+	 */
+	@Override
+	public Test createTest(String name) {
+		throw new UnsupportedOperationException("Test requires a parent Pool.");
+	}
+
+	/**
+	 * Creates a new {@link Project}.
+	 *
+	 * @param name
+	 *            Name of the created {@code Project}.
+	 * @return The created {@code Project} is returned.
+	 */
+	public Project createProject(String name) {
+		Project project = new Project(createCore(Project.class));
+
+		// properties
+		project.setName(name);
+
+		return project;
+	}
+
+	/**
+	 * Creates a new {@link Pool} for given {@link Project}.
+	 *
+	 * @param name
+	 *            Name of the created {@code Pool}.
+	 * @param project
+	 *            The parent {@code Project}.
+	 * @return The created {@code Pool} is returned.
+	 */
+	public Pool createPool(String name, Project project) {
+		Pool pool = new Pool(createCore(Pool.class));
+
+		// relations
+		getCore(pool).getPermanentStore().set(project);
+		getCore(project).getChildrenStore().add(pool);
+
+		// properties
+		pool.setName(name);
+
+		return pool;
+	}
+
+	/**
+	 * Creates a new {@link Test} for given {@link Pool} using given
+	 * {@link TemplateTest}.
+	 *
+	 * @param name
+	 *            Name of the created {@code Test}.
+	 * @param pool
+	 *            The parent {@code Pool}.
+	 * @param templateTest
+	 *            The template the returned {@code Test} will be derived from.
+	 * @return The created {@code Test} is returned.
+	 */
+	// TODO make a decision: status in or out!
+	public Test createTest(String name, Pool pool, TemplateTest templateTest) {
+		return createTest(name, pool, null, null, templateTest);
+	}
+
+	/**
+	 * Creates a new {@link ContextRoot} for given {@link TestStep} using given
+	 * {@link TemplateRoot}.
+	 *
+	 * @param testStep
+	 *            The parent {@code TestStep}.
+	 * @param templateRoot
+	 *            The template the returned {@code ContextRoot} will be derived
+	 *            from.
+	 * @return The created {@code ContextRoot} is returned.
+	 */
+	public ContextRoot createContextRoot(TestStep testStep, TemplateRoot templateRoot) {
+		ContextRoot contextRoot = createContextRoot(templateRoot);
+
+		// relations
+		getCore(testStep).getMutableStore().set(contextRoot, templateRoot.getContextType());
+
+		return contextRoot;
+	}
+
+	/**
+	 * Creates a new {@link ContextRoot} for given {@link Measurement} using
+	 * given {@link TemplateRoot}.
+	 *
+	 * @param measurement
+	 *            The parent {@code Measurement}.
+	 * @param templateRoot
+	 *            The template the returned {@code ContextRoot} will be derived
+	 *            from.
+	 * @return The created {@code ContextRoot} is returned.
+	 */
+	public ContextRoot createContextRoot(Measurement measurement, TemplateRoot templateRoot) {
+		ContextRoot contextRoot = createContextRoot(templateRoot);
+
+		// relations
+		getCore(measurement).getMutableStore().set(contextRoot, templateRoot.getContextType());
+
+		return contextRoot;
+	}
+
+	/**
+	 * Creates a new {@link ContextRoot} using given {@link TemplateRoot}.
+	 *
+	 * @param templateRoot
+	 *            The template the returned {@code ContextRoot} will be derived
+	 *            from.
+	 * @return The created {@code ContextRoot} is returned.
+	 */
+	public ContextRoot createContextRoot(TemplateRoot templateRoot) {
+		ContextRoot contextRoot = createContextRoot(templateRoot.getName(), templateRoot.getContextType());
+
+		// relations
+		getCore(contextRoot).getMutableStore().set(templateRoot);
+
+		// create default active and mandatory context components
+		templateRoot.getTemplateComponents().stream()
+				.filter(TemplateComponent.IS_DEFAULT_ACTIVE.or(TemplateComponent.IS_MANDATORY))
+				.forEach(templateComponent -> {
+					createContextComponent(templateComponent.getName(), contextRoot);
+				});
+
+		return contextRoot;
+	}
+
+	/**
+	 * @throws IllegalArgumentException
+	 *             Thrown if given name is already in use or
+	 *             {@link TemplateComponent} with given name does not exist.
+	 */
+	@Override
+	public ContextComponent createContextComponent(String name, ContextRoot contextRoot) {
+		if (contextRoot.getContextComponent(name).isPresent()) {
+			throw new IllegalArgumentException("Context component with name '" + name + "' already exists.");
+		}
+
+		TemplateRoot templateRoot = TemplateRoot.of(contextRoot)
+				.orElseThrow(() -> new IllegalArgumentException("Template root is not available."));
+
+		Optional<TemplateComponent> templateComponent = templateRoot.getTemplateComponent(name);
+		if (templateComponent.isPresent()) {
+			// recursively create missing parent context components
+			templateComponent.get().getParentTemplateComponent()
+					.filter(tc -> !contextRoot.getContextComponent(tc.getName()).isPresent())
+					.ifPresent(tc -> createContextComponent(tc.getName(), contextRoot));
+
+			// create context component if not already done
+			if (!contextRoot.getContextComponent(name).isPresent()) {
+				ContextComponent contextComponent = super.createContextComponent(
+						templateComponent.get().getCatalogComponent().getName(), contextRoot);
+
+				// relations
+				getCore(contextComponent).getMutableStore().set(templateComponent.get());
+
+				// properties
+				contextComponent.setName(name);
+				contextComponent
+						.setMimeType(contextComponent.getMimeType().addSubType(templateComponent.get().getName()));
+				hideValues(getCore(contextComponent), templateComponent.get().getTemplateAttributes());
+				templateComponent.get().getTemplateAttributes().forEach(ta -> {
+					contextComponent.getValue(ta.getName()).set(ta.getDefaultValue().extract());
+				});
+
+				// create default active and mandatory child context components
+				templateComponent.get().getTemplateComponents().stream().filter(TemplateComponent.IS_IMPLICIT_CREATE)
+						.forEach(childTemplateComponent -> {
+							createContextComponent(childTemplateComponent.getName(), contextRoot);
+						});
+
+				// create default active and mandatory context sensors
+				templateComponent.get().getTemplateSensors().stream().filter(TemplateSensor.IS_IMPLICIT_CREATE)
+						.forEach(templateSensor -> {
+							createContextSensor(templateSensor.getName(), contextComponent);
+						});
+
+				return contextComponent;
+			}
+		}
+
+		throw new IllegalArgumentException("Template component with name '" + name + "' does not exist.");
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public ContextSensor createContextSensor(String name, ContextComponent contextComponent) {
+		if (contextComponent.getContextSensor(name).isPresent()) {
+			throw new IllegalArgumentException("Context sensor with name '" + name + "' already exists.");
+		}
+
+		TemplateComponent templateComponent = TemplateComponent.of(contextComponent)
+				.orElseThrow(() -> new IllegalArgumentException("Template component is not available."));
+
+		Optional<TemplateSensor> templateSensor = templateComponent.getTemplateSensor(name);
+		if (templateSensor.isPresent()) {
+			ContextSensor contextSensor = super.createContextSensor(templateSensor.get().getCatalogSensor().getName(),
+					contextComponent);
+
+			// relations
+			getCore(contextSensor).getMutableStore().set(templateSensor.get());
+
+			// properties
+			contextSensor.setName(name);
+			hideValues(getCore(contextSensor), templateSensor.get().getTemplateAttributes());
+			templateSensor.get().getTemplateAttributes().forEach(ta -> {
+				contextSensor.getValue(ta.getName()).set(ta.getDefaultValue().extract());
+			});
+			
+			return contextSensor;
+		}
+
+		throw new IllegalArgumentException("Template sensor with name '" + name + "' does not exist.");
+	}
+
+	/**
+	 * Creates a new {@link CatalogComponent} with given {@link ContextType} and
+	 * name.
+	 *
+	 * @param contextType
+	 *            The {@code ContextType}.
+	 * @param name
+	 *            Name of the created {@code CatalogComponent}.
+	 * @return The created {@code CatalogComponent} is returned.
+	 * @throws IllegalArgumentException
+	 *             Thrown if name is not allowed.
+	 */
+	public CatalogComponent createCatalogComponent(ContextType contextType, String name) {
+		validateCatalogName(name, false);
+
+		CatalogComponent catalogComponent = new CatalogComponent(createCore(CatalogComponent.class, contextType));
+
+		// properties
+		catalogComponent.setName(name);
+		catalogComponent.setDateCreated(LocalDateTime.now());
+		catalogComponent.getValue("ValidFlag").set(VersionState.VALID);
+
+		return catalogComponent;
+	}
+
+	/**
+	 * Creates a new {@link CatalogAttribute} for given
+	 * {@link CatalogComponent}. The {@link ValueType} may be one of the
+	 * following:
+	 *
+	 * <ul>
+	 * <li>{@link ValueType#STRING}</li>
+	 * <li>{@link ValueType#STRING_SEQUENCE}</li>
+	 * <li>{@link ValueType#DATE}</li>
+	 * <li>{@link ValueType#DATE_SEQUENCE}</li>
+	 * <li>{@link ValueType#BOOLEAN}</li>
+	 * <li>{@link ValueType#BOOLEAN_SEQUENCE}</li>
+	 * <li>{@link ValueType#BYTE}</li>
+	 * <li>{@link ValueType#BYTE_SEQUENCE}</li>
+	 * <li>{@link ValueType#SHORT}</li>
+	 * <li>{@link ValueType#SHORT_SEQUENCE}</li>
+	 * <li>{@link ValueType#INTEGER}</li>
+	 * <li>{@link ValueType#INTEGER_SEQUENCE}</li>
+	 * <li>{@link ValueType#LONG}</li>
+	 * <li>{@link ValueType#LONG_SEQUENCE}</li>
+	 * <li>{@link ValueType#FLOAT}</li>
+	 * <li>{@link ValueType#FLOAT_SEQUENCE}</li>
+	 * <li>{@link ValueType#DOUBLE}</li>
+	 * <li>{@link ValueType#DOUBLE_SEQUENCE}</li>
+	 * <li>{@link ValueType#BYTE_STREAM}</li>
+	 * <li>{@link ValueType#BYTE_STREAM_SEQUENCE}</li>
+	 * <li>{@link ValueType#FLOAT_COMPLEX}</li>
+	 * <li>{@link ValueType#FLOAT_COMPLEX_SEQUENCE}</li>
+	 * <li>{@link ValueType#DOUBLE_COMPLEX}</li>
+	 * <li>{@link ValueType#DOUBLE_COMPLEX_SEQUENCE}</li>
+	 * <li>{@link ValueType#FILE_LINK}</li>
+	 * <li>{@link ValueType#FILE_LINK_SEQUENCE}</li>
+	 * </ul>
+	 *
+	 *
+	 * @param name
+	 *            Name of the created {@code CatalogAttribute}.
+	 * @param valueType
+	 *            The {@code ValueType}.
+	 * @param catalogComponent
+	 *            The parent {@code CatalogComponent}.
+	 * @return The created {@code CatalogAttribute} is returned.
+	 * @throws IllegalArgumentException
+	 *             Thrown if given name is already in use or not allowed or
+	 *             given {@code ValueType} is not supported.
+	 */
+	public CatalogAttribute createCatalogAttribute(String name, ValueType<?> valueType,
+			CatalogComponent catalogComponent) {
+		validateCatalogName(name, true);
+
+		if (catalogComponent.getCatalogAttribute(name).isPresent()) {
+			throw new IllegalArgumentException("Catalog attribute with name '" + name + "' already exists.");
+		} else if (valueType.isEnumerationType() || valueType.isByteStreamType() || valueType.isUnknown()
+				|| valueType.isBlob()) {
+			throw new IllegalArgumentException("Value type '" + valueType + "' is not allowed.");
+		}
+
+		CatalogAttribute catalogAttribute = new CatalogAttribute(
+				createCore(CatalogAttribute.class, catalogComponent.getContextType()));
+
+		// relations
+		getCore(catalogAttribute).getPermanentStore().set(catalogComponent);
+		getCore(catalogComponent).getChildrenStore().add(catalogAttribute);
+
+		// properties
+		catalogAttribute.setName(name);
+		catalogAttribute.setValueType(valueType);
+		catalogAttribute.setSortIndex(nextIndex(catalogComponent.getCatalogAttributes()));
+
+		return catalogAttribute;
+	}
+
+	/**
+	 * Creates a new {@link CatalogAttribute} for given
+	 * {@link CatalogComponent}.
+	 *
+	 * @param name
+	 *            Name of the created {@code CatalogAttribute}.
+	 * @param enumerationObject
+	 *            The enumeration.
+	 * @param catalogComponent
+	 *            The parent {@code CatalogComponent}.
+	 * @return The created {@code CatalogAttribute} is returned.
+	 * @throws IllegalArgumentException
+	 *             Thrown if given name is already in use or not allowed or
+	 *             given enumeration class is not supported.
+	 */
+	public CatalogAttribute createCatalogAttribute(String name, Enumeration<?> enumerationObj,
+			CatalogComponent catalogComponent) {
+		validateCatalogName(name, true);
+		validateEnum(enumerationObj);
+		if (catalogComponent.getCatalogAttribute(name).isPresent()) {
+			throw new IllegalArgumentException("Catalog attribute with name '" + name + "' already exists.");
+		}
+
+		CatalogAttribute catalogAttribute = new CatalogAttribute(
+				createCore(CatalogAttribute.class, catalogComponent.getContextType()));
+
+		// relations
+		getCore(catalogAttribute).getPermanentStore().set(catalogComponent);
+		getCore(catalogComponent).getChildrenStore().add(catalogAttribute);
+
+		// properties
+		catalogAttribute.setName(name);
+		catalogAttribute.setEnumerationObj(enumerationObj);
+		catalogAttribute.setSortIndex(nextIndex(catalogComponent.getCatalogAttributes()));
+
+		return catalogAttribute;
+	}
+	
+	/**
+	 * Creates a new {@link CatalogAttribute} for given {@link CatalogSensor}. The
+	 * {@link ValueType} may be one of the following like in
+	 * {@link #createCatalogAttribute(String, ValueType, CatalogComponent)}:
+	 *
+	 * @param name
+	 *            Name of the created {@code CatalogAttribute}.
+	 * @param valueType
+	 *            The {@code ValueType}.
+	 * @param catalogSensor
+	 *            The parent {@code CatalogSensor}.
+	 * @return The created {@code CatalogAttribute} is returned.
+	 * @throws IllegalArgumentException
+	 *             Thrown if given name is already in use or not allowed or given
+	 *             {@code ValueType} is not supported.
+	 */
+	public CatalogAttribute createCatalogSensorAttribute(String name, ValueType<?> valueType,
+			CatalogSensor catalogSensor) {
+		validateCatalogName(name, true);
+
+		if (catalogSensor.getCatalogAttribute(name).isPresent()) {
+			throw new IllegalArgumentException("CatalogSensor attribute with name '" + name + "' already exists.");
+		} else if (valueType.isEnumerationType() || valueType.isByteStreamType() || valueType.isUnknown()
+				|| valueType.isBlob()) {
+			throw new IllegalArgumentException("Value type '" + valueType + "' is not allowed.");
+		}
+
+		CatalogAttribute catalogAttribute = new CatalogAttribute(
+				createCore(CatalogAttribute.class));
+
+		// relations
+		getCore(catalogAttribute).getPermanentStore().set(catalogSensor);
+		getCore(catalogSensor).getChildrenStore().add(catalogAttribute);
+
+		// properties
+		catalogAttribute.setName(name);
+		catalogAttribute.setValueType(valueType);
+		catalogAttribute.setSortIndex(nextIndex(catalogSensor.getCatalogAttributes()));
+
+		return catalogAttribute;
+	}
+
+	/**
+	 * Creates a new {@link CatalogSensor} for given {@link CatalogComponent}.
+	 *
+	 * @param name
+	 *            Name of the created {@code CatalogSensor}.
+	 * @param enumerationObject
+	 *            The enumeration.
+	 * @param catalogComponent
+	 *            The parent {@code CatalogComponent}.
+	 * @return The created {@code CatalogSensor} is returned.
+	 * @throws IllegalArgumentException
+	 *             Thrown if given name is already in use or not allowed
+	 */
+	public CatalogSensor createCatalogSensor(String name, CatalogComponent catalogComponent) {
+		validateCatalogName(name, false);
+
+		if (!catalogComponent.getContextType().isTestEquipment()) {
+			throw new IllegalArgumentException("Catalog component is not of type 'TESTEQUIPMENT'");
+		} else if (catalogComponent.getCatalogSensor(name).isPresent()) {
+			throw new IllegalArgumentException("Catalog sensor with name '" + name + "' already exists.");
+		}
+
+		CatalogSensor catalogSensor = new CatalogSensor(createCore(CatalogSensor.class));
+
+		// relations
+		getPermanentStore(catalogSensor).set(catalogComponent);
+		getChildrenStore(catalogComponent).add(catalogSensor);
+
+		// properties
+		catalogSensor.setName(name);
+		catalogSensor.setDateCreated(LocalDateTime.now());
+
+		return catalogSensor;
+	}
+
+	/**
+	 * Creates a new {@link TemplateRoot} with given {@link ContextType} and
+	 * name.
+	 *
+	 * @param contextType
+	 *            The {@code ContextType}.
+	 * @param name
+	 *            Name of the created {@code TemplateRoot}.
+	 * @return The created {@code TemplateRoot} is returned.
+	 */
+	public TemplateRoot createTemplateRoot(ContextType contextType, String name) {
+		TemplateRoot templateRoot = new TemplateRoot(createCore(TemplateRoot.class, contextType));
+
+		// properties
+		templateRoot.setName(name);
+		templateRoot.setDateCreated(LocalDateTime.now());
+		templateRoot.setVersionState(VersionState.EDITABLE);
+		templateRoot.setVersion(Integer.valueOf(1));
+
+		return templateRoot;
+	}
+
+	/**
+	 * Creates a new {@link TemplateComponent} for given {@link TemplateRoot}
+	 * using given {@link CatalogComponent}.
+	 *
+	 * @param name
+	 *            Name of the created {@code TemplateComponent}.
+	 * @param templateRoot
+	 *            The parent {@code TemplateRoot}.
+	 * @param catalogComponent
+	 *            The associated {@link CatalogComponent}.
+	 * @return The created {@code TemplateComponent} is returned.
+	 * @throws IllegalArgumentException
+	 *             Thrown if {@code ContextType} of {@code
+	 * 		TemplateRoot} and {@code CatalogComponent} do not match or given
+	 *             name is already in use.
+	 */
+	public TemplateComponent createTemplateComponent(String name, TemplateRoot templateRoot,
+			CatalogComponent catalogComponent) {
+		if (!templateRoot.getContextType().equals(catalogComponent.getContextType())) {
+			throw new IllegalArgumentException("Context type of template root and catalog component do not match.");
+		} else if (templateRoot.getTemplateComponent(name).isPresent()) {
+			throw new IllegalArgumentException("Template component with name '" + name + "' already exists.");
+		}
+
+		TemplateComponent templateComponent = new TemplateComponent(
+				createCore(TemplateComponent.class, templateRoot.getContextType()));
+
+		// relations
+		getCore(templateComponent).getPermanentStore().set(templateRoot);
+		getCore(templateComponent).getMutableStore().set(catalogComponent);
+		getCore(templateRoot).getChildrenStore().add(templateComponent);
+
+		// properties
+		templateComponent.setName(name);
+		templateComponent.setOptional(Boolean.TRUE);
+		templateComponent.setDefaultActive(Boolean.TRUE);
+		templateComponent.setSeriesConstant(Boolean.TRUE);
+		templateComponent.setSortIndex(nextIndex(templateRoot.getTemplateComponents()));
+
+		// create template attributes
+		catalogComponent.getCatalogAttributes().forEach(ca -> createTemplateAttribute(ca.getName(), templateComponent));
+
+		return templateComponent;
+	}
+
+	/**
+	 * Creates a new {@link TemplateComponent} for given
+	 * {@link TemplateComponent} using given {@link CatalogComponent}.
+	 *
+	 * @param name
+	 *            Name of the created {@code TemplateComponent}.
+	 * @param partentComponentTemplate
+	 *            The parent {@code TemplateComponent}.
+	 * @param catalogComponent
+	 *            The associated {@link CatalogComponent}.
+	 * @return The created {@code TemplateComponent} is returned.
+	 * @throws IllegalArgumentException
+	 *             Thrown if {@code ContextType} of {@code
+	 * 		TemplateComponent} and {@code CatalogComponent} do not match or
+	 *             given name is already in use.
+	 */
+	public TemplateComponent createTemplateComponent(String name, TemplateComponent partentComponentTemplate,
+			CatalogComponent catalogComponent) {
+		TemplateRoot templateRoot = partentComponentTemplate.getTemplateRoot();
+		if (!templateRoot.getContextType().equals(catalogComponent.getContextType())) {
+			throw new IllegalArgumentException("Context type of template root and catalog component do not match.");
+		} else if (templateRoot.getTemplateComponent(name).isPresent()) {
+			throw new IllegalArgumentException("Template component with name '" + name + "' already exists.");
+		}
+
+		TemplateComponent templateComponent = new TemplateComponent(
+				createCore(TemplateComponent.class, templateRoot.getContextType()));
+
+		// relations
+		getCore(templateComponent).getPermanentStore().set(partentComponentTemplate);
+		getCore(templateComponent).getMutableStore().set(catalogComponent);
+		getCore(partentComponentTemplate).getChildrenStore().add(templateComponent);
+
+		// properties
+		templateComponent.setName(name);
+		templateComponent.setOptional(Boolean.TRUE);
+		templateComponent.setDefaultActive(Boolean.TRUE);
+		templateComponent.setSeriesConstant(Boolean.TRUE);
+		templateComponent.setSortIndex(nextIndex(partentComponentTemplate.getTemplateComponents()));
+
+		// create template attributes
+		catalogComponent.getCatalogAttributes().forEach(ca -> createTemplateAttribute(ca.getName(), templateComponent));
+
+		return templateComponent;
+	}
+
+	/**
+	 * Creates a new {@link TemplateAttribute} for given
+	 * {@link TemplateComponent}.
+	 *
+	 * @param name
+	 *            Name of the created {@code TemplateAttribute}.
+	 * @param templateComponent
+	 *            The parent {@code TemplateComponent}.
+	 * @return The created {@code TemplateAttribute} is returned.
+	 * @throws IllegalArgumentException
+	 *             Thrown if given name is already in use.
+	 */
+	public TemplateAttribute createTemplateAttribute(String name, TemplateComponent templateComponent) {
+		if (templateComponent.getTemplateAttribute(name).isPresent()) {
+			throw new IllegalArgumentException("Template attribute with name '" + name + "' already exists.");
+		}
+
+		CatalogComponent catalogComponent = templateComponent.getCatalogComponent();
+		Optional<CatalogAttribute> catalogAttribute = catalogComponent.getCatalogAttribute(name);
+		if (catalogAttribute.isPresent()) {
+			TemplateAttribute templateAttribute = new TemplateAttribute(
+					createCore(TemplateAttribute.class, catalogComponent.getContextType()));
+
+			// relations
+			getCore(templateAttribute).getPermanentStore().set(templateComponent);
+			getCore(templateAttribute).getMutableStore().set(catalogAttribute.get());
+			getCore(templateComponent).getChildrenStore().add(templateAttribute);
+
+			// properties
+			templateAttribute.setName(name);
+			templateAttribute.setValueReadOnly(Boolean.FALSE);
+			templateAttribute.setOptional(Boolean.TRUE);
+
+			return templateAttribute;
+		}
+
+		throw new IllegalArgumentException("Catalog attribute with name '" + name + "' does not exists.");
+	}
+
+	/**
+	 * Creates a new {@link TemplateSensor} for given {@link TemplateComponent}
+	 * based on the given {@link CatalogSensor}.
+	 *
+	 * @param name
+	 *            Name of the created {@code TemplateAttribute}.
+	 * @param templateComponent
+	 *            The parent {@code TemplateComponent}.
+	 * @param catalogSensor
+	 *            reference CatalogSensor
+	 * @param quantity
+	 *            Quantity to create {@link TemplateSensor} for
+	 * @return The created {@code TemplateSensor} is returned.
+	 * @throws IllegalArgumentException
+	 *             Thrown if given name is already in use.
+	 */
+	public TemplateSensor createTemplateSensor(String name, TemplateComponent templateComponent,
+			CatalogSensor catalogSensor, Quantity quantity) {
+		if (templateComponent.getTemplateSensor(name)
+				.isPresent()) {
+			throw new IllegalArgumentException("Template sensor with name '" + name + "' already exists.");
+		}
+
+		if (catalogSensor != null) {
+			TemplateSensor templateSensor = new TemplateSensor(createCore(TemplateSensor.class));
+			// create all implicit TemplateAttributes
+			for (CatalogAttribute catAttr : catalogSensor.getCatalogAttributes()) {
+				TemplateAttribute tplAttr = new TemplateAttribute(createCore(TemplateAttribute.class));
+				tplAttr.setName(catAttr.getName());
+				tplAttr.setValueReadOnly(Boolean.FALSE);
+				tplAttr.setOptional(Boolean.TRUE);
+				getPermanentStore(tplAttr).set(templateSensor);
+				getMutableStore(tplAttr).set(catAttr);
+				getCore(templateSensor).getChildrenStore()
+						.add(tplAttr);
+			}
+
+			// relations
+			getPermanentStore(templateSensor).set(templateComponent);
+			getMutableStore(templateSensor).set(catalogSensor);
+			getMutableStore(templateSensor).set(quantity);
+			getChildrenStore(templateComponent).add(templateSensor);
+
+			// properties
+			templateSensor.setName(name);
+			templateSensor.setDefaultActive(true);
+			templateSensor.setOptional(Boolean.TRUE);
+
+			return templateSensor;
+		}
+
+		throw new IllegalArgumentException("Catalog attribute with name '" + name + "' does not exists.");
+	}
+
+	/**
+	 * Creates a new {@link TemplateTestStep}.
+	 *
+	 * @param name
+	 *            Name of the created {@code TemplateTestStep}.
+	 * @return The created {@code TemplateTestStep} is returned.
+	 */
+	public TemplateTestStep createTemplateTestStep(String name) {
+		TemplateTestStep templateTestStep = new TemplateTestStep(createCore(TemplateTestStep.class));
+
+		// properties
+		templateTestStep.setName(name);
+		templateTestStep.setDateCreated(LocalDateTime.now());
+		templateTestStep.setVersionState(VersionState.EDITABLE);
+		templateTestStep.setVersion(Integer.valueOf(1));
+
+		return templateTestStep;
+	}
+
+	/**
+	 * Creates a new {@link TemplateTest}.
+	 *
+	 * @param name
+	 *            Name of the created {@code TemplateTest}.
+	 * @return The created {@code TemplateTest} is returned.
+	 */
+	public TemplateTest createTemplateTest(String name) {
+		TemplateTest templateTest = new TemplateTest(createCore(TemplateTest.class));
+
+		// properties
+		templateTest.setName(name);
+		templateTest.setDateCreated(LocalDateTime.now());
+		templateTest.setVersion(Integer.valueOf(1));
+		templateTest.setVersionState(VersionState.EDITABLE);
+
+		return templateTest;
+	}
+
+	/**
+	 * Creates a new {@link TemplateTestStepUsage} for given
+	 * {@link TemplateTest} using given {@link TemplateTestStep}.
+	 *
+	 * @param name
+	 *            Name of the created {@code TemplateTestStepUsage}.
+	 * @param templateTest
+	 *            The parent {@link TemplateTest}.
+	 * @param templateTestStep
+	 *            The related {@link TemplateTestStep}.
+	 * @return The created {@code TemplateTestStepUsage} is returned.
+	 */
+	public TemplateTestStepUsage createTemplateTestStepUsage(String name, TemplateTest templateTest,
+			TemplateTestStep templateTestStep) {
+		if (templateTest.getTemplateTestStepUsage(name).isPresent()) {
+			throw new IllegalArgumentException("Template test step usage with name '" + name + "' already exists.");
+		}
+
+		TemplateTestStepUsage templateTestStepUsage = new TemplateTestStepUsage(
+				createCore(TemplateTestStepUsage.class));
+
+		// relations
+		getCore(templateTestStepUsage).getPermanentStore().set(templateTest);
+		getCore(templateTestStepUsage).getMutableStore().set(templateTestStep);
+		getCore(templateTest).getChildrenStore().add(templateTestStepUsage);
+
+		// properties
+		templateTestStepUsage.setName(name);
+		templateTestStepUsage.setOptional(Boolean.TRUE);
+		templateTestStepUsage.setDefaultActive(Boolean.TRUE);
+		templateTestStepUsage.setSortIndex(nextIndex(templateTest.getTemplateTestStepUsages()));
+
+		return templateTestStepUsage;
+	}
+
+	/**
+	 * Creates a new {@link ValueList}.
+	 *
+	 * @param name
+	 *            Name of the created {@code ValueList}.
+	 * @return The created {@code ValueList} is returned.
+	 */
+	public ValueList createValueList(String name) {
+		ValueList valueList = new ValueList(createCore(ValueList.class));
+
+		// properties
+		valueList.setName(name);
+		valueList.setDateCreated(LocalDateTime.now());
+
+		return valueList;
+	}
+
+	/**
+	 * Creates a new {@link ValueListValue} for given {@link ValueList}.
+	 *
+	 * @param name
+	 *            Name of the created {@code ValueListValue}.
+	 * @param valueList
+	 *            The parent {@code ValueList}.
+	 * @return The created {@code ValueListValue} is returned.
+	 */
+	public ValueListValue createValueListValue(String name, ValueList valueList) {
+		if (valueList.getValueListValue(name).isPresent()) {
+			throw new IllegalArgumentException("Value list value with name '" + name + "' already exists.");
+		}
+
+		ValueListValue valueListValue = new ValueListValue(createCore(ValueListValue.class));
+
+		// relations
+		getCore(valueListValue).getPermanentStore().set(valueList);
+		getCore(valueList).getChildrenStore().add(valueListValue);
+
+		// properties
+		valueListValue.setName(name);
+		valueListValue.setSortIndex(nextIndex(valueList.getValueListValues()));
+
+		// this property is hidden by the public API and is not allowed to be
+		// modified!
+		valueListValue.getValue(ValueListValue.ATTR_SCALAR_TYPE).set(ScalarType.STRING);
+
+		return valueListValue;
+	}
+
+	// ======================================================================
+	// Protected methods
+	// ======================================================================
+
+	/**
+	 * Creates a new {@link Test} for given {@link Pool} using given
+	 * {@link TemplateTest}.
+	 *
+	 * @param name
+	 *            Name of the created {@code Test}.
+	 * @param pool
+	 *            The parent {@code Pool}.
+	 * @param statusTest
+	 *            The related {@link Status} of the created {@code
+	 * 		Test}.
+	 * @param statusTestStep
+	 *            The related {@link Status} of the created {@code
+	 * 		TestStep}.
+	 * @param templateTest
+	 *            The template the returned {@code Test} will be derived from.
+	 * @return The created {@code Test} is returned.
+	 */
+	// TODO make a decision: status in or out!
+	protected Test createTest(String name, Pool pool, Status statusTest, Status statusTestStep,
+			TemplateTest templateTest) {
+		Test test = createTest(name, pool, statusTest);
+
+		// relations
+		getCore(test).getMutableStore().set(templateTest);
+
+		// create default active and mandatory test steps according to the
+		// template
+		templateTest.getTemplateTestStepUsages().stream().filter(TemplateTestStepUsage.IS_IMPLICIT_CREATE)
+				.map(TemplateTestStepUsage::getTemplateTestStep).forEach(templateTestStep -> {
+					createTestStep(test, statusTestStep, templateTestStep);
+				});
+
+		return test;
+	}
+
+	/**
+	 * Creates a new {@link Test} for given {@link Pool}.
+	 *
+	 * @param name
+	 *            Name of the created {@code Test}.
+	 * @param pool
+	 *            The parent {@code Pool}.
+	 * @param status
+	 *            The related {@link Status}.
+	 * @return The created {@code Test} is returned.
+	 */
+	// TODO make a decision: status in or out!
+	protected Test createTest(String name, Pool pool, Status status) {
+		Test test = super.createTest(name);
+
+		// relations
+		getCore(test).getPermanentStore().set(pool);
+		getCore(pool).getChildrenStore().add(test);
+
+		if (status != null) {
+			status.assign(test);
+		}
+
+		return test;
+	}
+
+	/**
+	 * Creates a new {@link TestStep} for given {@link Test} using given
+	 * {@link TemplateTestStep}.
+	 *
+	 * @param test
+	 *            The parent {@code Test}.
+	 * @param templateTestStep
+	 *            The template the returned {@code TestStep} will be derived
+	 *            from.
+	 * @return The created {@code TestStep} is returned.
+	 */
+	protected TestStep createTestStep(Test test, TemplateTestStep templateTestStep) {
+		return createTestStep(test, null, templateTestStep);
+	}
+
+	/**
+	 * Creates a new {@link TestStep} for given {@link Test} using given
+	 * {@link TemplateTestStep}.
+	 *
+	 * @param test
+	 *            The parent {@code Test}.
+	 * @param status
+	 *            The related {@link Status}.
+	 * @param templateTestStep
+	 *            The template the returned {@code TestStep} will be derived
+	 *            from.
+	 * @return The created {@code TestStep} is returned.
+	 */
+	// TODO make a decision: status in or out!
+	protected TestStep createTestStep(Test test, Status status, TemplateTestStep templateTestStep) {
+		TemplateTest templateTest = TemplateTest.of(test)
+				.orElseThrow(() -> new IllegalArgumentException("Template test is not available."));
+		if (!templateTest.contains(templateTestStep)) {
+			throw new IllegalArgumentException("Template test step is part of the test template.");
+		}
+
+		TestStep testStep = createTestStep(templateTestStep.getName(), test, status);
+
+		// relations
+		getCore(testStep).getMutableStore().set(templateTestStep);
+
+		// create initial context roots
+		templateTestStep.getTemplateRoots().forEach(templateRoot -> createContextRoot(testStep, templateRoot));
+
+		return testStep;
+	}
+
+	/**
+	 * Creates a new {@link TestStep} for given {@link Test}.
+	 *
+	 * @param name
+	 *            Name of the created {@code Test}.
+	 * @param test
+	 *            The parent {@code Test}.
+	 * @param status
+	 *            The related {@link Status}.
+	 * @return The created {@code TestStep} is returned.
+	 */
+	// TODO make a decision: status in or out!
+	protected TestStep createTestStep(String name, Test test, Status status) {
+		TestStep testStep = super.createTestStep(name, test);
+
+		if (status != null) {
+			status.assign(testStep);
+		}
+
+		return testStep;
+	}
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	protected <T extends BaseEntity> T createBaseEntity(Class<T> clazz, Core core) {
+		try {
+			Constructor<T> constructor = clazz.getDeclaredConstructor(Core.class);
+			try {
+				return constructor.newInstance(core);
+			} catch (IllegalAccessException exc) {
+				return super.createBaseEntity(clazz, core);
+			}
+		} catch (NoSuchMethodException | InvocationTargetException | InstantiationException exc) {
+			throw new IllegalStateException(exc.getMessage(), exc);
+		}
+	}
+
+	/**
+	 * Checks whether given enumeration is defined in the application
+	 * model or not.
+	 *
+	 * @param enumerationObj
+	 *            The checked enumeration class.
+	 * @throws IllegalArgumentException
+	 *             Thrown if given enumeration class is not supported.
+	 */
+	protected abstract void validateEnum(Enumeration<?> enumerationObj);
+
+	// ======================================================================
+	// Private methods
+	// ======================================================================
+
+	/**
+	 * Checks whether given catalog name is allowed or not.
+	 *
+	 * @param name
+	 *            The checked name.
+	 * @param isAttributeName
+	 *            Flag indicates whether given name is for a catalog attribute.
+	 * @throws IllegalArgumentException
+	 *             Thrown if given name is not allowed.
+	 */
+	private static void validateCatalogName(String name, boolean isAttributeName) {
+		if (!isValidCatalogName(name)) {
+			throw new IllegalArgumentException(
+					"A catalog name is not allowed to be empty and " + "must not exceed 30 characters.");
+		} else if (name.toLowerCase(Locale.ROOT).startsWith("ao")) {
+			throw new IllegalArgumentException("A catalog name is not allowed to " + "start with 'ao' (case ignored).");
+		} else if (!name.matches("^[\\w]+$")) {
+			throw new IllegalArgumentException(
+					"A calatog name may only constists of the " + "following characters: a-z, A-Z, 0-9 or _.");
+		} else if (isAttributeName && Arrays.asList("id", "name", "mimetype").contains(name.toLowerCase(Locale.ROOT))) {
+			throw new IllegalArgumentException(
+					"A catalog attribute name is not allowed to be " + "'id', 'name' or 'mimetype' (case ignored).");
+		}
+	}
+	
+	/**
+	 * Checks whether given catalog name is valid
+	 *
+	 * @param name
+	 *            The checked name.
+	 * @return Returns {@code true} if name is a valid catalog name
+	 */
+	private static boolean isValidCatalogName(String name) {
+		return name != null && !name.isEmpty() && name.length() <= 30;
+	}
+
+	/**
+	 * Hides {@link Value} containers missing in the templates.
+	 *
+	 * @param contextCore
+	 *            The {@link ContextComponent} {@link Core}.
+	 * @param templateAttributes
+	 *            The {@link TemplateAttribute}s of the template.
+	 */
+	private static void hideValues(Core contextCore, List<TemplateAttribute> templateAttributes) {
+		Set<String> names = new HashSet<>(contextCore.getValues().keySet());
+		names.remove(Entity.ATTR_NAME);
+		names.remove(Entity.ATTR_MIMETYPE);
+		templateAttributes.stream().map(Entity::getName).forEach(names::remove);
+		contextCore.hideValues(names);
+	}
+
+}
\ No newline at end of file