521052 - [REQU-76] (1) Classes

Signed-off-by: Martin Fleischer <m.fleischer@peak-solution.de>
diff --git a/src/main/java/org/eclipse/mdm/api/base/adapter/DefaultCore.java b/src/main/java/org/eclipse/mdm/api/base/adapter/DefaultCore.java
index 16b6e17..14f2b6f 100644
--- a/src/main/java/org/eclipse/mdm/api/base/adapter/DefaultCore.java
+++ b/src/main/java/org/eclipse/mdm/api/base/adapter/DefaultCore.java
@@ -12,7 +12,9 @@
 import java.util.HashMap;
 import java.util.Map;
 
-import org.eclipse.mdm.api.base.model.Core;
+import org.eclipse.mdm.api.base.core.ChildrenStore;
+import org.eclipse.mdm.api.base.core.Core;
+import org.eclipse.mdm.api.base.core.EntityStore;
 import org.eclipse.mdm.api.base.model.Entity;
 import org.eclipse.mdm.api.base.model.Value;
 import org.eclipse.mdm.api.base.query.Record;
diff --git a/src/main/java/org/eclipse/mdm/api/base/core/ChildrenStore.java b/src/main/java/org/eclipse/mdm/api/base/core/ChildrenStore.java
new file mode 100644
index 0000000..c24202d
--- /dev/null
+++ b/src/main/java/org/eclipse/mdm/api/base/core/ChildrenStore.java
@@ -0,0 +1,103 @@
+package org.eclipse.mdm.api.base.core;

+

+import java.util.ArrayList;

+import java.util.Collections;

+import java.util.Comparator;

+import java.util.HashMap;

+import java.util.List;

+import java.util.Map;

+

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

+

+/**

+ * Holds related entities of any kind and keeps track of modifications.

+ */

+public final class ChildrenStore {

+

+	private final Map<Class<? extends Deletable>, List<? extends Deletable>> current = new HashMap<>(0);

+	private final Map<Class<? extends Deletable>, List<? extends Deletable>> removed = new HashMap<>(0);

+

+	/**

+	 * Returns current set of related children mapped by their type.

+	 *

+	 * @return Returned {@code Map} is unmodifiable.

+	 */

+	public Map<Class<? extends Deletable>, List<? extends Deletable>> getCurrent() {

+		return Collections.unmodifiableMap(current);

+	}

+

+	/**

+	 * Returns current set of removed related children mapped by their type.

+	 *

+	 * @return Returned {@code Map} is unmodifiable.

+	 */

+	public Map<Class<? extends Deletable>, List<? extends Deletable>> getRemoved() {

+		return Collections.unmodifiableMap(removed);

+	}

+

+	/**

+	 * Returns related child entities of given type.

+	 *

+	 * @param <T>

+	 *            Desired entity type.

+	 * @param entityClass

+	 *            Used as identifier.

+	 * @return Returned {@code List} is unmodifiable.

+	 */

+	@SuppressWarnings("unchecked")

+	public <T extends Deletable> List<T> get(Class<T> entityClass) {

+		return Collections.unmodifiableList((List<T>) current.computeIfAbsent(entityClass, k -> new ArrayList<>()));

+	}

+

+	/**

+	 * Sorts the child entities with given {@code Comparator}.

+	 *

+	 * @param <T>

+	 *            Desired entity type.

+	 * @param entityClass

+	 *            Used as identifier.

+	 * @param comparator

+	 *            Used for sorting.

+	 */

+	@SuppressWarnings("unchecked")

+	public <T extends Deletable> void sort(Class<T> entityClass, Comparator<? super T> comparator) {

+		List<T> children = (List<T>) current.get(entityClass);

+		if (children != null) {

+			children.sort(comparator);

+		}

+	}

+

+	/**

+	 * Adds given child entity.

+	 *

+	 * @param child

+	 *            The new child.

+	 */

+	@SuppressWarnings("unchecked")

+	public void add(Deletable child) {

+		removed.getOrDefault(child.getClass(), new ArrayList<>()).remove(child);

+		((List<Deletable>) current.computeIfAbsent(child.getClass(), k -> new ArrayList<>())).add(child);

+	}

+

+	/**

+	 * Removes given child entity.

+	 *

+	 * @param child

+	 *            The child which will be removed.

+	 */

+	@SuppressWarnings("unchecked")

+	public void remove(Deletable child) {

+		List<Deletable> children = (List<Deletable>) current.getOrDefault(child.getClass(), new ArrayList<>());

+		if (children.remove(child) && child.getID() != null && child.getID().length() > 0) {

+			((List<Deletable>) removed.computeIfAbsent(child.getClass(), k -> new ArrayList<>())).add(child);

+		}

+	}

+

+	/**

+	 * Clean up list of removed entities.

+	 */

+	void apply() {

+		removed.clear();

+	}

+

+}
\ No newline at end of file
diff --git a/src/main/java/org/eclipse/mdm/api/base/core/Core.java b/src/main/java/org/eclipse/mdm/api/base/core/Core.java
new file mode 100644
index 0000000..a8b33ae
--- /dev/null
+++ b/src/main/java/org/eclipse/mdm/api/base/core/Core.java
@@ -0,0 +1,193 @@
+/*
+ * 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.base.core;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+import org.eclipse.mdm.api.base.model.FileLink;
+import org.eclipse.mdm.api.base.model.Value;
+
+/**
+ * Provides access to the internals of any entity:
+ *
+ * <ul>
+ * <li>name of the data source</li>
+ * <li>name of the type</li>
+ * <li>instance ID</li>
+ * <li>values</li>
+ * <li>added/removed file links</li>
+ * <li>related entities</li>
+ * <li>parent/child entities</li>
+ * </ul>
+ *
+ * @since 1.0.0
+ * @author Viktor Stoehr, Gigatronik Ingolstadt GmbH
+ */
+public interface Core {
+
+	// ======================================================================
+	// Public methods
+	// ======================================================================
+
+	/**
+	 * Returns the name of the data source this entity was retrieved from.
+	 *
+	 * @return Name of the data source.
+	 */
+	String getSourceName();
+
+	/**
+	 * Returns the name of the entity type.
+	 *
+	 * @return Name of the entity type is returned.
+	 */
+	String getTypeName();
+
+	/**
+	 * Returns the instance ID or {@code 0} if this instance is not yet
+	 * persisted.
+	 *
+	 * @return The instance ID is returned.
+	 */
+	String getID();
+
+	/**
+	 * Sets an instance ID.
+	 *
+	 * @param instanceID
+	 *            The new instance ID.
+	 */
+	void setID(String instanceID);
+
+	/**
+	 * Returns <i>all</i> {@link Value} containers of this entity.
+	 *
+	 * @return Values mapped by their name are returned.
+	 */
+	Map<String, Value> getValues();
+
+	/**
+	 * Hides {@link Value} containers whose name is contained in the given names
+	 * {@code Collection}.
+	 * E.g. hide attributes from a CatalogComponent when not used in a TemplateComponent.  
+	 *
+	 * @param names
+	 *            Names of the {@code Value} which shall be hidden.
+	 */
+	void hideValues(Collection<String> names);
+
+	/**
+	 * Returns <i>all</i> {@link Value} containers, including the hidden ones.
+	 *
+	 * @return All {@code Value} containers are returned.
+	 */
+	Map<String, Value> getAllValues();
+
+	/**
+	 * Returns all newly added {@link FileLink}.
+	 *
+	 * @return New {@code FileLink}s are returned.
+	 */
+	default List<FileLink> getAddedFileLinks() {
+		Predicate<FileLink> isRemote = FileLink::isRemote;
+
+		List<FileLink> fileLinks = getValues().values().stream().filter(v -> v.getValueType().isFileLink())
+				.filter(Value::isValid).map(v -> (FileLink) v.extract()).filter(isRemote.negate())
+				.collect(Collectors.toList());
+
+		List<Value> values = getValues().values().stream().filter(v -> v.getValueType().isFileLinkSequence())
+				.filter(Value::isValid).collect(Collectors.toList());
+
+		for (Value value : values) {
+			Arrays.stream((FileLink[]) value.extract()).filter(isRemote.negate()).forEach(fileLinks::add);
+		}
+
+		return fileLinks;
+	}
+
+	/**
+	 * Returns all removed {@link FileLink}s.
+	 *
+	 * @return Removed {@code FileLink}s are returned.
+	 */
+	default List<FileLink> getRemovedFileLinks() {
+		Predicate<FileLink> isRemote = FileLink::isRemote;
+
+		List<FileLink> fileLinks = getValues().values().stream().filter(v -> v.getValueType().isFileLink())
+				.filter(Value::isModified).map(v -> (FileLink) v.extractInitial()).filter(Objects::nonNull)
+				.filter(isRemote).collect(Collectors.toList());
+
+		List<Value> values = getValues().values().stream().filter(v -> v.getValueType().isFileLinkSequence())
+				.filter(Value::wasValid).filter(Value::isModified).collect(Collectors.toList());
+
+		for (Value value : values) {
+			List<FileLink> current = Arrays.asList((FileLink[]) value.extract());
+			Arrays.stream((FileLink[]) value.extractInitial()).filter(fl -> !current.contains(fl))
+					.forEach(fileLinks::add);
+		}
+
+		return fileLinks;
+	}
+
+	/**
+	 * Applies modifications made to the entity stores and {@link Value}
+	 * containers. This method is called when a transaction is finalized 
+	 * (all operations completed successfully) to reflect the new state in
+	 * the core.
+	 */
+	default void apply() {
+		// apply the removed state to mutable entities
+		getMutableStore().apply();
+
+		// apply the removed state to children
+		getChildrenStore().apply();
+
+		// apply modified values
+		getValues().values().stream().filter(Value::isModified).forEach(Value::apply);
+	}
+
+	/**
+	 * Returns the mutable {@link EntityStore}. 
+	 * Holds entities with mutable (editable) relations to the entity 
+	 * bound to this core instance.
+	 * This store only contains always only one relation for one entity. 
+	 * For child relations use {@link ChildrenStore}.  
+	 *
+	 * @return The mutable {@code EntityStore} is returned.
+	 */
+	EntityStore getMutableStore();
+
+	/**
+	 * Returns the permanent {@link EntityStore}. 
+	 * Holds entities with immutable (non-editable) relations to the entity 
+	 * bound to this core instance. 
+	 * E.g. relations to the parent entity. 
+	 *
+	 * @return The permanent {@code EntityStore} is returned.
+	 */
+	EntityStore getPermanentStore();
+
+	/**
+	 * Returns the {@link ChildrenStore}. This store holds child
+	 * entities with relations to the entity bound to this core instance. 
+	 * 	 
+	 * @return The {@code ChildrenStore} is returned.
+	 */
+	// TODO (8.11.2017; Florian Schmitt, Angelika Wittek)
+	// Entities with more than one related entity that do not refer to children, have also to go here, 
+	// as it is not permitted to go to the other stores. Does this work at all? 
+	ChildrenStore getChildrenStore();
+
+}
diff --git a/src/main/java/org/eclipse/mdm/api/base/core/EntityStore.java b/src/main/java/org/eclipse/mdm/api/base/core/EntityStore.java
new file mode 100644
index 0000000..74d88a2
--- /dev/null
+++ b/src/main/java/org/eclipse/mdm/api/base/core/EntityStore.java
@@ -0,0 +1,185 @@
+package org.eclipse.mdm.api.base.core;

+

+import java.util.Collection;

+import java.util.Collections;

+import java.util.HashMap;

+import java.util.Map;

+

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

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

+

+/**

+ * Holds related entities of any kind and keeps track of modifications.

+ */

+public final class EntityStore {

+

+	private final Map<String, Entity> current = new HashMap<>(0);

+	private final Map<String, Entity> removed = new HashMap<>(0);

+

+	/**

+	 * Returns current set of related entities.

+	 *

+	 * @return Returned {@code Collection} is unmodifiable.

+	 */

+	public Collection<Entity> getCurrent() {

+		return Collections.unmodifiableCollection(current.values());

+	}

+

+	/**

+	 * Returns current set of removed related entities.

+	 *

+	 * @return Returned {@code Collection} is unmodifiable.

+	 */

+	public Collection<Entity> getRemoved() {

+		return Collections.unmodifiableCollection(removed.values());

+	}

+

+	/**

+	 * Returns related entity identified by given entity class.

+	 *

+	 * @param <T>

+	 *            The desired entity type.

+	 * @param entityClass

+	 *            Used as identifier.

+	 * @return The related entity is returned or null of not defined.

+	 */

+	public <T extends Entity> T get(Class<T> entityClass) {

+		return get(entityClass.getSimpleName(), entityClass);

+	}

+

+	/**

+	 * Returns related entity identified by given entity class.

+	 *

+	 * @param <T>

+	 *            The desired entity type.

+	 * @param relationName

+	 *            The relation name the entity is referenced by.

+	 * @param entityClass

+	 *            Used as identifier.

+	 * @return The related entity is returned or null of not defined.

+	 */

+	public <T extends Entity> T get(String relationName, Class<T> entityClass) {

+		return entityClass.cast(current.get(relationName));

+	}

+

+	/**

+	 * Replaces a related entity with the given one.

+	 *

+	 * @param entity

+	 *            The new related entity.

+	 */

+	public void set(Entity entity) {

+		set(entity.getClass().getSimpleName(), entity);

+	}

+

+	/**

+	 * Replaces a related entity with the given one.

+	 *

+	 * @param name

+	 *            The name of the relation the entity is referenced by.

+	 * @param entity

+	 *            The new related entity.

+	 */

+	public void set(String name, Entity entity) {

+		Entity old = current.put(name, entity);

+		if (old != null) {

+			removed.put(name, old);

+		}

+	}

+

+	/**

+	 * Removes a related entity for given entity class.

+	 *

+	 * @param entityClass

+	 *            Used as identifier.

+	 */

+	public void remove(Class<? extends Entity> entityClass) {

+		String key = entityClass.getSimpleName();

+		remove(key, entityClass);

+	}

+

+	/**

+	 * Removes a related entity for given relation name and entity class.

+	 *

+	 * @param name

+	 *            The name of the relation the entity is referenced by.

+	 * @param entityClass

+	 *            Used as identifier.

+	 */

+	public void remove(String name, Class<? extends Entity> entityClass) {

+		Entity old = current.remove(name);

+		if (old != null) {

+			removed.put(name, old);

+		}

+	}

+

+	/**

+	 * Returns related entity identified by given entity class and

+	 * {@link ContextType}.

+	 *

+	 * @param <T>

+	 *            The desired entity type.

+	 * @param entityClass

+	 *            Used as identifier.

+	 * @param contextType

+	 *            Used as identifier.

+	 * @return The related entity is returned or null of not defined.

+	 */

+	public <T extends Entity> T get(Class<T> entityClass, ContextType contextType) {

+		return entityClass.cast(current.get(createContextTypeKey(entityClass, contextType)));

+	}

+

+	/**

+	 * Replaces a related entity with the given one.

+	 *

+	 * @param entity

+	 *            The new related entity.

+	 * @param contextType

+	 *            Used as identifier.

+	 */

+	public void set(Entity entity, ContextType contextType) {

+		String key = createContextTypeKey(entity.getClass(), contextType);

+		Entity old = current.put(key, entity);

+		if (old != null) {

+			removed.put(key, old);

+		}

+	}

+

+	/**

+	 * Removes a related entity for given entity class and

+	 * {@link ContextType}.

+	 *

+	 * @param entityClass

+	 *            Used as identifier.

+	 * @param contextType

+	 *            Used as identifier.

+	 */

+	public void remove(Class<? extends Entity> entityClass, ContextType contextType) {

+		String key = createContextTypeKey(entityClass, contextType);

+		Entity old = current.remove(key);

+		if (old != null) {

+			removed.put(key, old);

+		}

+	}

+

+	/**

+	 * Clean up list of removed entities.

+	 */

+	void apply() {

+		removed.clear();

+	}

+

+	/**

+	 * Generates a key from given entity class and {@link ContextType}.

+	 *

+	 * @param entityClass

+	 *            Identifier part 1.

+	 * @param contextType

+	 *            Identifier part 2.

+	 * @return A context type dependent key is returned.

+	 */

+	private static String createContextTypeKey(Class<? extends Entity> entityClass, ContextType contextType) {

+		return entityClass.getSimpleName() + '_' + contextType;

+	}

+

+}
\ No newline at end of file
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/BaseEntity.java b/src/main/java/org/eclipse/mdm/api/base/model/BaseEntity.java
index 869be38..10884f2 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/BaseEntity.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/BaseEntity.java
@@ -12,6 +12,8 @@
 import java.util.Map;
 import java.util.stream.Collectors;
 
+import org.eclipse.mdm.api.base.core.Core;
+
 /**
  * This is a base implementation for modeled entities. API consumers should
  * never use this class in any way, instead the most common interface should be
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/BaseEntityFactory.java b/src/main/java/org/eclipse/mdm/api/base/model/BaseEntityFactory.java
index 6d8c36d..bf45157 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/BaseEntityFactory.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/BaseEntityFactory.java
@@ -14,8 +14,9 @@
 import java.util.List;

 import java.util.Optional;

 

-import org.eclipse.mdm.api.base.model.Core.ChildrenStore;

-import org.eclipse.mdm.api.base.model.Core.EntityStore;

+import org.eclipse.mdm.api.base.core.ChildrenStore;

+import org.eclipse.mdm.api.base.core.Core;

+import org.eclipse.mdm.api.base.core.EntityStore;

 

 /**

  * Implementation of an abstract entity factory which creates new entities.

diff --git a/src/main/java/org/eclipse/mdm/api/base/model/BaseParameter.java b/src/main/java/org/eclipse/mdm/api/base/model/BaseParameter.java
index 55c8b81..78b1dc0 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/BaseParameter.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/BaseParameter.java
@@ -14,6 +14,8 @@
 import java.util.Optional;
 import java.util.function.Function;
 
+import org.eclipse.mdm.api.base.core.Core;
+
 /**
  * Implementation of an abstract parameter which holds a value with one of the
  * supported {@link ValueType}s listed below. The value is internally stored in
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/Channel.java b/src/main/java/org/eclipse/mdm/api/base/model/Channel.java
index 15b121c..9f4f8ac 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/Channel.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/Channel.java
@@ -8,6 +8,8 @@
 
 package org.eclipse.mdm.api.base.model;
 
+import org.eclipse.mdm.api.base.core.Core;
+
 /**
  * Implementation of the channel entity type. Entities of this type are based on
  * {@link Quantity}s.
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/ChannelGroup.java b/src/main/java/org/eclipse/mdm/api/base/model/ChannelGroup.java
index fbf5a8e..124d19d 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/ChannelGroup.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/ChannelGroup.java
@@ -8,6 +8,8 @@
 
 package org.eclipse.mdm.api.base.model;
 
+import org.eclipse.mdm.api.base.core.Core;
+
 /**
  * Implementation of the channel group entity type. It belongs to exactly one
  * {@link Measurement} and groups a set of its {@link Channel}s.
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/ContextComponent.java b/src/main/java/org/eclipse/mdm/api/base/model/ContextComponent.java
index cbf8a81..58b6bbb 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/ContextComponent.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/ContextComponent.java
@@ -12,6 +12,8 @@
 import java.util.Optional;

 import java.util.stream.Collectors;

 

+import org.eclipse.mdm.api.base.core.Core;

+

 /**

  * Implementation of the context component entity types. Instances of this class

  * are only provided / managed via the owning descriptive {@link ContextRoot}.

diff --git a/src/main/java/org/eclipse/mdm/api/base/model/ContextRoot.java b/src/main/java/org/eclipse/mdm/api/base/model/ContextRoot.java
index 4c7548f..8bc67f3 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/ContextRoot.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/ContextRoot.java
@@ -15,6 +15,8 @@
 import java.util.Optional;

 import java.util.stream.Collectors;

 

+import org.eclipse.mdm.api.base.core.Core;

+

 /**

  * Implementation of the context root entity types. This is the root node of the

  * descriptive component structure for a {@link ContextType}. This element is

diff --git a/src/main/java/org/eclipse/mdm/api/base/model/ContextSensor.java b/src/main/java/org/eclipse/mdm/api/base/model/ContextSensor.java
index 1f3f909..b633002 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/ContextSensor.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/ContextSensor.java
@@ -8,6 +8,8 @@
 
 package org.eclipse.mdm.api.base.model;
 
+import org.eclipse.mdm.api.base.core.Core;
+
 /**
  * Implementation of the context sensor entity types. Instances of this class
  * are only provided / managed via the owning {@link ContextComponent}. A
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/Core.java b/src/main/java/org/eclipse/mdm/api/base/model/Core.java
deleted file mode 100644
index b0132a3..0000000
--- a/src/main/java/org/eclipse/mdm/api/base/model/Core.java
+++ /dev/null
@@ -1,467 +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.base.model;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
-
-/**
- * Provides access to the internals of any entity:
- *
- * <ul>
- * <li>name of the data source</li>
- * <li>name of the type</li>
- * <li>instance ID</li>
- * <li>values</li>
- * <li>added/removed file links</li>
- * <li>related entities</li>
- * <li>parent/child entities</li>
- * </ul>
- *
- * @since 1.0.0
- * @author Viktor Stoehr, Gigatronik Ingolstadt GmbH
- */
-public interface Core {
-
-	// ======================================================================
-	// Public methods
-	// ======================================================================
-
-	/**
-	 * Returns the name of the data source this entity was retrieved from.
-	 *
-	 * @return Name of the data source.
-	 */
-	String getSourceName();
-
-	/**
-	 * Returns the name of the entity type.
-	 *
-	 * @return Name of the entity type is returned.
-	 */
-	String getTypeName();
-
-	/**
-	 * Returns the instance ID or {@code 0} if this instance is not yet
-	 * persisted.
-	 *
-	 * @return The instance ID is returned.
-	 */
-	String getID();
-
-	/**
-	 * Sets an instance ID.
-	 *
-	 * @param instanceID
-	 *            The new instance ID.
-	 */
-	void setID(String instanceID);
-
-	/**
-	 * Returns <i>all</i> {@link Value} containers of this entity.
-	 *
-	 * @return Values mapped by their name are returned.
-	 */
-	Map<String, Value> getValues();
-
-	/**
-	 * Hides {@link Value} containers whose name is contained in the given names
-	 * {@code Collection}.
-	 * E.g. hide attributes from a CatalogComponent when not used in a TemplateComponent.  
-	 *
-	 * @param names
-	 *            Names of the {@code Value} which shall be hidden.
-	 */
-	void hideValues(Collection<String> names);
-
-	/**
-	 * Returns <i>all</i> {@link Value} containers, including the hidden ones.
-	 *
-	 * @return All {@code Value} containers are returned.
-	 */
-	Map<String, Value> getAllValues();
-
-	/**
-	 * Returns all newly added {@link FileLink}.
-	 *
-	 * @return New {@code FileLink}s are returned.
-	 */
-	default List<FileLink> getAddedFileLinks() {
-		Predicate<FileLink> isRemote = FileLink::isRemote;
-
-		List<FileLink> fileLinks = getValues().values().stream().filter(v -> v.getValueType().isFileLink())
-				.filter(Value::isValid).map(v -> (FileLink) v.extract()).filter(isRemote.negate())
-				.collect(Collectors.toList());
-
-		List<Value> values = getValues().values().stream().filter(v -> v.getValueType().isFileLinkSequence())
-				.filter(Value::isValid).collect(Collectors.toList());
-
-		for (Value value : values) {
-			Arrays.stream((FileLink[]) value.extract()).filter(isRemote.negate()).forEach(fileLinks::add);
-		}
-
-		return fileLinks;
-	}
-
-	/**
-	 * Returns all removed {@link FileLink}s.
-	 *
-	 * @return Removed {@code FileLink}s are returned.
-	 */
-	default List<FileLink> getRemovedFileLinks() {
-		Predicate<FileLink> isRemote = FileLink::isRemote;
-
-		List<FileLink> fileLinks = getValues().values().stream().filter(v -> v.getValueType().isFileLink())
-				.filter(Value::isModified).map(v -> (FileLink) v.extractInitial()).filter(Objects::nonNull)
-				.filter(isRemote).collect(Collectors.toList());
-
-		List<Value> values = getValues().values().stream().filter(v -> v.getValueType().isFileLinkSequence())
-				.filter(Value::wasValid).filter(Value::isModified).collect(Collectors.toList());
-
-		for (Value value : values) {
-			List<FileLink> current = Arrays.asList((FileLink[]) value.extract());
-			Arrays.stream((FileLink[]) value.extractInitial()).filter(fl -> !current.contains(fl))
-					.forEach(fileLinks::add);
-		}
-
-		return fileLinks;
-	}
-
-	/**
-	 * Applies modifications made to the entity stores and {@link Value}
-	 * containers. This method is called when a transaction is finalized 
-	 * (all operations completed successfully) to reflect the new state in
-	 * the core.
-	 */
-	default void apply() {
-		// apply the removed state to mutable entities
-		getMutableStore().apply();
-
-		// apply the removed state to children
-		getChildrenStore().apply();
-
-		// apply modified values
-		getValues().values().stream().filter(Value::isModified).forEach(Value::apply);
-	}
-
-	/**
-	 * Returns the mutable {@link EntityStore}. 
-	 * Holds entities with mutable (editable) relations to the entity 
-	 * bound to this core instance.
-	 * This store only contains always only one relation for one entity. 
-	 * For child relations use {@link ChildrenStore}.  
-	 *
-	 * @return The mutable {@code EntityStore} is returned.
-	 */
-	EntityStore getMutableStore();
-
-	/**
-	 * Returns the permanent {@link EntityStore}. 
-	 * Holds entities with immutable (non-editable) relations to the entity 
-	 * bound to this core instance. 
-	 * E.g. relations to the parent entity. 
-	 *
-	 * @return The permanent {@code EntityStore} is returned.
-	 */
-	EntityStore getPermanentStore();
-
-	/**
-	 * Returns the {@link ChildrenStore}. This store holds child
-	 * entities with relations to the entity bound to this core instance. 
-	 * 	 
-	 * @return The {@code ChildrenStore} is returned.
-	 */
-	// TODO (8.11.2017; Florian Schmitt, Angelika Wittek)
-	// Entities with more than one related entity that do not refer to children, have also to go here, 
-	// as it is not permitted to go to the other stores. Does this work at all? 
-	ChildrenStore getChildrenStore();
-
-	// ======================================================================
-	// Inner classes
-	// ======================================================================
-
-	/**
-	 * Holds related entities of any kind and keeps track of modifications.
-	 */
-	public static final class EntityStore {
-
-		private final Map<String, Entity> current = new HashMap<>(0);
-		private final Map<String, Entity> removed = new HashMap<>(0);
-
-		/**
-		 * Returns current set of related entities.
-		 *
-		 * @return Returned {@code Collection} is unmodifiable.
-		 */
-		public Collection<Entity> getCurrent() {
-			return Collections.unmodifiableCollection(current.values());
-		}
-
-		/**
-		 * Returns current set of removed related entities.
-		 *
-		 * @return Returned {@code Collection} is unmodifiable.
-		 */
-		public Collection<Entity> getRemoved() {
-			return Collections.unmodifiableCollection(removed.values());
-		}
-
-		/**
-		 * Returns related entity identified by given entity class.
-		 *
-		 * @param <T>
-		 *            The desired entity type.
-		 * @param entityClass
-		 *            Used as identifier.
-		 * @return The related entity is returned or null of not defined.
-		 */
-		public <T extends Entity> T get(Class<T> entityClass) {
-			return get(entityClass.getSimpleName(), entityClass);
-		}
-
-		/**
-		 * Returns related entity identified by given entity class.
-		 *
-		 * @param <T>
-		 *            The desired entity type.
-		 * @param relationName
-		 *            The relation name the entity is referenced by.
-		 * @param entityClass
-		 *            Used as identifier.
-		 * @return The related entity is returned or null of not defined.
-		 */
-		public <T extends Entity> T get(String relationName, Class<T> entityClass) {
-			return entityClass.cast(current.get(relationName));
-		}
-
-		/**
-		 * Replaces a related entity with the given one.
-		 *
-		 * @param entity
-		 *            The new related entity.
-		 */
-		public void set(Entity entity) {
-			set(entity.getClass().getSimpleName(), entity);
-		}
-
-		/**
-		 * Replaces a related entity with the given one.
-		 *
-		 * @param name
-		 *            The name of the relation the entity is referenced by.
-		 * @param entity
-		 *            The new related entity.
-		 */
-		public void set(String name, Entity entity) {
-			Entity old = current.put(name, entity);
-			if (old != null) {
-				removed.put(name, old);
-			}
-		}
-
-		/**
-		 * Removes a related entity for given entity class.
-		 *
-		 * @param entityClass
-		 *            Used as identifier.
-		 */
-		public void remove(Class<? extends Entity> entityClass) {
-			String key = entityClass.getSimpleName();
-			remove(key, entityClass);
-		}
-
-		/**
-		 * Removes a related entity for given relation name and entity class.
-		 *
-		 * @param name
-		 *            The name of the relation the entity is referenced by.
-		 * @param entityClass
-		 *            Used as identifier.
-		 */
-		public void remove(String name, Class<? extends Entity> entityClass) {
-			Entity old = current.remove(name);
-			if (old != null) {
-				removed.put(name, old);
-			}
-		}
-
-		/**
-		 * Returns related entity identified by given entity class and
-		 * {@link ContextType}.
-		 *
-		 * @param <T>
-		 *            The desired entity type.
-		 * @param entityClass
-		 *            Used as identifier.
-		 * @param contextType
-		 *            Used as identifier.
-		 * @return The related entity is returned or null of not defined.
-		 */
-		public <T extends Entity> T get(Class<T> entityClass, ContextType contextType) {
-			return entityClass.cast(current.get(createContextTypeKey(entityClass, contextType)));
-		}
-
-		/**
-		 * Replaces a related entity with the given one.
-		 *
-		 * @param entity
-		 *            The new related entity.
-		 * @param contextType
-		 *            Used as identifier.
-		 */
-		public void set(Entity entity, ContextType contextType) {
-			String key = createContextTypeKey(entity.getClass(), contextType);
-			Entity old = current.put(key, entity);
-			if (old != null) {
-				removed.put(key, old);
-			}
-		}
-
-		/**
-		 * Removes a related entity for given entity class and
-		 * {@link ContextType}.
-		 *
-		 * @param entityClass
-		 *            Used as identifier.
-		 * @param contextType
-		 *            Used as identifier.
-		 */
-		public void remove(Class<? extends Entity> entityClass, ContextType contextType) {
-			String key = createContextTypeKey(entityClass, contextType);
-			Entity old = current.remove(key);
-			if (old != null) {
-				removed.put(key, old);
-			}
-		}
-
-		/**
-		 * Clean up list of removed entities.
-		 */
-		private void apply() {
-			removed.clear();
-		}
-
-		/**
-		 * Generates a key from given entity class and {@link ContextType}.
-		 *
-		 * @param entityClass
-		 *            Identifier part 1.
-		 * @param contextType
-		 *            Identifier part 2.
-		 * @return A context type dependent key is returned.
-		 */
-		private static String createContextTypeKey(Class<? extends Entity> entityClass, ContextType contextType) {
-			return entityClass.getSimpleName() + '_' + contextType;
-		}
-
-	}
-
-	/**
-	 * Holds related entities of any kind and keeps track of modifications.
-	 */
-	public static final class ChildrenStore {
-
-		private final Map<Class<? extends Deletable>, List<? extends Deletable>> current = new HashMap<>(0);
-		private final Map<Class<? extends Deletable>, List<? extends Deletable>> removed = new HashMap<>(0);
-
-		/**
-		 * Returns current set of related children mapped by their type.
-		 *
-		 * @return Returned {@code Map} is unmodifiable.
-		 */
-		public Map<Class<? extends Deletable>, List<? extends Deletable>> getCurrent() {
-			return Collections.unmodifiableMap(current);
-		}
-
-		/**
-		 * Returns current set of removed related children mapped by their type.
-		 *
-		 * @return Returned {@code Map} is unmodifiable.
-		 */
-		public Map<Class<? extends Deletable>, List<? extends Deletable>> getRemoved() {
-			return Collections.unmodifiableMap(removed);
-		}
-
-		/**
-		 * Returns related child entities of given type.
-		 *
-		 * @param <T>
-		 *            Desired entity type.
-		 * @param entityClass
-		 *            Used as identifier.
-		 * @return Returned {@code List} is unmodifiable.
-		 */
-		@SuppressWarnings("unchecked")
-		public <T extends Deletable> List<T> get(Class<T> entityClass) {
-			return Collections.unmodifiableList((List<T>) current.computeIfAbsent(entityClass, k -> new ArrayList<>()));
-		}
-
-		/**
-		 * Sorts the child entities with given {@code Comparator}.
-		 *
-		 * @param <T>
-		 *            Desired entity type.
-		 * @param entityClass
-		 *            Used as identifier.
-		 * @param comparator
-		 *            Used for sorting.
-		 */
-		@SuppressWarnings("unchecked")
-		public <T extends Deletable> void sort(Class<T> entityClass, Comparator<? super T> comparator) {
-			List<T> children = (List<T>) current.get(entityClass);
-			if (children != null) {
-				children.sort(comparator);
-			}
-		}
-
-		/**
-		 * Adds given child entity.
-		 *
-		 * @param child
-		 *            The new child.
-		 */
-		@SuppressWarnings("unchecked")
-		public void add(Deletable child) {
-			removed.getOrDefault(child.getClass(), new ArrayList<>()).remove(child);
-			((List<Deletable>) current.computeIfAbsent(child.getClass(), k -> new ArrayList<>())).add(child);
-		}
-
-		/**
-		 * Removes given child entity.
-		 *
-		 * @param child
-		 *            The child which will be removed.
-		 */
-		@SuppressWarnings("unchecked")
-		public void remove(Deletable child) {
-			List<Deletable> children = (List<Deletable>) current.getOrDefault(child.getClass(), new ArrayList<>());
-			if (children.remove(child) && child.getID() != null && child.getID().length() > 0) {
-				((List<Deletable>) removed.computeIfAbsent(child.getClass(), k -> new ArrayList<>())).add(child);
-			}
-		}
-
-		/**
-		 * Clean up list of removed entities.
-		 */
-		private void apply() {
-			removed.clear();
-		}
-
-	}
-
-}
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/Environment.java b/src/main/java/org/eclipse/mdm/api/base/model/Environment.java
index 8220e4e..0d733f5 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/Environment.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/Environment.java
@@ -8,6 +8,8 @@
 
 package org.eclipse.mdm.api.base.model;
 
+import org.eclipse.mdm.api.base.core.Core;
+
 /**
  * Implementation of the environment entity type. The {@link Environment} is a
  * singleton within a connected data source.
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/Measurement.java b/src/main/java/org/eclipse/mdm/api/base/model/Measurement.java
index 7e4d332..685cb7a 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/Measurement.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/Measurement.java
@@ -13,6 +13,7 @@
 import java.util.Map;
 
 import org.eclipse.mdm.api.base.BaseEntityManager;
+import org.eclipse.mdm.api.base.core.Core;
 import org.eclipse.mdm.api.base.query.DataAccessException;
 
 /**
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/Parameter.java b/src/main/java/org/eclipse/mdm/api/base/model/Parameter.java
index 3845655..5e8038f 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/Parameter.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/Parameter.java
@@ -10,6 +10,8 @@
 
 import java.time.LocalDateTime;
 
+import org.eclipse.mdm.api.base.core.Core;
+
 /**
  * Implementation of the parameter entity type. Instances of this class hold a
  * value in its {@code String} representation, which is converted upon request
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/ParameterSet.java b/src/main/java/org/eclipse/mdm/api/base/model/ParameterSet.java
index 178891d..fae8a2f 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/ParameterSet.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/ParameterSet.java
@@ -12,6 +12,8 @@
 import java.util.Optional;

 import java.util.stream.Collectors;

 

+import org.eclipse.mdm.api.base.core.Core;

+

 /**

  * Implementation of the parameter set entity type. Instances of this class

  * group a set of further describing data stored in {@link Parameter}s.

diff --git a/src/main/java/org/eclipse/mdm/api/base/model/PhysicalDimension.java b/src/main/java/org/eclipse/mdm/api/base/model/PhysicalDimension.java
index c0068b3..aba5b12 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/PhysicalDimension.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/PhysicalDimension.java
@@ -8,6 +8,8 @@
 
 package org.eclipse.mdm.api.base.model;
 
+import org.eclipse.mdm.api.base.core.Core;
+
 /**
  * Implementation of the physical dimension entity type. Each {@link Unit} must
  * have a relation to an instance of this type. The attributes represent the
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/Quantity.java b/src/main/java/org/eclipse/mdm/api/base/model/Quantity.java
index 4ed5d6e..1a1acd7 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/Quantity.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/Quantity.java
@@ -8,6 +8,8 @@
 
 package org.eclipse.mdm.api.base.model;
 
+import org.eclipse.mdm.api.base.core.Core;
+
 /**
  * Implementation of the quantity entity type. {@link Channel}s are based on
  * entities of this type. Each quantity has a relation to a default
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/Test.java b/src/main/java/org/eclipse/mdm/api/base/model/Test.java
index 828a88c..21c1669 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/Test.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/Test.java
@@ -11,6 +11,8 @@
 import java.util.List;
 import java.util.Optional;
 
+import org.eclipse.mdm.api.base.core.Core;
+
 /**
  * Implementation of the test entity type. The test groups a number of single
  * {@link TestStep}s. A measurement order always corresponds with exactly one
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/TestStep.java b/src/main/java/org/eclipse/mdm/api/base/model/TestStep.java
index 126215d..6e542b3 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/TestStep.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/TestStep.java
@@ -12,6 +12,7 @@
 import java.util.Map;
 
 import org.eclipse.mdm.api.base.BaseEntityManager;
+import org.eclipse.mdm.api.base.core.Core;
 import org.eclipse.mdm.api.base.query.DataAccessException;
 
 /**
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/Unit.java b/src/main/java/org/eclipse/mdm/api/base/model/Unit.java
index 1c6b49f..6c3bbfc 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/Unit.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/Unit.java
@@ -8,6 +8,8 @@
 
 package org.eclipse.mdm.api.base.model;
 
+import org.eclipse.mdm.api.base.core.Core;
+
 /**
  * Implementation of the unit entity type. Units referring to the same
  * {@link PhysicalDimension} can be converted to each other by means of their
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/User.java b/src/main/java/org/eclipse/mdm/api/base/model/User.java
index 86cae4d..f7d745d 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/User.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/User.java
@@ -8,6 +8,8 @@
 
 package org.eclipse.mdm.api.base.model;
 
+import org.eclipse.mdm.api.base.core.Core;
+
 /**
  * Implementation of the user entity type.
  *
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/Value.java b/src/main/java/org/eclipse/mdm/api/base/model/Value.java
index 2415137..87abf10 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/Value.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/Value.java
@@ -319,10 +319,6 @@
 		return sb.toString();
 	}
 
-	// ======================================================================
-	// Package methods
-	// ======================================================================
-
 	/**
 	 * Checks whether either the validity flag or the value have been modified
 	 * since initialization.
@@ -330,7 +326,7 @@
 	 * @return Returns {@code true} either if the flag or the value has been
 	 *         modified.
 	 */
-	boolean isModified() {
+	public boolean isModified() {
 		return wasValid() != isValid() || !Objects.deepEquals(extractInitial(), extract());
 	}
 
@@ -339,7 +335,7 @@
 	 *
 	 * @return Returns {@code true} if the value was initially marked as valid.
 	 */
-	boolean wasValid() {
+	public boolean wasValid() {
 		return initialValid;
 	}
 
@@ -348,17 +344,21 @@
 	 *
 	 * @return The initial value is returned.
 	 */
-	Object extractInitial() {
+	public Object extractInitial() {
 		return initialValue;
 	}
 
 	/**
 	 * Overwrites the initial validity flag and value with the current ones.
 	 */
-	void apply() {
+	public void apply() {
 		initialValid = isValid();
 		initialValue = copy(extract());
 	}
+	
+	// ======================================================================
+	// Package methods
+	// ======================================================================
 
 	/**
 	 * Returns the {@code String} value from given array at given position.
diff --git a/src/test/java/org/eclipse/mdm/api/base/CoreImpl.java b/src/test/java/org/eclipse/mdm/api/base/CoreImpl.java
index 19bbb5c..3e02c11 100755
--- a/src/test/java/org/eclipse/mdm/api/base/CoreImpl.java
+++ b/src/test/java/org/eclipse/mdm/api/base/CoreImpl.java
@@ -11,7 +11,9 @@
 import java.util.Collection;

 import java.util.Map;

 

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

+import org.eclipse.mdm.api.base.core.ChildrenStore;

+import org.eclipse.mdm.api.base.core.Core;

+import org.eclipse.mdm.api.base.core.EntityStore;

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

 

 /**

diff --git a/src/test/java/org/eclipse/mdm/api/base/EntityFactoryImpl.java b/src/test/java/org/eclipse/mdm/api/base/EntityFactoryImpl.java
index 798dfaf..b5b80e4 100755
--- a/src/test/java/org/eclipse/mdm/api/base/EntityFactoryImpl.java
+++ b/src/test/java/org/eclipse/mdm/api/base/EntityFactoryImpl.java
@@ -10,9 +10,9 @@
 

 import java.util.Optional;

 

+import org.eclipse.mdm.api.base.core.Core;

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

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

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

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

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

 

diff --git a/src/test/java/org/eclipse/mdm/api/base/model/ModelTest.java b/src/test/java/org/eclipse/mdm/api/base/model/ModelTest.java
index f8e49a3..1394507 100755
--- a/src/test/java/org/eclipse/mdm/api/base/model/ModelTest.java
+++ b/src/test/java/org/eclipse/mdm/api/base/model/ModelTest.java
@@ -18,6 +18,7 @@
 
 import org.eclipse.mdm.api.base.CoreImpl;
 import org.eclipse.mdm.api.base.EntityFactoryImpl;
+import org.eclipse.mdm.api.base.core.Core;
 import org.eclipse.mdm.api.base.massdata.UnitBuilder;
 import org.eclipse.mdm.api.base.massdata.WriteRequest;
 import org.eclipse.mdm.api.base.massdata.WriteRequestBuilder;