"561698 -  Merge 'org.eclipse.mdm.api.default/mkoller/contrib' into 'mkoller/contrib'"

Signed-off-by: Simon Skoczylas <simon.skoczylas@karakun.com>
diff --git a/org.eclipse.mdm.api.default/.gitignore b/org.eclipse.mdm.api.default/.gitignore
new file mode 100644
index 0000000..49678ad
--- /dev/null
+++ b/org.eclipse.mdm.api.default/.gitignore
@@ -0,0 +1,17 @@
+# eclipse
+.classpath
+.project
+.settings/
+bin/
+
+# gradle
+.gradle
+build/
+
+# intellij
+.idea/
+out/
+*.ipr
+*.iml
+*.iws
+/bin/
diff --git a/org.eclipse.mdm.api.default/LICENSE.txt b/org.eclipse.mdm.api.default/LICENSE.txt
new file mode 100644
index 0000000..e48e096
--- /dev/null
+++ b/org.eclipse.mdm.api.default/LICENSE.txt
@@ -0,0 +1,277 @@
+Eclipse Public License - v 2.0
+
+    THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE
+    PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION
+    OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
+
+1. DEFINITIONS
+
+"Contribution" means:
+
+  a) in the case of the initial Contributor, the initial content
+     Distributed under this Agreement, and
+
+  b) in the case of each subsequent Contributor:
+     i) changes to the Program, and
+     ii) additions to the Program;
+  where such changes and/or additions to the Program originate from
+  and are Distributed by that particular Contributor. A Contribution
+  "originates" from a Contributor if it was added to the Program by
+  such Contributor itself or anyone acting on such Contributor's behalf.
+  Contributions do not include changes or additions to the Program that
+  are not Modified Works.
+
+"Contributor" means any person or entity that Distributes the Program.
+
+"Licensed Patents" mean patent claims licensable by a Contributor which
+are necessarily infringed by the use or sale of its Contribution alone
+or when combined with the Program.
+
+"Program" means the Contributions Distributed in accordance with this
+Agreement.
+
+"Recipient" means anyone who receives the Program under this Agreement
+or any Secondary License (as applicable), including Contributors.
+
+"Derivative Works" shall mean any work, whether in Source Code or other
+form, that is based on (or derived from) the Program and for which the
+editorial revisions, annotations, elaborations, or other modifications
+represent, as a whole, an original work of authorship.
+
+"Modified Works" shall mean any work in Source Code or other form that
+results from an addition to, deletion from, or modification of the
+contents of the Program, including, for purposes of clarity any new file
+in Source Code form that contains any contents of the Program. Modified
+Works shall not include works that contain only declarations,
+interfaces, types, classes, structures, or files of the Program solely
+in each case in order to link to, bind by name, or subclass the Program
+or Modified Works thereof.
+
+"Distribute" means the acts of a) distributing or b) making available
+in any manner that enables the transfer of a copy.
+
+"Source Code" means the form of a Program preferred for making
+modifications, including but not limited to software source code,
+documentation source, and configuration files.
+
+"Secondary License" means either the GNU General Public License,
+Version 2.0, or any later versions of that license, including any
+exceptions or additional permissions as identified by the initial
+Contributor.
+
+2. GRANT OF RIGHTS
+
+  a) Subject to the terms of this Agreement, each Contributor hereby
+  grants Recipient a non-exclusive, worldwide, royalty-free copyright
+  license to reproduce, prepare Derivative Works of, publicly display,
+  publicly perform, Distribute and sublicense the Contribution of such
+  Contributor, if any, and such Derivative Works.
+
+  b) Subject to the terms of this Agreement, each Contributor hereby
+  grants Recipient a non-exclusive, worldwide, royalty-free patent
+  license under Licensed Patents to make, use, sell, offer to sell,
+  import and otherwise transfer the Contribution of such Contributor,
+  if any, in Source Code or other form. This patent license shall
+  apply to the combination of the Contribution and the Program if, at
+  the time the Contribution is added by the Contributor, such addition
+  of the Contribution causes such combination to be covered by the
+  Licensed Patents. The patent license shall not apply to any other
+  combinations which include the Contribution. No hardware per se is
+  licensed hereunder.
+
+  c) Recipient understands that although each Contributor grants the
+  licenses to its Contributions set forth herein, no assurances are
+  provided by any Contributor that the Program does not infringe the
+  patent or other intellectual property rights of any other entity.
+  Each Contributor disclaims any liability to Recipient for claims
+  brought by any other entity based on infringement of intellectual
+  property rights or otherwise. As a condition to exercising the
+  rights and licenses granted hereunder, each Recipient hereby
+  assumes sole responsibility to secure any other intellectual
+  property rights needed, if any. For example, if a third party
+  patent license is required to allow Recipient to Distribute the
+  Program, it is Recipient's responsibility to acquire that license
+  before distributing the Program.
+
+  d) Each Contributor represents that to its knowledge it has
+  sufficient copyright rights in its Contribution, if any, to grant
+  the copyright license set forth in this Agreement.
+
+  e) Notwithstanding the terms of any Secondary License, no
+  Contributor makes additional grants to any Recipient (other than
+  those set forth in this Agreement) as a result of such Recipient's
+  receipt of the Program under the terms of a Secondary License
+  (if permitted under the terms of Section 3).
+
+3. REQUIREMENTS
+
+3.1 If a Contributor Distributes the Program in any form, then:
+
+  a) the Program must also be made available as Source Code, in
+  accordance with section 3.2, and the Contributor must accompany
+  the Program with a statement that the Source Code for the Program
+  is available under this Agreement, and informs Recipients how to
+  obtain it in a reasonable manner on or through a medium customarily
+  used for software exchange; and
+
+  b) the Contributor may Distribute the Program under a license
+  different than this Agreement, provided that such license:
+     i) effectively disclaims on behalf of all other Contributors all
+     warranties and conditions, express and implied, including
+     warranties or conditions of title and non-infringement, and
+     implied warranties or conditions of merchantability and fitness
+     for a particular purpose;
+
+     ii) effectively excludes on behalf of all other Contributors all
+     liability for damages, including direct, indirect, special,
+     incidental and consequential damages, such as lost profits;
+
+     iii) does not attempt to limit or alter the recipients' rights
+     in the Source Code under section 3.2; and
+
+     iv) requires any subsequent distribution of the Program by any
+     party to be under a license that satisfies the requirements
+     of this section 3.
+
+3.2 When the Program is Distributed as Source Code:
+
+  a) it must be made available under this Agreement, or if the
+  Program (i) is combined with other material in a separate file or
+  files made available under a Secondary License, and (ii) the initial
+  Contributor attached to the Source Code the notice described in
+  Exhibit A of this Agreement, then the Program may be made available
+  under the terms of such Secondary Licenses, and
+
+  b) a copy of this Agreement must be included with each copy of
+  the Program.
+
+3.3 Contributors may not remove or alter any copyright, patent,
+trademark, attribution notices, disclaimers of warranty, or limitations
+of liability ("notices") contained within the Program from any copy of
+the Program which they Distribute, provided that Contributors may add
+their own appropriate notices.
+
+4. COMMERCIAL DISTRIBUTION
+
+Commercial distributors of software may accept certain responsibilities
+with respect to end users, business partners and the like. While this
+license is intended to facilitate the commercial use of the Program,
+the Contributor who includes the Program in a commercial product
+offering should do so in a manner which does not create potential
+liability for other Contributors. Therefore, if a Contributor includes
+the Program in a commercial product offering, such Contributor
+("Commercial Contributor") hereby agrees to defend and indemnify every
+other Contributor ("Indemnified Contributor") against any losses,
+damages and costs (collectively "Losses") arising from claims, lawsuits
+and other legal actions brought by a third party against the Indemnified
+Contributor to the extent caused by the acts or omissions of such
+Commercial Contributor in connection with its distribution of the Program
+in a commercial product offering. The obligations in this section do not
+apply to any claims or Losses relating to any actual or alleged
+intellectual property infringement. In order to qualify, an Indemnified
+Contributor must: a) promptly notify the Commercial Contributor in
+writing of such claim, and b) allow the Commercial Contributor to control,
+and cooperate with the Commercial Contributor in, the defense and any
+related settlement negotiations. The Indemnified Contributor may
+participate in any such claim at its own expense.
+
+For example, a Contributor might include the Program in a commercial
+product offering, Product X. That Contributor is then a Commercial
+Contributor. If that Commercial Contributor then makes performance
+claims, or offers warranties related to Product X, those performance
+claims and warranties are such Commercial Contributor's responsibility
+alone. Under this section, the Commercial Contributor would have to
+defend claims against the other Contributors related to those performance
+claims and warranties, and if a court requires any other Contributor to
+pay any damages as a result, the Commercial Contributor must pay
+those damages.
+
+5. NO WARRANTY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT
+PERMITTED BY APPLICABLE LAW, THE PROGRAM IS PROVIDED ON AN "AS IS"
+BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR
+IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF
+TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR
+PURPOSE. Each Recipient is solely responsible for determining the
+appropriateness of using and distributing the Program and assumes all
+risks associated with its exercise of rights under this Agreement,
+including but not limited to the risks and costs of program errors,
+compliance with applicable laws, damage to or loss of data, programs
+or equipment, and unavailability or interruption of operations.
+
+6. DISCLAIMER OF LIABILITY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT
+PERMITTED BY APPLICABLE LAW, NEITHER RECIPIENT NOR ANY CONTRIBUTORS
+SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST
+PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE
+EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+7. GENERAL
+
+If any provision of this Agreement is invalid or unenforceable under
+applicable law, it shall not affect the validity or enforceability of
+the remainder of the terms of this Agreement, and without further
+action by the parties hereto, such provision shall be reformed to the
+minimum extent necessary to make such provision valid and enforceable.
+
+If Recipient institutes patent litigation against any entity
+(including a cross-claim or counterclaim in a lawsuit) alleging that the
+Program itself (excluding combinations of the Program with other software
+or hardware) infringes such Recipient's patent(s), then such Recipient's
+rights granted under Section 2(b) shall terminate as of the date such
+litigation is filed.
+
+All Recipient's rights under this Agreement shall terminate if it
+fails to comply with any of the material terms or conditions of this
+Agreement and does not cure such failure in a reasonable period of
+time after becoming aware of such noncompliance. If all Recipient's
+rights under this Agreement terminate, Recipient agrees to cease use
+and distribution of the Program as soon as reasonably practicable.
+However, Recipient's obligations under this Agreement and any licenses
+granted by Recipient relating to the Program shall continue and survive.
+
+Everyone is permitted to copy and distribute copies of this Agreement,
+but in order to avoid inconsistency the Agreement is copyrighted and
+may only be modified in the following manner. The Agreement Steward
+reserves the right to publish new versions (including revisions) of
+this Agreement from time to time. No one other than the Agreement
+Steward has the right to modify this Agreement. The Eclipse Foundation
+is the initial Agreement Steward. The Eclipse Foundation may assign the
+responsibility to serve as the Agreement Steward to a suitable separate
+entity. Each new version of the Agreement will be given a distinguishing
+version number. The Program (including Contributions) may always be
+Distributed subject to the version of the Agreement under which it was
+received. In addition, after a new version of the Agreement is published,
+Contributor may elect to Distribute the Program (including its
+Contributions) under the new version.
+
+Except as expressly stated in Sections 2(a) and 2(b) above, Recipient
+receives no rights or licenses to the intellectual property of any
+Contributor under this Agreement, whether expressly, by implication,
+estoppel or otherwise. All rights in the Program not expressly granted
+under this Agreement are reserved. Nothing in this Agreement is intended
+to be enforceable by any entity that is not a Contributor or Recipient.
+No third-party beneficiary rights are created under this Agreement.
+
+Exhibit A - Form of Secondary Licenses Notice
+
+"This Source Code may also be made available under the following
+Secondary Licenses when the conditions for such availability set forth
+in the Eclipse Public License, v. 2.0 are satisfied: {name license(s),
+version(s), and exceptions or additional permissions here}."
+
+  Simply including a copy of this Agreement, including this Exhibit A
+  is not sufficient to license the Source Code under Secondary Licenses.
+
+  If it is not possible or desirable to put the notice in a particular
+  file, then You may include the notice in a location (such as a LICENSE
+  file in a relevant directory) where a recipient would be likely to
+  look for such a notice.
+
+  You may add additional accurate notices of copyright ownership.
diff --git a/org.eclipse.mdm.api.default/NOTICE.txt b/org.eclipse.mdm.api.default/NOTICE.txt
new file mode 100644
index 0000000..56281c6
--- /dev/null
+++ b/org.eclipse.mdm.api.default/NOTICE.txt
@@ -0,0 +1,382 @@
+# Notices for Eclipse MDM|BL
+
+This content is produced and maintained by the Eclipse MDM|BL project,
+it is a project of the openMDM(R) Eclipse Working Group.
+
+* Project home: https://projects.eclipse.org/projects/technology.mdmbl
+
+## Trademarks
+
+Eclipse MDM|BL, MDM|BL and Eclipse openMDM(R) logo are registered trademarks
+of the Eclipse Foundation.
+
+## Copyright
+
+All content is the property of the following respective authors or their employers.
+For more information regarding authorship of content, please consult the listed
+source code repository logs.
+
+Copyright (c) 2016-2019 Gigatronik Ingolstadt GmbH
+Copyright (c) 2016-2020 Peak Solution GmbH
+Copyright (c) 2017-2018 science + computing AG Tuebingen (ATOS SE)
+Copyright (c) 2017-2018 Canoo Engineering AG
+Copyright (c) 2017 Florian Schmitt
+Copyright (c) 2017-2020 Angelika Wittek
+Copyright (c) 2018-2019 Elektronische Fahrwerksysteme GMBH
+Copyright (c) 2018-2020 Karakun AG
+Copyright (c) 2018-2020 Alexander Nehmer
+
+## Declared Project Licenses
+
+This program and the accompanying materials are made available under the
+terms of the Eclipse Public License v. 2.0 which is available at
+http://www.eclipse.org/legal/epl-2.0.
+
+SPDX-License-Identifier: EPL-2.0
+
+## Source Code
+
+The project maintains the following source code repositories:
+
+org.eclipse.mdm.api.base.git	    - The openMDM(R) API.
+org.eclipse.mdm.api.default.git	    - Extension of the openMDM(R) API containing default elements.
+org.eclipse.mdm.api.odsadapter.git	- ODS implementation of persistence adapter.
+org.eclipse.mdm.nucleus.git	        - Core building blocks for the openMDM Business Logic and Web Frontend.
+
+## Third-party Content
+
+The Content includes items that have been sourced from third parties as set out below.
+If you did not receive this Content directly from the Eclipse Foundation, the following
+is provided for informational purposes only, and you should look to
+the Redistributor's license for terms and conditions of use.
+
+antlr4-4.5.3.jar(2.5.3)
+    * License: New BSD license
+
+aopalliance-repackaged-2.5.0-b05.jar (2.5.0-b05)
+    * License: CDDL
+
+commons-codec-1.2.jar (1.2)
+    * License: Apache License, 2.0
+
+commons-httpclient-3.1.jar  (3.1)
+    * License: Apache License, 2.0
+
+commons-lang3-3.8.1.jar (3.8.1)
+    * License: Apache License, 2.0
+
+commons-text-1.6.jar (1.6)
+    * License: Apache License, 2.0
+
+gson-2.7.jar (2.7)
+    * License: Apache License, 2.0
+
+Google Guava Version: 25.0-jre  (25.0)
+    * License: Apache License, 2.0
+
+Gradle Wrapper (4.10.2)
+    * License: Apache License, 2.0
+
+hk2-api-2.5.0-b05.jar (2.5.0-b05)
+    * License: CDDL-1.1
+
+hk2-locator-2.5.0-b05.jar(2.5.0-b05)
+    * License: CDDL
+
+hk2-utils-2.5.0-b05.jar (2.5.0-b05)
+    * License: CDDL
+
+jackson-annotations-2.9.0.jar  (2.9.0)
+    * License: Apache License, 2.0
+
+jackson-core-2.9.2.jar(2.9.2)
+    * License: Apache License, 2.0
+
+jackson-databind-2.9.2.jar  (2.9.2)
+    * License: Apache License, 2.0
+
+jackson-jaxrs-base-2.9.2.jar(2.9.2)
+    * License: Apache License, 2.0
+
+jackson-jaxrs-json-provider-2.9.2.jar(2.9.2)
+    * License: Apache License, 2.0
+
+jackson-module-jaxb-annotations-2.9.2.jar  (2.9.2)
+    * License: Apache License, 2.0
+
+javassist-3.20.0-GA.jar  (2.20.0-GA)
+    * License: Apache 2.0
+
+jcl-over-slf4j-1.7.25.jar(1.7.25)
+    * License: MIT License
+    * Licence Path: https://www.slf4j.org/license.html
+    * Project URL:  https://www.slf4j.org
+    * Source URL:   https://github.com/qos-ch/slf4j
+
+jersey-client-2.23.2.jar (2.23.2)
+     * License: CDDL
+
+jersey-common-2.23.2.jar (2.23.2)
+    * License: CDDL
+
+jersey-container-servlet-2.23.2.jar  (2.23.2)
+    * License: CDDL
+
+jersey-container-servlet-core-2.23.3.jar(2.23.2)
+    * License: CDDL
+
+jersey-guava-2.23.2.jar  (2.23.2)
+    * License: Apache License, 2.0
+
+jersey-media-jaxb-2.23.2.jar(2.23.2)
+    * License: CDDL
+
+jersey-media-sse-2.23.2.jar (2.23.2)
+    * License: CDDL
+
+jersey-media-multipart-2.23.2.jar (2.23.2)
+    * License: CDDL
+
+jersey-server-2.23.2.jar (2.23.2)
+    * License: Apache-2.0
+
+log4j-over-slf4j-1.7.25.jar (1.7.25)
+    * License: Apache-2.0
+
+logback-classic-1.2.3.jar(1.2.3)
+    * License: Eclipse Public License 1.0
+
+logback-core-1.2.3.jar(1.2.3)
+    * License: Eclipse Public License 1.0
+
+mimepull-1.9.6.jar (1.9.4)
+    * License: CDDL
+
+openatfx-0.7.4.jar (0.7.4)
+    * License: Apache-2.0
+
+osgi-resource-locator-1.0.1.jar(1.0.1)
+    * License: CDDL
+
+protobuf-java-3.2.0.jar (3.2.0)
+    * License: New BSD license
+
+protobuf-java-util-3.2.0.jar  (3.2.0)
+    * License: New BSD license
+
+swagger-annotations-2.0.8.jar (2.0.8)
+    * License: Apache-2.0
+
+swagger-ui-3.23.0.jar (3.23.0)
+    * License: Apache-2.0
+
+slf4j-api-1.7.25.jar  (1.7.25)
+    * License: MIT license
+    * Licence Path: https://www.slf4j.org/license.html
+    * Project URL: https://github.com/qos-ch/slf4j
+    * Source URL:  https://github.com/qos-ch/slf4j/releases/tag/v_1.7.25
+
+stax2-api-3.1.4.jar (3.1.4)
+    * License: BSD-2-Clause
+
+validation-api-1.1.0.Final.jar (1.1.0.Final)
+  * License: Apache License, 2.0
+
+vavr-0.9.1-sources.jar (0.9.1)
+  * License: Apache License, 2.0
+
+vavr-match-0.9.1.jar (0.9.1)
+  * License: Apache License, 2.0
+
+woodstox-core-asl-4.4.1.jar (4.4.1)
+  * License: Apache License, 2.0
+
+
+FFAMFAMFAM Silk Icon, Version 1.3
+    * License: Creative Commons Attribution 3.0 License
+    * Licence Path: https://creativecommons.org/licenses/by/3.0/
+    * Project: http://www.famfamfam.com/lab/icons/silk/
+    * Source:  http://www.famfamfam.com/lab/icons/silk/
+
+@angular/animations:7.2.4
+    * License: MIT
+    * Licence Path: https://github.com/angular/angular/blob/master/LICENSE
+    * Project: https://angular.io/api/animations
+    * Source:  https://github.com/angular/angular/releases/tag/7.2.4
+
+@angular/cdk:7.1.1
+    * License: MIT
+    * Licence Path: https://github.com/angular/angular/blob/master/LICENSE
+    * Project: https://angular.io/api
+    * Source:  https://github.com/angular/angular/releases/tag/7.1.1
+
+
+@angular/common@7.2.4
+    * License: MIT
+    * Licence Path: https://github.com/angular/angular/blob/master/LICENSE
+    * Project: https://angular.io/api/common
+    * Source:  https://github.com/angular/angular/releases/tag/7.2.4r
+
+@angular/compiler@7.2.4
+    * License: MIT
+    * Licence Path: https://github.com/angular/angular/blob/master/LICENSE
+    * Project: https://angular.io
+    * Source:  https://github.com/angular/angular/releases/tag/7.2.4
+
+@angular/core@7.2.4
+    * License: MIT
+    * Licence Path: https://github.com/angular/angular/blob/master/LICENSE
+    * Project: https://angular.io
+    * Source:  https://github.com/angular/angular/releases/tag/7.2.4
+
+@angular/forms@7.2.4
+    * License: MIT
+    * Licence Path: https://github.com/angular/angular/blob/master/LICENSE
+    * Project: https://angular.io
+    * Source:  https://github.com/angular/angular/releases/tag/7.2.4
+
+@angular/http@7.2.4
+    * License: MIT
+    * Licence Path: https://github.com/angular/angular/blob/master/LICENSE
+    * Project: https://angular.io
+    * Source:  https://github.com/angular/angular/releases/tag/7.2.4
+
+@angular/platform-browser-dynamic@7.2.4
+    * License: MIT
+    * Licence Path: https://github.com/angular/angular/blob/master/LICENSE
+    * Project: https://angular.io
+    * Source:  https://github.com/angular/angular/releases/tag/7.2.4
+
+@angular/platform-browser@7.2.4
+    * License: MIT
+    * Licence Path: https://github.com/angular/angular/blob/master/LICENSE
+    * Project: https://angular.io
+    * Source:  https://github.com/angular/angular/releases/tag/7.2.4
+
+@angular/router@7.2.4
+    * License: MIT
+    * Licence Path: https://github.com/angular/angular/blob/master/LICENSE
+    * Project: https://angular.io
+    * Source:  https://github.com/angular/angular/releases/tag/7.2.4
+
+bootstrap@4.1.3
+    * License: MIT
+    * Licence Path: https://github.com/twbs/bootstrap/raw/master/LICENSE
+    * Project: https://getbootstrap.com/
+    * Source:  https://github.com/twbs/bootstrap
+
+class-transformer@0.1.6
+    * License: MIT
+    * Licence Path: https://github.com/typestack/class-transformer/blob/master/LICENSE
+    * Project: https://github.com/pleerock/class-transformer
+    * Source:  https://github.com/pleerock/class-transformer
+
+core-js@2.6.0
+    * License: MIT
+    * Licence Path: https://github.com/zloirock/core-js/raw/master/LICENSE
+    * Project: https://github.com/zloirock/core-js
+    * Source:  https://github.com/zloirock/core-js/releases/tag/v2.6.0
+
+file-saver@1.3.3
+    * License: MIT
+    * Licence Path: https://github.com/eligrey/FileSaver.js/raw/master/LICENSE.md
+    * Project: https://github.com/eligrey/FileSaver.js
+    * Source:  https://github.com/eligrey/FileSaver.js
+
+font-awesome@4.7.0
+    * License: MIT
+    * Licence Path: https://github.com/FortAwesome/Font-Awesome/blob/master/LICENSE.txt
+    * Project: https://fontawesome.com/
+    * Source:  https://github.com/FortAwesome/Font-Awesome
+
+ng2-split-pane@1.3.1
+    * License: MIT
+    * Licence Path: https://github.com/wannabegeek/ng2-split-pane/raw/master/LICENSE
+    * Project: https://github.com/wannabegeek/ng2-split-pane
+    * Source:  https://github.com/wannabegeek/ng2-split-pane
+
+ngx-bootstrap@3.1.2
+    * License: MIT
+    * Licence Path: https://github.com/valor-software/ngx-bootstrap/blob/v3.1.2/LICENSE
+    * Project: https://valor-software.com/ngx-bootstrap
+    * Source:  https://github.com/valor-software/ngx-bootstrap/tree/v3.1.2
+
+@ngx-translate/core@11.0.1
+    * License: MIT 
+    * Licence Path:   https://github.com/ngx-translate/core/blob/v11.0.1/LICENSE  
+    * Project URL:    http://www.ngx-translate.com/
+    * Source URL:     https://github.com/ngx-translate/core
+
+@ngx-translate/http-loader@4.0.0
+    * License: MIT 
+    * Licence Path:   https://github.com/ngx-translate/http-loader/blob/v4.0.0/LICENSE  
+    * Project URL:    http://www.ngx-translate.com/
+    * Source URL:     https://github.com/ngx-translate/http-loader/tree/v4.0.0
+
+primeicons:1.0.0
+    * License: MIT
+    * Licence Path: https://github.com/primefaces/primeicons/blob/1.0.0/LICENSE
+    * Project: https://www.primefaces.org/primeng
+    * Source:  https://github.com/primefaces/primeicons/tree/1.0.0
+
+primeng@7.0.1
+    * License: MIT
+    * Licence Path: https://github.com/primefaces/primeng/blob/7.0.1/LICENSE.md
+    * Project: https://www.primefaces.org/primeng
+    * Source:  https://github.com/primefaces/primeng/tree/7.0.1
+
+rxjs@6.3.3
+    * License: Apache-2.0
+    * Project: https://rxjs-dev.firebaseapp.com/
+    * Source:  https://github.com/ReactiveX/rxjs/tree/6.3.3
+
+rxjs-compat:6.3.3
+    * License: Apache-2.0
+    * Project: https://rxjs-dev.firebaseapp.com/
+    * Source:  https://github.com/ReactiveX/rxjs/tree/6.3.3/compat
+
+tslib@1.9.0
+    * License: Apache-2.0
+    * Project: https://github.com/Microsoft/tslib
+    * Source:  https://github.com/Microsoft/tslib/tree/1.9.0
+
+zone.js@0.8.26
+    * License: MIT
+    * Licence Path: https://github.com/angular/zone.js/raw/master/LICENSE
+    * Project: https://github.com/angular
+    * Source:  https://github.com/angular/zone.js/releases/tag/v0.8.26
+
+OMG Event Service Specification (1.2)
+
+* License: LicenseRef - Object-Management-Group-License
+* Project: https://www.omg.org/spec/EVNT/1.2/
+* Source: https://www.omg.org/spec/EVNT/1.2/pdf
+
+OMG Notification Service Specification (1.1)
+
+* License: LicenseRef - Object-Management-Group-License
+* Project: https://www.omg.org/spec/NOT/
+* Source: https://www.omg.org/spec/NOT/1.1/PDF
+
+ods530.idl
+Date: Hoehenkirchen, 06/01/2016
+"The ASAM Board of Directors releases the IDL files for use under the EPL to the Eclipse IWG openMDM.
+This is valid for all versions of ASAM ODS 5.3.x.
+This permission is valid under the conditions of Eclipse will not modify the file."
+
+AvalonEvent.idl, CorbaFileServer.idl
+Date: 08/15/2016
+"Herewith, we release the generated Client-Source-Code generated from our CORBA IDLs, namely
+* CORBANotification Service (generated from „AvalonEvent.idl”)
+* CORBAFileServer (generated from „CorbaFileServer.idl“),
+Under the Eclipse Public License (EPL). This agreement does not include the „AvalonEvent.idl“ and
+„CorbaFileServer.idl“ itself, which remain protected property of HighQSoft. "
+
+## Cryptography
+
+Content may contain encryption software. The country in which you are currently
+may have restrictions on the import, possession, and use, and/or re-export to
+another country, of encryption software. BEFORE using any encryption software,
+please check the country's laws, regulations and policies concerning the import,
+possession, or use, and re-export of encryption software, to see if this is
+permitted.
diff --git a/org.eclipse.mdm.api.default/build.gradle b/org.eclipse.mdm.api.default/build.gradle
new file mode 100644
index 0000000..26035f0
--- /dev/null
+++ b/org.eclipse.mdm.api.default/build.gradle
@@ -0,0 +1,49 @@
+/********************************************************************************
+ * Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+description = 'MDM API - Default Model'
+group = 'org.eclipse.mdm'
+version = '5.2.0M1-SNAPSHOT'
+
+apply plugin: 'java'
+apply plugin: 'maven'
+apply plugin: 'eclipse'
+
+repositories {
+	mavenLocal()
+	mavenCentral()
+}
+
+dependencies {
+	compile "org.eclipse.mdm:org.eclipse.mdm.api.base:${version}"
+
+	// testing
+	testCompile 'junit:junit:4.12'
+	testCompile 'org.mockito:mockito-core:2.13.0'
+	testCompile 'org.assertj:assertj-core:3.6.2'
+}
+
+jar {
+	metaInf { from 'NOTICE.txt' }
+	metaInf { from 'LICENSE.txt' }
+}
+
+task sourcesJar(type: Jar, dependsOn: classes) {
+	classifier = 'sources'
+	from sourceSets.main.allSource
+}
+
+artifacts {
+	archives sourcesJar
+}
\ No newline at end of file
diff --git a/org.eclipse.mdm.api.default/gradle.properties b/org.eclipse.mdm.api.default/gradle.properties
new file mode 100644
index 0000000..2ab5436
--- /dev/null
+++ b/org.eclipse.mdm.api.default/gradle.properties
@@ -0,0 +1,16 @@
+/********************************************************************************
+ * Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+ 
+sourceCompatibility=1.8
+targetCompatibility=1.8
\ No newline at end of file
diff --git a/org.eclipse.mdm.api.default/gradle/wrapper/gradle-wrapper.jar b/org.eclipse.mdm.api.default/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..7a3265e
--- /dev/null
+++ b/org.eclipse.mdm.api.default/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/org.eclipse.mdm.api.default/gradle/wrapper/gradle-wrapper.properties b/org.eclipse.mdm.api.default/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..b82e006
--- /dev/null
+++ b/org.eclipse.mdm.api.default/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME

+distributionPath=wrapper/dists

+zipStoreBase=GRADLE_USER_HOME

+zipStorePath=wrapper/dists

+distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-bin.zip

diff --git a/org.eclipse.mdm.api.default/gradlew b/org.eclipse.mdm.api.default/gradlew
new file mode 100755
index 0000000..cccdd3d
--- /dev/null
+++ b/org.eclipse.mdm.api.default/gradlew
@@ -0,0 +1,172 @@
+#!/usr/bin/env sh
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+    echo "$*"
+}
+
+die () {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+  NONSTOP* )
+    nonstop=true
+    ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+    JAVACMD=`cygpath --unix "$JAVACMD"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Escape application args
+save () {
+    for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+    echo " "
+}
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+  cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
diff --git a/org.eclipse.mdm.api.default/gradlew.bat b/org.eclipse.mdm.api.default/gradlew.bat
new file mode 100644
index 0000000..e95643d
--- /dev/null
+++ b/org.eclipse.mdm.api.default/gradlew.bat
@@ -0,0 +1,84 @@
+@if "%DEBUG%" == "" @echo off

+@rem ##########################################################################

+@rem

+@rem  Gradle startup script for Windows

+@rem

+@rem ##########################################################################

+

+@rem Set local scope for the variables with windows NT shell

+if "%OS%"=="Windows_NT" setlocal

+

+set DIRNAME=%~dp0

+if "%DIRNAME%" == "" set DIRNAME=.

+set APP_BASE_NAME=%~n0

+set APP_HOME=%DIRNAME%

+

+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.

+set DEFAULT_JVM_OPTS=

+

+@rem Find java.exe

+if defined JAVA_HOME goto findJavaFromJavaHome

+

+set JAVA_EXE=java.exe

+%JAVA_EXE% -version >NUL 2>&1

+if "%ERRORLEVEL%" == "0" goto init

+

+echo.

+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.

+echo.

+echo Please set the JAVA_HOME variable in your environment to match the

+echo location of your Java installation.

+

+goto fail

+

+:findJavaFromJavaHome

+set JAVA_HOME=%JAVA_HOME:"=%

+set JAVA_EXE=%JAVA_HOME%/bin/java.exe

+

+if exist "%JAVA_EXE%" goto init

+

+echo.

+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%

+echo.

+echo Please set the JAVA_HOME variable in your environment to match the

+echo location of your Java installation.

+

+goto fail

+

+:init

+@rem Get command-line arguments, handling Windows variants

+

+if not "%OS%" == "Windows_NT" goto win9xME_args

+

+:win9xME_args

+@rem Slurp the command line arguments.

+set CMD_LINE_ARGS=

+set _SKIP=2

+

+:win9xME_args_slurp

+if "x%~1" == "x" goto execute

+

+set CMD_LINE_ARGS=%*

+

+:execute

+@rem Setup the command line

+

+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar

+

+@rem Execute Gradle

+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%

+

+:end

+@rem End local scope for the variables with windows NT shell

+if "%ERRORLEVEL%"=="0" goto mainEnd

+

+:fail

+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of

+rem the _cmd.exe /c_ return code!

+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1

+exit /b 1

+

+:mainEnd

+if "%OS%"=="Windows_NT" endlocal

+

+:omega

diff --git a/org.eclipse.mdm.api.default/settings.gradle b/org.eclipse.mdm.api.default/settings.gradle
new file mode 100644
index 0000000..c7402a5
--- /dev/null
+++ b/org.eclipse.mdm.api.default/settings.gradle
@@ -0,0 +1,15 @@
+/********************************************************************************
+ * Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+rootProject.name = 'org.eclipse.mdm.api.default'
diff --git a/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/ApplicationContext.java b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/ApplicationContext.java
new file mode 100644
index 0000000..2831ec9
--- /dev/null
+++ b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/ApplicationContext.java
@@ -0,0 +1,28 @@
+/********************************************************************************
+ * Copyright (c) 2015-2019 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+package org.eclipse.mdm.api.dflt;
+
+import org.eclipse.mdm.api.base.BaseApplicationContext;
+import org.eclipse.mdm.api.dflt.model.EntityFactory;
+
+/**
+ * Extends the {@link BaseApplicationContext} interface to return
+ * {@link EntityFactory} and {@link EntityManager}.
+ *
+ * @since 1.0.0
+ */
+public interface ApplicationContext extends BaseApplicationContext<EntityFactory, EntityManager> {
+
+}
diff --git a/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/ApplicationContextFactory.java b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/ApplicationContextFactory.java
new file mode 100644
index 0000000..2bdad67
--- /dev/null
+++ b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/ApplicationContextFactory.java
@@ -0,0 +1,27 @@
+/********************************************************************************
+ * Copyright (c) 2015-2019 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+package org.eclipse.mdm.api.dflt;
+
+import org.eclipse.mdm.api.base.BaseApplicationContextFactory;
+
+/**
+ * Extends the {@link BaseApplicationContextFactory} interface to return an
+ * {@link ApplicationContext}.
+ *
+ * @since 1.0.0
+ */
+public interface ApplicationContextFactory extends BaseApplicationContextFactory<ApplicationContext> {
+
+}
diff --git a/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/EntityManager.java b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/EntityManager.java
new file mode 100644
index 0000000..8298101
--- /dev/null
+++ b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/EntityManager.java
@@ -0,0 +1,167 @@
+/********************************************************************************
+ * Copyright (c) 2015-2019 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+package org.eclipse.mdm.api.dflt;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+
+import org.eclipse.mdm.api.base.BaseEntityManager;
+import org.eclipse.mdm.api.base.model.ContextType;
+import org.eclipse.mdm.api.base.model.Entity;
+import org.eclipse.mdm.api.base.model.StatusAttachable;
+import org.eclipse.mdm.api.base.model.Test;
+import org.eclipse.mdm.api.base.model.TestStep;
+import org.eclipse.mdm.api.base.query.DataAccessException;
+import org.eclipse.mdm.api.dflt.model.Status;
+import org.eclipse.mdm.api.dflt.model.TemplateTest;
+import org.eclipse.mdm.api.dflt.model.TemplateTestStep;
+import org.eclipse.mdm.api.dflt.model.Versionable;
+
+/**
+ * Extends the {@link BaseEntityManager} interface with additional load methods
+ * dedicated to the default application models.
+ *
+ * @since 1.0.0
+ * @author Viktor Stoehr, Gigatronik Ingolstadt GmbH
+ */
+public interface EntityManager extends BaseEntityManager {
+
+	// ======================================================================
+	// Public methods
+	// ======================================================================
+
+	/**
+	 * Loads the entity identified by given entity class, {@link ContextType} and
+	 * its instance ID.
+	 *
+	 * @param <T>         The desired type.
+	 * @param entityClass Type of the returned entity.
+	 * @param contextType The {@link ContextType}.
+	 * @param instanceID  The instance ID.
+	 * @return The entity with given instance ID is returned.
+	 * @throws DataAccessException Thrown if unable to retrieve the entity.
+	 */
+	default <T extends Entity> T load(Class<T> entityClass, ContextType contextType, String instanceID)
+			throws DataAccessException {
+		List<T> entities = load(entityClass, contextType, Collections.singletonList(instanceID));
+		if (entities.size() != 1) {
+			throw new DataAccessException("Failed to load entity by instance ID.");
+		}
+		return entities.get(0);
+
+	}
+
+	<T extends Entity> List<T> load(Class<T> entityClass, ContextType contextType, Collection<String> instanceIDs)
+			throws DataAccessException;
+
+	/**
+	 * Loads all available entities of given type.
+	 *
+	 * <pre>
+	 * {
+	 * 	&#64;code
+	 * 	List<CatalogComponent> catalogComponents = entityManager.loadAll(CatalogComponent.class, UNITUNDERTEST);
+	 * }
+	 * </pre>
+	 *
+	 * @param <T>         The desired type.
+	 * @param entityClass Type of the returned entities.
+	 * @param contextType The {@link ContextType}.
+	 * @return Entities are returned in a {@code List}.
+	 * @throws DataAccessException Thrown if unable to retrieve the entities.
+	 * @see #loadAll(Class, ContextType, String)
+	 */
+	default <T extends Entity> List<T> loadAll(Class<T> entityClass, ContextType contextType)
+			throws DataAccessException {
+		return loadAll(entityClass, contextType, "*");
+	}
+
+	/**
+	 * Loads all available entities of given type whose name fulfills the given
+	 * pattern.
+	 *
+	 * <pre>
+	 * {
+	 * 	&#64;code
+	 * 	// retrieve all template roots whose name starts with 'Example'
+	 * 	List<TemplateRoot> templateRoots = entityManager.loadAll(TemplateRoot.class, UNITUNDERTEST, "Example*");
+	 * }
+	 * </pre>
+	 *
+	 * @param <T>         The desired type.
+	 * @param entityClass Type of the returned entities.
+	 * @param contextType The {@link ContextType}.
+	 * @param pattern     Is always case sensitive and may contain wildcard
+	 *                    characters as follows: "?" for one matching character and
+	 *                    "*" for a sequence of matching characters.
+	 * @return Matched entities are returned in a {@code List}.
+	 * @throws DataAccessException Thrown if unable to retrieve the entities.
+	 * @see #loadAll(Class)
+	 */
+	<T extends Entity> List<T> loadAll(Class<T> entityClass, ContextType contextType, String pattern)
+			throws DataAccessException;
+
+	/**
+	 * Loads the latest valid {@link Versionable} entity of given type and name.
+	 *
+	 * @param <T>         The desired type.
+	 * @param entityClass Type of the returned entity.
+	 * @param name        The exact name of the requested entity.
+	 * @return Optional is empty if no such entity was found
+	 * @throws DataAccessException Thrown if unable to retrieve the entity.
+	 */
+	default <T extends Versionable> Optional<T> loadLatestValid(Class<T> entityClass, String name)
+			throws DataAccessException {
+		return loadAll(entityClass, name).stream().filter(v -> v.nameEquals(name)).filter(Versionable::isValid)
+				.max(Versionable.COMPARATOR);
+	}
+
+	/**
+	 * Loads the latest valid {@link Versionable} entity of given type,
+	 * {@link ContextType} and name.
+	 *
+	 * @param <T>         The desired type.
+	 * @param entityClass Type of the returned entity.
+	 * @param contextType The {@code ContextType}.
+	 * @param name        The exact name of the requested entity.
+	 * @return Optional is empty if no such entity was found
+	 * @throws DataAccessException Thrown if unable to retrieve the entity.
+	 */
+	default <T extends Versionable> Optional<T> loadLatestValid(Class<T> entityClass, ContextType contextType,
+			String name) throws DataAccessException {
+		return loadAll(entityClass, contextType, name).stream().filter(v -> v.nameEquals(name))
+				.filter(Versionable::isValid).max(Versionable.COMPARATOR);
+	}
+
+	<T extends StatusAttachable> List<T> loadAll(Class<T> entityClass, Status status, String pattern);
+
+	/**
+	 * Loads the refereced {@link TemplateTest} for a {@link Test}.
+	 * 
+	 * @param test {@link Test} referencing the desired template
+	 * @return {@link Optional} with the loaded {@link TemplateTest}
+	 */
+	Optional<TemplateTest> loadTemplate(Test test);
+
+	/**
+	 * Loads the referenced {@link TemplateTestStep} for a {@link TestStep}
+	 * 
+	 * @param testStep {@link TestStep} referencing the desired template
+	 * @return {@link Optional} with the loaded {@link TemplateTestStep}
+	 */
+	Optional<TemplateTestStep> loadTemplate(TestStep testStep);
+}
diff --git a/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/CatalogAttribute.java b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/CatalogAttribute.java
new file mode 100644
index 0000000..ac6c20d
--- /dev/null
+++ b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/CatalogAttribute.java
@@ -0,0 +1,321 @@
+/********************************************************************************
+ * Copyright (c) 2015-2019 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+package org.eclipse.mdm.api.dflt.model;
+
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import org.eclipse.mdm.api.base.adapter.Core;
+import org.eclipse.mdm.api.base.model.BaseEntity;
+import org.eclipse.mdm.api.base.model.Deletable;
+import org.eclipse.mdm.api.base.model.Describable;
+import org.eclipse.mdm.api.base.model.EnumRegistry;
+import org.eclipse.mdm.api.base.model.Enumeration;
+import org.eclipse.mdm.api.base.model.ScalarType;
+import org.eclipse.mdm.api.base.model.Sortable;
+import org.eclipse.mdm.api.base.model.Unit;
+import org.eclipse.mdm.api.base.model.Value;
+import org.eclipse.mdm.api.base.model.ValueType;
+
+/**
+ * Implementation of the catalog attribute entity type. A catalog attribute is a
+ * generic attribute description to store context data ("as measured", "as
+ * ordered"). It always belongs to a {@link CatalogComponent} or a
+ * {@link CatalogSensor}. Its name has to be unique within the parent and may
+ * not be changed, once written.
+ *
+ * @since 1.0.0
+ * @author Viktor Stoehr, Gigatronik Ingolstadt GmbH
+ * @see CatalogComponent
+ * @see CatalogSensor
+ */
+public class CatalogAttribute extends BaseEntity implements Deletable, Describable, Sortable {
+
+	// ======================================================================
+	// Class variables
+	// ======================================================================
+
+	/**
+	 * The 'ValueListReference' attribute name.
+	 */
+	public static final String ATTR_VALUE_LIST_REFERENCE = "ValueListRef";
+
+	/**
+	 * The 'ValueCopyable' attribute name.
+	 */
+	public static final String ATTR_VALUE_COPYABLE = "ValueCopyable";
+
+	/**
+	 * The 'ActionRequestClassname' attribute name.
+	 */
+	public static final String ATTR_ACTION_REQUEST_CLASSNAME = "ActionRequestClassname";
+
+	/**
+	 * The <u>virtual</u> '{@literal @}EnumerationName' attribute name.
+	 */
+	public static final String VATTR_ENUMERATION_NAME = "@EnumerationName";
+
+	/**
+	 * The <u>virtual</u> '{@literal @}ScalarType' attribute name.
+	 */
+	public static final String VATTR_SCALAR_TYPE = "@ScalarType";
+
+	/**
+	 * The <u>virtual</u> '{@literal @}Sequence' attribute name.
+	 */
+	public static final String VATTR_SEQUENCE = "@Sequence";
+
+	// ======================================================================
+	// Instance variables
+	// ======================================================================
+
+	private Enumeration<?> enumerationObj;
+	private final Value scalarTypeValue;
+	private final Value sequenceValue;
+
+	private Unit unit;
+
+	// ======================================================================
+	// Constructors
+	// ======================================================================
+
+	/**
+	 * Constructor.
+	 *
+	 * @param core The {@link Core}.
+	 */
+	CatalogAttribute(Core core) {
+		super(core);
+
+		Map<String, Value> values = core.getValues();
+		EnumRegistry er = EnumRegistry.getInstance();
+		Value enumValue = values.remove(VATTR_ENUMERATION_NAME);
+		if (enumValue != null) {
+			enumerationObj = er.get(enumValue.extract(ValueType.STRING));
+		}
+		scalarTypeValue = values.remove(VATTR_SCALAR_TYPE);
+		sequenceValue = values.remove(VATTR_SEQUENCE);
+
+		unit = core.getMutableStore().get(Unit.class);
+		core.getMutableStore().remove(Unit.class);
+	}
+
+	// ======================================================================
+	// Public methods
+	// ======================================================================
+
+	/**
+	 * Checks whether it is allowed to store other data than those provided via
+	 * related {@link ValueList}.
+	 *
+	 * @return Returns {@code false} if it is allowed to store other values then
+	 *         those provided.
+	 */
+	public Boolean isValueListReference() {
+		boolean valueListReference = getValue(ATTR_VALUE_LIST_REFERENCE).extract();
+		return valueListReference && getValueList().isPresent();
+	}
+
+	/**
+	 * Sets a new value reference flag for this catalog attribute.
+	 *
+	 * @param valueListReference The new value list reference flag.
+	 */
+	public void setValueListReference(Boolean valueListReference) {
+		getValue(ATTR_VALUE_LIST_REFERENCE).set(valueListReference);
+	}
+
+	/**
+	 * Checks whether it is allowed to copy the contained value in case of an
+	 * associated descriptive component is copied.
+	 *
+	 * @return Returns {@code true} if it allowed to copy a contained value.
+	 */
+	public Boolean isValueCopyable() {
+		return getValue(ATTR_VALUE_COPYABLE).extract();
+	}
+
+	/**
+	 * Sets a new value copyable flag for this catalog attribute.
+	 *
+	 * @param valueCopyable The new value copyable flag.
+	 */
+	public void setValueCopyable(Boolean valueCopyable) {
+		getValue(ATTR_VALUE_COPYABLE).set(valueCopyable);
+	}
+
+	/**
+	 * Returns the action request class name of this catalog attribute.
+	 *
+	 * @return The action request class name is returned.
+	 */
+	public String getActionRequestClassname() {
+		return getValue(ATTR_ACTION_REQUEST_CLASSNAME).extract();
+	}
+
+	/**
+	 * Sets a new action request class name for this attribute.
+	 *
+	 * @param actionRequestClassname The new action request class name.
+	 */
+	public void setActionRequestClassname(String actionRequestClassname) {
+		getValue(ATTR_ACTION_REQUEST_CLASSNAME).set(actionRequestClassname);
+	}
+
+	/**
+	 * Returns the related {@link ValueList}.
+	 *
+	 * @return {@code Optional} is empty if no {@code ValueList} is related.
+	 */
+	public Optional<ValueList> getValueList() {
+		return Optional.ofNullable(getCore().getMutableStore().get(ValueList.class));
+	}
+
+	/**
+	 * Replaces current {@link ValueList} relation with the given one.
+	 *
+	 * @param valueList The new {@code ValueList} may be null.
+	 */
+	public void setValueList(ValueList valueList) {
+		if (valueList == null) {
+			getCore().getMutableStore().remove(ValueList.class);
+			setValueListReference(Boolean.FALSE);
+		} else {
+			getCore().getMutableStore().set(valueList);
+		}
+	}
+
+	/**
+	 * Returns the parent {@link CatalogComponent}.
+	 *
+	 * @return {@code Optional} is empty if a {@link CatalogSensor} is parent of
+	 *         this catalog attribute.
+	 * @see #getCatalogSensor()
+	 */
+	public Optional<CatalogComponent> getCatalogComponent() {
+		return Optional.ofNullable(getCore().getPermanentStore().get(CatalogComponent.class));
+	}
+
+	/**
+	 * Returns the parent {@link CatalogSensor}.
+	 *
+	 * @return {@code Optional} is empty if a {@link CatalogComponent} is parent of
+	 *         this catalog attribute.
+	 * @see #getCatalogComponent()
+	 */
+	public Optional<CatalogSensor> getCatalogSensor() {
+		return Optional.ofNullable(getCore().getPermanentStore().get(CatalogSensor.class));
+	}
+
+	/**
+	 * Returns the virtual and unmodifiable {@link ValueType} of this catalog
+	 * attribute.
+	 *
+	 * @return The {@code ValueType} is returned.
+	 */
+	public ValueType<?> getValueType() {
+		ScalarType scalarType = scalarTypeValue.extract();
+		Boolean sequence = sequenceValue.extract();
+		return sequence.booleanValue() ? scalarType.toValueType() : scalarType.toSingleValueType();
+	}
+
+	/**
+	 * Returns the virtual and unmodifiable enumeration class of this catalog
+	 * attribute.
+	 *
+	 * @return The enumeration class is returned.
+	 * @throws IllegalStateException Thrown if this catalog attribute's
+	 *                               {@link ValueType} returns {@code true} when
+	 *                               {@link ValueType#isEnumerationType()} is
+	 *                               called.
+	 */
+	@SuppressWarnings("rawtypes")
+	public Enumeration getEnumerationObject() {
+		if (!getValueType().isEnumerationType()) {
+			throw new IllegalStateException("Catalog attribute is not of type enumeration.");
+		}
+		return enumerationObj;
+	}
+
+	/**
+	 * Returns the {@link Unit} of this catalog attribute.
+	 *
+	 * @return {@code Optional} is empty if no unit is defined.
+	 */
+	public Optional<Unit> getUnit() {
+		return Optional.ofNullable(unit);
+	}
+
+	/**
+	 * Sets a new {@link Unit} for this catalog attribute.
+	 *
+	 * @param unit The new {@code Unit} may be null.
+	 */
+	public void setUnit(Unit unit) {
+		this.unit = unit;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public String toString() {
+		StringBuilder sb = new StringBuilder(getClass().getSimpleName()).append('(');
+
+		ScalarType scalarType = scalarTypeValue.extract();
+		sb.append("ScalarType = ").append(scalarType);
+		if (scalarType.isEnumeration()) {
+			sb.append(", EnumerationObject = ").append(getEnumerationObject());
+		}
+
+		sb.append(", Sequence = ").append((boolean) sequenceValue.extract());
+
+		Optional<Unit> catalogUnit = getUnit();
+		if (catalogUnit.isPresent()) {
+			sb.append(", Unit = ").append(catalogUnit.get());
+		}
+
+		sb.append(", ").append(getValues().values().stream().map(Value::toString).collect(Collectors.joining(", ")));
+
+		return sb.append(')').toString();
+	}
+
+	// ======================================================================
+	// Package methods
+	// ======================================================================
+
+	/**
+	 * Sets {@link ValueType} of this catalog attribute.
+	 *
+	 * @param valueType The {@link ValueType}.
+	 */
+	void setValueType(ValueType<?> valueType) {
+		Enumeration<?> scalarTypeEnum = EnumRegistry.getInstance().get(EnumRegistry.SCALAR_TYPE);
+		scalarTypeValue.set(scalarTypeEnum.valueOf(valueType.toSingleType().name()));
+		sequenceValue.set(valueType.isSequence());
+	}
+
+	/**
+	 * Sets enumeration Object of this catalog attribute.
+	 *
+	 * @param enumerationObj The enumeration.
+	 */
+	void setEnumerationObj(Enumeration<?> enumerationObj) {
+		setValueType(ValueType.ENUMERATION);
+		this.enumerationObj = enumerationObj;
+	}
+
+}
diff --git a/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/CatalogComponent.java b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/CatalogComponent.java
new file mode 100644
index 0000000..f91dc18
--- /dev/null
+++ b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/CatalogComponent.java
@@ -0,0 +1,192 @@
+/********************************************************************************
+ * Copyright (c) 2015-2019 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+package org.eclipse.mdm.api.dflt.model;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import org.eclipse.mdm.api.base.adapter.Core;
+import org.eclipse.mdm.api.base.model.BaseEntity;
+import org.eclipse.mdm.api.base.model.ContextType;
+import org.eclipse.mdm.api.base.model.Datable;
+import org.eclipse.mdm.api.base.model.Deletable;
+import org.eclipse.mdm.api.base.model.Describable;
+import org.eclipse.mdm.api.base.model.Value;
+
+/**
+ * Implementation of the catalog component entity type. A catalog component acts
+ * as a container to store context data ("as measured", "as ordered"). Each
+ * catalog component has a corresponding entity type whose name is equal to the
+ * name of the catalog component. Therefore the name of a catalog component has
+ * to be unique and is not allowed to be modified, once written. A catalog
+ * component consists of {@link CatalogAttribute} which describe the attributes
+ * of this container. In case of {@link ContextType#TESTEQUIPMENT} it may have
+ * {@link CatalogSensor}s which describe the available measurement sensors.
+ *
+ * @since 1.0.0
+ * @author Viktor Stoehr, Gigatronik Ingolstadt GmbH
+ * @see CatalogAttribute
+ * @see CatalogSensor
+ */
+public class CatalogComponent extends BaseEntity implements Datable, Deletable, Describable {
+
+	// ======================================================================
+	// Instance variables
+	// ======================================================================
+
+	private final ContextType contextType;
+
+	// ======================================================================
+	// Constructors
+	// ======================================================================
+
+	/**
+	 * Constructor.
+	 *
+	 * @param core The {@link Core}.
+	 */
+	CatalogComponent(Core core) {
+		super(core);
+
+		String typeName = core.getTypeName().toUpperCase(Locale.ROOT);
+		for (ContextType contextTypeCandidate : ContextType.values()) {
+			if (typeName.contains(contextTypeCandidate.name())) {
+				contextType = contextTypeCandidate;
+				return;
+			}
+		}
+
+		throw new IllegalStateException("Core is incompatible.");
+	}
+
+	// ======================================================================
+	// Public methods
+	// ======================================================================
+
+	/**
+	 * Returns the {@link ContextType} of this catalog component.
+	 *
+	 * @return The {@code ContextType} is returned.
+	 */
+	public ContextType getContextType() {
+		return contextType;
+	}
+
+	/**
+	 * Returns the {@link CatalogAttribute} identified by given name.
+	 *
+	 * @param name The name of the {@code CatalogAttribute}.
+	 * @return The {@code Optional} is empty if a {@code CatalogAttribute} with
+	 *         given name does not exist.
+	 */
+	public Optional<CatalogAttribute> getCatalogAttribute(String name) {
+		return getCatalogAttributes().stream().filter(ca -> ca.nameEquals(name)).findAny();
+	}
+
+	/**
+	 * Returns all available {@link CatalogAttribute}s related to this catalog
+	 * component.
+	 *
+	 * @return The returned {@code List} is unmodifiable.
+	 */
+	public List<CatalogAttribute> getCatalogAttributes() {
+		return getCore().getChildrenStore().get(CatalogAttribute.class);
+	}
+
+	/**
+	 * Removes the {@link CatalogAttribute} identified by given name.
+	 *
+	 * @param name Name of the {@code CatalogAttribute} that has to be removed.
+	 * @return Returns {@code true} if the {@code CatalogAttribute} with given name
+	 *         has been removed.
+	 */
+	public boolean removeCatalogAttribute(String name) {
+		Optional<CatalogAttribute> catalogAttribute = getCatalogAttribute(name);
+		if (catalogAttribute.isPresent()) {
+			getCore().getChildrenStore().remove(catalogAttribute.get());
+			return true;
+		}
+
+		return false;
+	}
+
+	/**
+	 * Returns the {@link CatalogSensor} identified by given name.
+	 *
+	 * @param name The name of the {@code CatalogSensor}.
+	 * @return The {@code Optional} is empty if a {@code CatalogSensor} with given
+	 *         name does not exist.
+	 */
+	public Optional<CatalogSensor> getCatalogSensor(String name) {
+		return getCatalogSensors().stream().filter(cs -> cs.nameEquals(name)).findAny();
+	}
+
+	/**
+	 * Returns all available {@link CatalogSensor}s related to this catalog
+	 * component.
+	 *
+	 * @return The returned {@code List} is unmodifiable.
+	 */
+	public List<CatalogSensor> getCatalogSensors() {
+		if (contextType.isTestEquipment()) {
+			return getCore().getChildrenStore().get(CatalogSensor.class);
+		}
+
+		return Collections.emptyList();
+	}
+
+	/**
+	 * Removes the {@link CatalogSensor} identified by given name.
+	 *
+	 * @param name Name of the {@code CatalogSensor} that has to be removed.
+	 * @return Returns {@code true} if the {@code CatalogSensor} with given name has
+	 *         been removed.
+	 */
+	public boolean removeCatalogSensor(String name) {
+		Optional<CatalogSensor> catalogSensor = getCatalogSensor(name);
+		if (catalogSensor.isPresent()) {
+			getCore().getChildrenStore().remove(catalogSensor.get());
+			return true;
+		}
+
+		return false;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public String toString() {
+		StringBuilder sb = new StringBuilder(getClass().getSimpleName()).append('(');
+		sb.append("ContextType = ").append(getContextType()).append(", ");
+		sb.append(getValues().values().stream().map(Value::toString).collect(Collectors.joining(", ")));
+
+		List<CatalogAttribute> catalogAttributes = getCatalogAttributes();
+		if (!catalogAttributes.isEmpty()) {
+			sb.append(", CatalogAttributes = ").append(catalogAttributes);
+		}
+
+		List<CatalogSensor> catalogSensors = getCatalogSensors();
+		if (!catalogSensors.isEmpty()) {
+			sb.append(", CatalogSensors = ").append(catalogSensors);
+		}
+
+		return sb.append(')').toString();
+	}
+
+}
diff --git a/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/CatalogSensor.java b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/CatalogSensor.java
new file mode 100644
index 0000000..d365abd
--- /dev/null
+++ b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/CatalogSensor.java
@@ -0,0 +1,126 @@
+/********************************************************************************
+ * Copyright (c) 2015-2019 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+package org.eclipse.mdm.api.dflt.model;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import org.eclipse.mdm.api.base.adapter.Core;
+import org.eclipse.mdm.api.base.model.BaseEntity;
+import org.eclipse.mdm.api.base.model.ContextType;
+import org.eclipse.mdm.api.base.model.Datable;
+import org.eclipse.mdm.api.base.model.Deletable;
+import org.eclipse.mdm.api.base.model.Describable;
+import org.eclipse.mdm.api.base.model.Value;
+
+/**
+ * Implementation of the catalog sensor entity type. A catalog sensor acts as a
+ * container to store sensor context data ("as measured", "as ordered"). It
+ * always belongs to a {@link CatalogComponent} of type
+ * {@link ContextType#TESTEQUIPMENT}. Each catalog sensor has a corresponding
+ * entity type whose name is equal to the name of the catalog sensor. Therefore
+ * the name of a catalog sensor has to be unique and is not allowed to be
+ * modified, once written. A catalog sensor consists of {@link CatalogAttribute}
+ * which describe the attributes of this container.
+ *
+ * @since 1.0.0
+ * @author Viktor Stoehr, Gigatronik Ingolstadt GmbH
+ * @see CatalogComponent
+ * @see CatalogComponent
+ */
+public class CatalogSensor extends BaseEntity implements Datable, Deletable, Describable {
+
+	// ======================================================================
+	// Constructors
+	// ======================================================================
+
+	/**
+	 * Constructor.
+	 *
+	 * @param core The {@link Core}.
+	 */
+	CatalogSensor(Core core) {
+		super(core);
+	}
+
+	// ======================================================================
+	// Public methods
+	// ======================================================================
+
+	/**
+	 * Returns the parent {@link CatalogComponent}.
+	 *
+	 * @return The parent {@code CatalogComponent} is returned.
+	 */
+	public CatalogComponent getCatalogComponent() {
+		return getCore().getPermanentStore().get(CatalogComponent.class);
+	}
+
+	/**
+	 * Returns the {@link CatalogAttribute} identified by given name.
+	 *
+	 * @param name The name of the {@code CatalogAttribute}.
+	 * @return The {@code Optional} is empty if a {@code CatalogAttribute} with
+	 *         given name does not exist.
+	 */
+	public Optional<CatalogAttribute> getCatalogAttribute(String name) {
+		return getCatalogAttributes().stream().filter(ca -> ca.nameEquals(name)).findAny();
+	}
+
+	/**
+	 * Returns all available {@link CatalogAttribute}s related to this catalog
+	 * sensor.
+	 *
+	 * @return The returned {@code List} is unmodifiable.
+	 */
+	public List<CatalogAttribute> getCatalogAttributes() {
+		return getCore().getChildrenStore().get(CatalogAttribute.class);
+	}
+
+	/**
+	 * Removes the {@link CatalogAttribute} identified by given name.
+	 *
+	 * @param name Name of the {@code CatalogAttribute} that has to be removed.
+	 * @return Returns {@code true} if the {@code CatalogAttribute} with given name
+	 *         has been removed.
+	 */
+	public boolean removeCatalogAttribute(String name) {
+		Optional<CatalogAttribute> catalogAttribute = getCatalogAttribute(name);
+		if (catalogAttribute.isPresent()) {
+			getCore().getChildrenStore().remove(catalogAttribute.get());
+			return true;
+		}
+
+		return false;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public String toString() {
+		StringBuilder sb = new StringBuilder(getClass().getSimpleName()).append('(');
+		sb.append(getValues().values().stream().map(Value::toString).collect(Collectors.joining(", ")));
+
+		List<CatalogAttribute> catalogAttributes = getCatalogAttributes();
+		if (!catalogAttributes.isEmpty()) {
+			sb.append(", CatalogAttributes = ").append(catalogAttributes);
+		}
+
+		return sb.append(')').toString();
+	}
+
+}
diff --git a/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/Classification.java b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/Classification.java
new file mode 100644
index 0000000..6cb91ff
--- /dev/null
+++ b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/Classification.java
@@ -0,0 +1,56 @@
+/********************************************************************************
+ * Copyright (c) 2015-2019 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+package org.eclipse.mdm.api.dflt.model;
+
+import java.util.List;
+
+import org.eclipse.mdm.api.base.adapter.Core;
+import org.eclipse.mdm.api.base.model.BaseEntity;
+import org.eclipse.mdm.api.base.model.StatusAttachable;
+
+public class Classification extends BaseEntity {
+
+	// ======================================================================
+	// Constructors
+	// ======================================================================
+
+	/**
+	 * Constructor.
+	 *
+	 * @param core The {@link Core}.
+	 */
+	Classification(Core core) {
+		super(core);
+	}
+
+	/**
+	 * Assigns this status to given {@link StatusAttachable}s.
+	 *
+	 * @param <T>               The status attachable type.
+	 * @param statusAttachables This status will be assigned to all of them.
+	 */
+	public <T extends StatusAttachable> void assign(List<T> statusAttachables) {
+		statusAttachables.forEach(this::assign);
+	}
+
+	/**
+	 * Assigns this status to given {@link StatusAttachable}.
+	 *
+	 * @param <T>              The status attachable type.
+	 * @param statusAttachable This status will be assigned to it.
+	 */
+	public <T extends StatusAttachable> void assign(T statusAttachable) {
+		getCore(statusAttachable).getMutableStore().set(this);
+	}
+}
diff --git a/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/Domain.java b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/Domain.java
new file mode 100644
index 0000000..f31fcdd
--- /dev/null
+++ b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/Domain.java
@@ -0,0 +1,34 @@
+/********************************************************************************
+ * Copyright (c) 2015-2019 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+package org.eclipse.mdm.api.dflt.model;
+
+import org.eclipse.mdm.api.base.adapter.Core;
+import org.eclipse.mdm.api.base.model.BaseEntity;
+import org.eclipse.mdm.api.base.model.Describable;
+
+public class Domain extends BaseEntity implements Describable {
+
+	// ======================================================================
+	// Constructors
+	// ======================================================================
+
+	/**
+	 * Constructor.
+	 *
+	 * @param core The {@link Core}.
+	 */
+	Domain(Core core) {
+		super(core);
+	}
+}
diff --git a/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/EntityFactory.java b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/EntityFactory.java
new file mode 100644
index 0000000..d18d760
--- /dev/null
+++ b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/EntityFactory.java
@@ -0,0 +1,1244 @@
+/********************************************************************************
+ * Copyright (c) 2015-2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+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
+	// ======================================================================
+
+	/**
+	 * Creates a new {@link Role}.
+	 *
+	 * @param name Name of the created {@code Role}.
+	 * @return The created {@code Role} is returned.
+	 */
+	public Role createRole(String name) {
+		Role role = new Role(createCore(Role.class));
+
+		// properties
+		role.setName(name);
+
+		return role;
+	}
+
+	/**
+	 * 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}.
+	 *
+	 * @param name Name of the created {@code Test}.
+	 * @param pool The parent {@code Pool}.
+	 * @return The created {@code Test} is returned.
+	 */
+	public Test createTest(String name, Pool pool) {
+		return createTest(name, pool, (Status) null);
+	}
+
+	/**
+	 * 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) {
+		return createContextRoot(Arrays.asList(measurement), templateRoot);
+	}
+
+	/**
+	 * Creates a new {@link ContextRoot} for given {@link List} if
+	 * {@link Measurement}s using given {@link TemplateRoot}. If List is null or
+	 * empty context root is created with no relations.
+	 *
+	 * @param measurements 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(List<Measurement> measurements, TemplateRoot templateRoot) {
+		ContextRoot contextRoot = createContextRoot(templateRoot);
+
+		// relations
+		if (measurements != null && !measurements.isEmpty()) {
+			measurements.forEach(m -> getCore(m).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;
+	}
+
+	/**
+	 * Creates a new {@link Classification} for given {@link Domain},
+	 * {@link ProjectDomain} and {@link Status}.
+	 * 
+	 * @param domain        The {@link Domain} for the {@link Classification}
+	 * @param projectDomain The {@link ProjectDomain} for the {@link Classification}
+	 * @param status        The {@link Status} for the {@link Classification}
+	 * @return The created {@link Classification} is returned.
+	 */
+	public Classification createClassification(Domain domain, ProjectDomain projectDomain, Status status) {
+		String name = String.format("ProjDomainId_%s.DomainId_%s.StatusId_%s", projectDomain.getID(), domain.getID(),
+				status.getID());
+		return createClassification(name, status, projectDomain, domain);
+	}
+
+	/**
+	 * Creates a new {@link Classification} for given {@link Domain},
+	 * {@link ProjectDomain} and {@link Status}.
+	 * 
+	 * @param name          The name for the {@link Classification}
+	 * @param status        The {@link Status} for the {@link Classification}
+	 * @param projectDomain The {@link ProjectDomain} for the {@link Classification}
+	 * @param domain        The {@link Domain} for the {@link Classification}
+	 * @return The created {@link Classification} is returned.
+	 */
+	public Classification createClassification(String name, Status status, ProjectDomain projectDomain, Domain domain) {
+		Classification classification = new Classification(createCore(Classification.class));
+
+		getMutableStore(classification).set(status);
+		getMutableStore(classification).set(projectDomain);
+		getMutableStore(classification).set(domain);
+
+		// properties
+		classification.setName(name);
+
+		return classification;
+	}
+
+	/**
+	 * Creates a new {@link ProjectDomain} with given name.
+	 * 
+	 * @param name Name of the {@link ProjectDomain}
+	 * @return The created {@link ProjectDomain} is returned.
+	 */
+	public ProjectDomain createProjectDomain(String name) {
+		ProjectDomain projectDomain = new ProjectDomain(createCore(ProjectDomain.class));
+		// properties
+		projectDomain.setName(name);
+		return projectDomain;
+	}
+
+	/**
+	 * Creates a new {@link Domain} with given name.
+	 * 
+	 * @param name Name of the {@link Domain}
+	 * @return The created {@link Domain} is returned.
+	 */
+	public Domain createDomain(String name) {
+		Domain domain = new Domain(createCore(Domain.class));
+
+		// properties
+		domain.setName(name);
+		return domain;
+	}
+
+	// ======================================================================
+	// 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} using given name,
+	 * {@link TemplateTest} and {@link Classification}.
+	 * 
+	 * @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.
+	 * @param classification The {@link Classification} for the created
+	 *                       {@link Test}.
+	 * @param withTestSteps  If true, {@link TestStep}s are automatically created
+	 *                       based on configured {@link TemplateTestStepUsage}.
+	 * @return The created {@code Test} is returned.
+	 */
+	public Test createTest(String name, Pool pool, TemplateTest templateTest, Classification classification,
+			boolean withTestSteps) {
+		// TODO
+		Test test = createTest(name, pool);
+
+		// relations
+		if (templateTest != null) {
+			getCore(test).getMutableStore().set(templateTest);
+		}
+		getCore(test).getMutableStore().set(classification);
+
+		if (withTestSteps && templateTest != null) {
+			// 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, templateTestStep, classification);
+					});
+		}
+
+		return test;
+	}
+
+	/**
+	 * Creates a new {@link TestStep} for given {@link Test} using given
+	 * {@link TemplateTestStep} and {@link Classification}.
+	 * 
+	 * @param test             The parent {@code Test}.
+	 * @param templateTestStep The template the returned {@code TestStep} will be
+	 *                         derived from.
+	 * @param classification   The {@link Classification} for the created
+	 *                         {@link TestStep}.
+	 * @return The created {@code TestStep} is returned.
+	 */
+	public TestStep createTestStep(Test test, TemplateTestStep templateTestStep, Classification classification) {
+		TestStep testStep = createTestStep(test, templateTestStep);
+		getCore(testStep).getMutableStore().set(classification);
+		return testStep;
+	}
+
+	/**
+	 * Creates a new {@link TestStep} for given {@link Test} using given
+	 * {@link TemplateTestStep} and {@link Classification}.
+	 * 
+	 * @param name           Name of the created {@code TestStep}.
+	 * @param test           The parent {@code Test}.
+	 * @param classification The {@link Classification} for the created
+	 *                       {@link TestStep}.
+	 * @return The created {@code TestStep} is returned.
+	 */
+	public TestStep createTestStep(String name, Test test, Classification classification) {
+		TestStep testStep = createTestStep(name, test);
+		getCore(testStep).getMutableStore().set(classification);
+		return testStep;
+	}
+
+	/**
+	 * Creates a new {@link TestStep} for given {@link Test} using given name,
+	 * {@link TemplateTestStep} and {@link Classification}.
+	 * 
+	 * @param name             Name of the created {@code TestStep}.
+	 * @param test             The parent {@code Test}.
+	 * @param templateTestStep The template the returned {@code TestStep} will be
+	 *                         derived from.
+	 * @param classification   The {@link Classification} for the created
+	 *                         {@link TestStep}.
+	 * @return The created {@code TestStep} is returned.
+	 */
+	public TestStep createTestStep(String name, Test test, TemplateTestStep templateTestStep,
+			Classification classification) {
+		TestStep testStep = createTestStep(test, templateTestStep);
+		getCore(testStep).getMutableStore().set(classification);
+		testStep.setName(name);
+		return testStep;
+	}
+
+	/**
+	 * Create a new {@link ExtSystem}
+	 * @param name The name of the external system
+	 * @return
+	 */
+	public ExtSystem createExtSystem(String name) {
+		ExtSystem extSystem = new ExtSystem(createCore(ExtSystem.class));
+		extSystem.setName(name);
+		return extSystem;
+	}
+
+	/**
+	 * Create a new {@link ExtSystemAttribute}
+	 * @param name        The name of the external system attribute
+	 * @param extSystem   The parent {@link ExtSystem}
+	 * @return
+	 */
+	public ExtSystemAttribute createExtSystemAttribute(String name, ExtSystem extSystem) {
+		ExtSystemAttribute extSystemAttribute = new ExtSystemAttribute(createCore(ExtSystemAttribute.class));
+		getCore(extSystemAttribute).getPermanentStore().set(extSystem);
+		getCore(extSystem).getChildrenStore().add(extSystemAttribute);
+		extSystemAttribute.setName(name);
+		return extSystemAttribute;
+	}
+
+	/**
+	 * Create a new {@link MDMAttribute}
+	 * @param name                The name of the mdm attribute
+	 * @param extSystemAttribute  The parent {@link ExtSystemAttribute}
+	 * @return
+	 */
+	public MDMAttribute createMDMAttribute(String name, ExtSystemAttribute extSystemAttribute) {
+		MDMAttribute mdmAttribute = new MDMAttribute(createCore(MDMAttribute.class));
+		getCore(mdmAttribute).getPermanentStore().set(extSystemAttribute);
+		getCore(extSystemAttribute).getChildrenStore().add(mdmAttribute);
+		mdmAttribute.setName(name);
+		String[] values = name.split("\\.");
+		if(values.length == 3) {
+			mdmAttribute.setComponentType(values[0]);
+			mdmAttribute.setComponentName(values[1]);
+			mdmAttribute.setAttributeName(values[2]);
+		}
+		return mdmAttribute;
+	}
+
+	/**
+	 * Creates a new {@link TestStep} for given {@link Test} using given
+	 * {@link TemplateTestStep} and {@link Classification}. Doesn't create context
+	 * roots
+	 * 
+	 * @param test             The parent {@code Test}.
+	 * @param templateTestStep The template the returned {@code TestStep} will be
+	 *                         derived from.
+	 * @param classification   The {@link Classification} for the created
+	 *                         {@link TestStep}.
+	 * @return The created {@code TestStep} is returned.
+	 */
+	public TestStep createTestStepWithOutContextRoots(Test test, TemplateTestStep templateTestStep,
+			Classification classification) {
+		TestStep testStep = createTestStepWithOutContextRoots(test, templateTestStep);
+		getCore(testStep).getMutableStore().set(classification);
+		return testStep;
+	}
+
+	/**
+	 * Creates a new {@link TestStep} for given {@link Test} using given
+	 * {@link TemplateTestStep}. Doesn't create context roots
+	 *
+	 * @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.
+	 */
+	public TestStep createTestStepWithOutContextRoots(Test test, TemplateTestStep templateTestStep) {
+		return createTestStepWithOutContextRoots(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 createTestStepWithOutContextRoots(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 not part of the test template.");
+		}
+
+		TestStep testStep = createTestStep(templateTestStep.getName(), test, status);
+
+		// relations
+		getCore(testStep).getMutableStore().set(templateTestStep);
+
+		return testStep;
+	}
+
+	/**
+	 * 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);
+
+		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.
+	 */
+	public 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) {
+
+		TestStep testStep = createTestStepWithOutContextRoots(test, status, 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
diff --git a/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/ExtSystem.java b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/ExtSystem.java
new file mode 100644
index 0000000..a6c45b2
--- /dev/null
+++ b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/ExtSystem.java
@@ -0,0 +1,56 @@
+/********************************************************************************
+ * Copyright (c) 2015-2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+package org.eclipse.mdm.api.dflt.model;
+
+import java.util.List;
+
+import org.eclipse.mdm.api.base.adapter.Core;
+import org.eclipse.mdm.api.base.model.BaseEntity;
+import org.eclipse.mdm.api.base.model.Deletable;
+import org.eclipse.mdm.api.base.model.Describable;
+
+/**
+ * Implementation of an external system entity type. An external system
+ * attribute contains several mdm attributes.
+ *
+ * @author Juergen Kleck, Peak Solution GmbH
+ *
+ */
+public class ExtSystem extends BaseEntity implements Describable, Deletable {
+
+	/**
+	 * Constructor.
+	 *
+	 * @param core The {@link Core}.
+	 */
+	protected ExtSystem(Core core) {
+		super(core);
+	}
+
+	public List<ExtSystemAttribute> getAttributes() {
+		return getExtSystemAttributes();
+	}
+
+	/**
+	 * Returns all available {@link ExtSystemAttribute}s related to this external
+	 * system.
+	 *
+	 * @return The returned {@code List} is unmodifiable.
+	 */
+	public List<ExtSystemAttribute> getExtSystemAttributes() {
+		return getCore().getChildrenStore().get(ExtSystemAttribute.class);
+	}
+
+}
diff --git a/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/ExtSystemAttribute.java b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/ExtSystemAttribute.java
new file mode 100644
index 0000000..806ba57
--- /dev/null
+++ b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/ExtSystemAttribute.java
@@ -0,0 +1,56 @@
+/********************************************************************************
+ * Copyright (c) 2015-2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+package org.eclipse.mdm.api.dflt.model;
+
+import java.util.List;
+
+import org.eclipse.mdm.api.base.adapter.Core;
+import org.eclipse.mdm.api.base.model.BaseEntity;
+import org.eclipse.mdm.api.base.model.Deletable;
+import org.eclipse.mdm.api.base.model.Describable;
+
+/**
+ * Implementation of an external system attribute entity type. An external
+ * system attribute contains several mdm attributes.
+ *
+ * @author Juergen Kleck, Peak Solution GmbH
+ *
+ */
+public class ExtSystemAttribute extends BaseEntity implements Describable, Deletable {
+
+	/**
+	 * Constructor.
+	 *
+	 * @param core The {@link Core}.
+	 */
+	protected ExtSystemAttribute(Core core) {
+		super(core);
+	}
+
+	public List<MDMAttribute> getAttributes() {
+		return getMDMAttributes();
+	}
+
+	/**
+	 * Returns all available {@link MDMAttribute}s related to this external system
+	 * attribute.
+	 *
+	 * @return The returned {@code List} is unmodifiable.
+	 */
+	public List<MDMAttribute> getMDMAttributes() {
+		return getCore().getChildrenStore().get(MDMAttribute.class);
+	}
+
+}
diff --git a/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/MDMAttribute.java b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/MDMAttribute.java
new file mode 100644
index 0000000..85b049d
--- /dev/null
+++ b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/MDMAttribute.java
@@ -0,0 +1,98 @@
+/********************************************************************************
+ * Copyright (c) 2015-2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+package org.eclipse.mdm.api.dflt.model;
+
+import org.eclipse.mdm.api.base.adapter.Core;
+import org.eclipse.mdm.api.base.model.BaseEntity;
+import org.eclipse.mdm.api.base.model.Deletable;
+import org.eclipse.mdm.api.base.model.Describable;
+
+/**
+ * Implementation of an external system entity type. An external system
+ * attribute contains several mdm attributes.
+ *
+ * @author Juergen Kleck, Peak Solution GmbH
+ *
+ */
+public class MDMAttribute extends BaseEntity implements Describable, Deletable {
+
+	public static final String ATTR_COMPONENT_TYPE = "CompType";
+	public static final String ATTR_COMPONENT_NAME = "CompName";
+	public static final String ATTR_ATTRIBUTE_NAME = "AttrName";
+
+	/**
+	 * Constructor.
+	 *
+	 * @param core The {@link Core}.
+	 */
+	protected MDMAttribute(Core core) {
+		super(core);
+	}
+
+	/**
+	 * Returns the component type for this attribute
+	 *
+	 * @return Returns the component type
+	 */
+	public String getComponentType() {
+		return getValue(ATTR_COMPONENT_TYPE).extract();
+	}
+
+	/**
+	 * Sets the component type for this attribute
+	 *
+	 * @param compType The component type
+	 */
+	public void setComponentType(String compType) {
+		getValue(ATTR_COMPONENT_TYPE).set(compType);
+	}
+
+	/**
+	 * Returns the component name for this attribute
+	 *
+	 * @return Returns the component name
+	 */
+	public String getComponentName() {
+		return getValue(ATTR_COMPONENT_NAME).extract();
+	}
+
+	/**
+	 * Sets the component name for this attribute
+	 *
+	 * @param compName The component name
+	 */
+	public void setComponentName(String compName) {
+		getValue(ATTR_COMPONENT_NAME).set(compName);
+	}
+
+	/**
+	 * Returns the attribute name for this attribute
+	 *
+	 * @return Returns the attribute name
+	 */
+	public String getAttributeName() {
+		return getValue(ATTR_ATTRIBUTE_NAME).extract();
+	}
+
+	/**
+	 * Sets the attribute name for this attribute
+	 *
+	 * @param attrName The attribute name
+	 */
+	public void setAttributeName(String attrName) {
+		getValue(ATTR_ATTRIBUTE_NAME).set(attrName);
+	}
+
+}
diff --git a/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/Pool.java b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/Pool.java
new file mode 100644
index 0000000..bac6ce7
--- /dev/null
+++ b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/Pool.java
@@ -0,0 +1,61 @@
+/********************************************************************************
+ * Copyright (c) 2015-2019 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+package org.eclipse.mdm.api.dflt.model;
+
+import org.eclipse.mdm.api.base.adapter.Core;
+import org.eclipse.mdm.api.base.model.BaseEntity;
+import org.eclipse.mdm.api.base.model.Deletable;
+import org.eclipse.mdm.api.base.model.Test;
+
+/**
+ * Implementation of the pool entity type. The pool entity is used to establish
+ * a further navigation structure through the stored measurement data. Its name
+ * may be freely chosen but has to to be unique. A project contains {@link Test}
+ * entities as its children.
+ *
+ * @since 1.0.0
+ * @author Viktor Stoehr, Gigatronik Ingolstadt GmbH
+ * @see Project
+ * @see Test
+ */
+public class Pool extends BaseEntity implements Deletable {
+
+	// ======================================================================
+	// Class variables
+	// ======================================================================
+
+	/**
+	 * The {@link Project} parent type.
+	 */
+	public static final Class<Project> PARENT_TYPE_PROJECT = Project.class;
+
+	/**
+	 * The {@link Test} child type.
+	 */
+	public static final Class<Test> CHILD_TYPE_TEST = Test.class;
+
+	// ======================================================================
+	// Constructors
+	// ======================================================================
+
+	/**
+	 * Constructor.
+	 *
+	 * @param core The {@link Core}.
+	 */
+	Pool(Core core) {
+		super(core);
+	}
+
+}
diff --git a/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/Project.java b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/Project.java
new file mode 100644
index 0000000..2c71b4d
--- /dev/null
+++ b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/Project.java
@@ -0,0 +1,53 @@
+/********************************************************************************
+ * Copyright (c) 2015-2019 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+package org.eclipse.mdm.api.dflt.model;
+
+import org.eclipse.mdm.api.base.adapter.Core;
+import org.eclipse.mdm.api.base.model.BaseEntity;
+import org.eclipse.mdm.api.base.model.Deletable;
+
+/**
+ * Implementation of the project entity type. The project is the top level of
+ * stored measurement data. Its name may be freely chosen but has to to be
+ * unique. A project contains {@link Pool} entities as its children.
+ *
+ * @since 1.0.0
+ * @author Viktor Stoehr, Gigatronik Ingolstadt GmbH
+ * @see Pool
+ */
+public class Project extends BaseEntity implements Deletable {
+
+	// ======================================================================
+	// Class variables
+	// ======================================================================
+
+	/**
+	 * The {@link Pool} child type.
+	 */
+	public static final Class<Pool> CHILD_TYPE_POOL = Pool.class;
+
+	// ======================================================================
+	// Constructors
+	// ======================================================================
+
+	/**
+	 * Constructor.
+	 *
+	 * @param core The {@link Core}.
+	 */
+	Project(Core core) {
+		super(core);
+	}
+
+}
diff --git a/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/ProjectDomain.java b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/ProjectDomain.java
new file mode 100644
index 0000000..dae7b14
--- /dev/null
+++ b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/ProjectDomain.java
@@ -0,0 +1,35 @@
+/********************************************************************************
+ * Copyright (c) 2015-2019 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+package org.eclipse.mdm.api.dflt.model;
+
+import org.eclipse.mdm.api.base.adapter.Core;
+import org.eclipse.mdm.api.base.model.BaseEntity;
+import org.eclipse.mdm.api.base.model.Describable;
+
+public class ProjectDomain extends BaseEntity implements Describable {
+
+	// ======================================================================
+	// Constructors
+	// ======================================================================
+
+	/**
+	 * Constructor.
+	 *
+	 * @param core The {@link Core}.
+	 */
+	ProjectDomain(Core core) {
+		super(core);
+	}
+}
diff --git a/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/Role.java b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/Role.java
new file mode 100644
index 0000000..de12617
--- /dev/null
+++ b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/Role.java
@@ -0,0 +1,55 @@
+/********************************************************************************
+ * Copyright (c) 2015-2019 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+package org.eclipse.mdm.api.dflt.model;
+
+import org.eclipse.mdm.api.base.adapter.Core;
+import org.eclipse.mdm.api.base.model.BaseEntity;
+import org.eclipse.mdm.api.base.model.Deletable;
+import org.eclipse.mdm.api.base.model.Describable;
+import org.eclipse.mdm.api.base.model.User;
+
+/**
+ * Implementation of the role entity type. Each role can contain multiple
+ * {@link User} and each {@link User} can be assigned multiple {@link Role}s.
+ */
+public class Role extends BaseEntity implements Deletable, Describable {
+
+	public static final String ATTR_SUPERUSER_FLAG = "SuperuserFlag";
+	public static final String REL_GROUPS2USERS = "groups2users";
+
+	/**
+	 * Constructor.
+	 *
+	 * @param core The {@link Core}.
+	 */
+	Role(Core core) {
+		super(core);
+		getValue(ATTR_SUPERUSER_FLAG).set((short) 0);
+	}
+
+	/**
+	 * @param user User to add
+	 */
+	public void addUser(User user) {
+		getCore().getNtoMStore().add(REL_GROUPS2USERS, user);
+	}
+
+	/**
+	 * @param user {@link User} to remove
+	 */
+	public void removeUser(User user) {
+		getCore().getNtoMStore().remove(REL_GROUPS2USERS, user);
+	}
+}
diff --git a/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/Status.java b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/Status.java
new file mode 100644
index 0000000..702ad32
--- /dev/null
+++ b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/Status.java
@@ -0,0 +1,94 @@
+/********************************************************************************
+ * Copyright (c) 2015-2019 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+package org.eclipse.mdm.api.dflt.model;
+
+import java.util.List;
+import java.util.Optional;
+
+import org.eclipse.mdm.api.base.adapter.Core;
+import org.eclipse.mdm.api.base.model.BaseEntity;
+import org.eclipse.mdm.api.base.model.Describable;
+import org.eclipse.mdm.api.base.model.StatusAttachable;
+import org.eclipse.mdm.api.base.model.Test;
+import org.eclipse.mdm.api.base.model.TestStep;
+import org.eclipse.mdm.api.base.query.DataAccessException;
+
+/**
+ * Implementation of the status entity type. A status may be attached to
+ * {@link StatusAttachable} entities like {@link Test} or {@link TestStep} to
+ * indicate they have a state in a complete workflow.
+ *
+ * @since 1.0.0
+ * @author Viktor Stoehr, Gigatronik Ingolstadt GmbH
+ */
+public class Status extends BaseEntity implements Describable {
+
+	// ======================================================================
+	// Constructors
+	// ======================================================================
+
+	/**
+	 * Constructor.
+	 *
+	 * @param core The {@link Core}.
+	 */
+	Status(Core core) {
+		super(core);
+	}
+
+	// ======================================================================
+	// Public methods
+	// ======================================================================
+
+	/**
+	 * Assigns this status to given {@link StatusAttachable}s.
+	 *
+	 * @param <T>               The status attachable type.
+	 * @param statusAttachables This status will be assigned to all of them.
+	 */
+	public <T extends StatusAttachable> void assign(List<T> statusAttachables) {
+		statusAttachables.forEach(this::assign);
+	}
+
+	/**
+	 * Assigns this status to given {@link StatusAttachable}.
+	 *
+	 * @param <T>              The status attachable type.
+	 * @param statusAttachable This status will be assigned to it.
+	 */
+	public <T extends StatusAttachable> void assign(T statusAttachable) {
+		Classification classification = getCore(statusAttachable).getMutableStore().get(Classification.class);
+		if (classification == null) {
+			throw new DataAccessException("Mandatory element classification not found!");
+		}
+
+		getCore(classification).getMutableStore().set(this);
+	}
+
+	/**
+	 * Returns the {@link Status} attached to given {@link StatusAttachable}.
+	 *
+	 * @param statusAttachable The {@code StatusAttachable}.
+	 * @return Optional is empty if no {@code Status} is attached.
+	 */
+	public static Optional<Status> of(StatusAttachable statusAttachable) {
+		Classification classification = getCore(statusAttachable).getMutableStore().get(Classification.class);
+		if (classification == null) {
+			return Optional.empty();
+		}
+		return Optional.ofNullable(getCore(classification).getMutableStore().get(Status.class));
+	}
+
+}
diff --git a/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/SystemParameter.java b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/SystemParameter.java
new file mode 100644
index 0000000..310a654
--- /dev/null
+++ b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/SystemParameter.java
@@ -0,0 +1,28 @@
+/*******************************************************************************

+ * Copyright (c) 2020 Contributors to the Eclipse Foundation

+ *

+ * See the NOTICE file(s) distributed with this work for additional

+ * information regarding copyright ownership.

+ *

+ * This program and the accompanying materials are made available under the

+ * terms of the Eclipse Public License v. 2.0 which is available at

+ * http://www.eclipse.org/legal/epl-2.0.

+ *

+ * SPDX-License-Identifier: EPL-2.0

+ *******************************************************************************/

+package org.eclipse.mdm.api.dflt.model;

+

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

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

+

+/**

+ * @author akn

+ *

+ */

+public class SystemParameter extends BaseEntity {

+

+	SystemParameter(Core core) {

+		super(core);

+	}

+

+}

diff --git a/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/TemplateAttribute.java b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/TemplateAttribute.java
new file mode 100644
index 0000000..998862b
--- /dev/null
+++ b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/TemplateAttribute.java
@@ -0,0 +1,408 @@
+/********************************************************************************
+ * Copyright (c) 2015-2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+package org.eclipse.mdm.api.dflt.model;
+
+import java.io.IOException;
+import java.lang.reflect.Array;
+import java.nio.file.Paths;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+import java.util.stream.Stream;
+
+import org.eclipse.mdm.api.base.adapter.Core;
+import org.eclipse.mdm.api.base.model.BaseEntity;
+import org.eclipse.mdm.api.base.model.Deletable;
+import org.eclipse.mdm.api.base.model.DoubleComplex;
+import org.eclipse.mdm.api.base.model.Enumeration;
+import org.eclipse.mdm.api.base.model.FileLink;
+import org.eclipse.mdm.api.base.model.FloatComplex;
+import org.eclipse.mdm.api.base.model.MimeType;
+import org.eclipse.mdm.api.base.model.Value;
+import org.eclipse.mdm.api.base.model.ValueType;
+
+/**
+ * Implementation of the template attribute entity type. A template attribute
+ * adds meta data to a {@link CatalogAttribute} it is associated with. It always
+ * belongs to a {@link TemplateComponent} or a {@link TemplateSensor}. Its name
+ * is the same as the name of the associated {@code CatalogAttribute} and is not
+ * allowed to be modified at all.
+ *
+ * @since 1.0.0
+ * @author Viktor Stoehr, Gigatronik Ingolstadt GmbH
+ * @see TemplateComponent
+ * @see TemplateSensor
+ */
+public class TemplateAttribute extends BaseEntity implements Deletable {
+
+	// ======================================================================
+	// Class variables
+	// ======================================================================
+
+	/**
+	 * This {@code Comparator} compares {@link TemplateAttribute}s by the sort index
+	 * of their corresponding {@link CatalogAttribute} in ascending order.
+	 */
+	public static final Comparator<TemplateAttribute> COMPARATOR = Comparator
+			.comparing(ta -> ta.getCatalogAttribute().getSortIndex());
+
+	/**
+	 * The 'DefaultValue' attribute name.
+	 */
+	public static final String ATTR_DEFAULT_VALUE = "DefaultValue";
+
+	/**
+	 * The 'ValueReadOnly' attribute name.
+	 */
+	public static final String ATTR_VALUE_READONLY = "ValueReadonly";
+
+	/**
+	 * The 'Optional' attribute name.
+	 */
+	public static final String ATTR_OPTIONAL = "Obligatory";
+
+	private static final Map<ValueType<?>, Function<String, Object>> VALUETYPE_FUNCTION_MAP = new HashMap<>();
+
+	static {
+		VALUETYPE_FUNCTION_MAP.put(ValueType.STRING, v -> v);
+		VALUETYPE_FUNCTION_MAP.put(ValueType.DATE, v -> LocalDateTime.parse(v, Value.LOCAL_DATE_TIME_FORMATTER));
+		VALUETYPE_FUNCTION_MAP.put(ValueType.BOOLEAN, Boolean::valueOf);
+		VALUETYPE_FUNCTION_MAP.put(ValueType.BYTE, Byte::valueOf);
+		VALUETYPE_FUNCTION_MAP.put(ValueType.SHORT, Short::valueOf);
+		VALUETYPE_FUNCTION_MAP.put(ValueType.INTEGER, Integer::valueOf);
+		VALUETYPE_FUNCTION_MAP.put(ValueType.LONG, Long::valueOf);
+		VALUETYPE_FUNCTION_MAP.put(ValueType.FLOAT, Float::valueOf);
+		VALUETYPE_FUNCTION_MAP.put(ValueType.DOUBLE, Double::valueOf);
+		VALUETYPE_FUNCTION_MAP.put(ValueType.FLOAT_COMPLEX, FloatComplex::valueOf);
+		VALUETYPE_FUNCTION_MAP.put(ValueType.DOUBLE_COMPLEX, DoubleComplex::valueOf);
+	}
+
+	// ======================================================================
+	// Constructors
+	// ======================================================================
+
+	/**
+	 * Constructor.
+	 *
+	 * @param core The {@link Core}.
+	 */
+	TemplateAttribute(Core core) {
+		super(core);
+	}
+
+	// ======================================================================
+	// Public methods
+	// ======================================================================
+
+	/**
+	 * Returns the default {@link Value} of this template attribute.
+	 *
+	 * @return The default {@code Value} is returned.
+	 */
+	@SuppressWarnings({ "rawtypes" })
+	public Value getDefaultValue() {
+		ValueType valueType = getCatalogAttribute().getValueType();
+		Value defaultValue = getValue(ATTR_DEFAULT_VALUE);
+		boolean isValid = defaultValue.isValid();
+		String value = defaultValue.extract();
+		if (valueType.isEnumerationType()) {
+			Enumeration enumObject = getCatalogAttribute().getEnumerationObject();
+			return valueType.create(getName(), "", isValid, isValid ? enumObject.valueOf(value) : null,
+					enumObject.getName());
+		} else {
+			return valueType.create(getName(), isValid ? parse(value, valueType) : null);
+		}
+	}
+
+	/**
+	 * Sets a new default value for this template attribute. Given input will be
+	 * stored in its {@link String} representation.
+	 *
+	 * @param input The new default value.
+	 */
+	public void setDefaultValue(Object input) {
+		if (input == null) {
+			getValue(ATTR_DEFAULT_VALUE).set(null);
+			return;
+		}
+
+		ValueType<?> valueType = getCatalogAttribute().getValueType();
+		boolean sequence = valueType.isSequence();
+
+		// if this passes -> input is valid
+		Value value = valueType.create("notRelevant", input);
+
+		String stringValue;
+		if (valueType.isFileLinkType()) {
+			stringValue = getStringValueForFileLinkType(value, sequence);
+		} else if (valueType.isDateType()) {
+			LocalDateTime[] values = sequence ? value.extract() : new LocalDateTime[] { value.extract() };
+			stringValue = Stream.of(values).map(ldt -> ldt.format(Value.LOCAL_DATE_TIME_FORMATTER))
+					.collect(Collectors.joining(","));
+		} else {
+			if (input.getClass().isArray()) {
+				stringValue = IntStream.range(0, Array.getLength(input)).mapToObj(i -> Array.get(input, i).toString())
+						.collect(Collectors.joining(","));
+			} else {
+				stringValue = value.extract().toString();
+			}
+		}
+
+		getValue(ATTR_DEFAULT_VALUE).set(stringValue);
+	}
+
+	/**
+	 * Returns the value read only flag of this template attribute.
+	 *
+	 * @return Returns {@code true} if it is not allowed to modify {@link Value}s
+	 *         derived from this template attribute.
+	 */
+	public Boolean isValueReadOnly() {
+		return getValue(ATTR_VALUE_READONLY).extract();
+	}
+
+	/**
+	 * Sets a new value read only flag for this template attribute.
+	 *
+	 * @param valueReadOnly The new value read only flag.
+	 */
+	public void setValueReadOnly(Boolean valueReadOnly) {
+		getValue(ATTR_VALUE_READONLY).set(valueReadOnly);
+	}
+
+	/**
+	 * Returns the optional flag of this template attribute.
+	 *
+	 * @return Returns {@code true} if it is allowed to omit a {@link Value} derived
+	 *         from this template attribute.
+	 */
+	public Boolean isOptional() {
+		boolean mandatory = getValue(ATTR_OPTIONAL).extract();
+		return mandatory ? Boolean.FALSE : Boolean.TRUE;
+	}
+
+	/**
+	 * Sets a new optional flag for this template attribute.
+	 *
+	 * @param optional The new optional flag.
+	 */
+	public void setOptional(Boolean optional) {
+		getValue(ATTR_OPTIONAL).set(optional ? Boolean.FALSE : Boolean.TRUE);
+	}
+
+	/**
+	 * Returns the {@link CatalogAttribute} this template attribute is associated
+	 * with.
+	 *
+	 * @return The associated {@code CatalogAttribute} is returned.
+	 */
+	public CatalogAttribute getCatalogAttribute() {
+		return getCore().getMutableStore().get(CatalogAttribute.class);
+	}
+
+	/**
+	 * Returns the {@link TemplateRoot} this template attribute belongs to.
+	 *
+	 * @return The {@code TemplateRoot} is returned.
+	 */
+	public TemplateRoot getTemplateRoot() {
+		Optional<TemplateComponent> templateComponent = getTemplateComponent();
+		Optional<TemplateSensor> templateSensor = getTemplateSensor();
+		if (templateComponent.isPresent()) {
+			return templateComponent.get().getTemplateRoot();
+		} else if (templateSensor.isPresent()) {
+			return templateSensor.get().getTemplateRoot();
+		} else {
+			throw new IllegalStateException("Parent entity is unknown.");
+		}
+	}
+
+	/**
+	 * Returns the parent {@link TemplateComponent} of this template attribute.
+	 *
+	 * @return {@code Optional} is empty if a {@link TemplateSensor} is parent of
+	 *         this template attribute.
+	 * @see #getTemplateSensor()
+	 */
+	public Optional<TemplateComponent> getTemplateComponent() {
+		return Optional.ofNullable(getCore().getPermanentStore().get(TemplateComponent.class));
+	}
+
+	/**
+	 * Returns the parent {@link TemplateSensor} of this template attribute.
+	 *
+	 * @return {@code Optional} is empty if a {@link TemplateComponent} is parent of
+	 *         this template attribute.
+	 * @see #getTemplateComponent()
+	 */
+	public Optional<TemplateSensor> getTemplateSensor() {
+		return Optional.ofNullable(getCore().getPermanentStore().get(TemplateSensor.class));
+	}
+
+	// ======================================================================
+	// Private methods
+	// ======================================================================
+
+	/**
+	 * Parses given {@code String} to the corresponding type of given
+	 * {@link ValueType}.
+	 *
+	 * @param value     The {@code String} value.
+	 * @param valueType Used to resolve the corresponding converter.
+	 * @return The parsed object is returned.
+	 */
+	private static Object parse(String value, ValueType<?> valueType) {
+		if (valueType.isFileLinkType()) {
+			Pattern pattern = Pattern.compile("([^,].*?)\\[(.*?),(.*?)\\]");
+			Matcher matcher = pattern.matcher(value);
+			List<FileLink> fileLinks = new ArrayList<>();
+			while (matcher.find()) {
+				fileLinks.add(FileLinkParser.parse(matcher.group()));
+			}
+
+			return valueType.isSequence() ? fileLinks.toArray(new FileLink[fileLinks.size()]) : fileLinks.get(0);
+		} else {
+			Function<String, Object> converter = getParser(valueType);
+			if (valueType.isSequence()) {
+				List<Object> values = Stream.of(value.split(",")).map(converter).collect(Collectors.toList());
+				Object array = Array.newInstance(valueType.getValueClass().getComponentType(), values.size());
+
+				if (valueType.getValueClass().getComponentType().isPrimitive()) {
+					IntStream.range(0, values.size()).forEach(i -> Array.set(array, i, values.get(i)));
+				} else {
+					values.toArray((Object[]) array);
+				}
+
+				return array;
+			} else {
+				return converter.apply(value);
+			}
+		}
+	}
+
+	/**
+	 * Returns the {@code String} conversion function for given {@link ValueType}.
+	 *
+	 * @param valueType Used as identifier.
+	 * @return The {@code String} conversion {@code Function} is returned.
+	 * @throws IllegalArgumentException Thrown if a corresponding {@code String} is
+	 *                                  not supported.
+	 */
+	private static Function<String, Object> getParser(ValueType<?> valueType) {
+		Function<String, Object> converter = VALUETYPE_FUNCTION_MAP.get(valueType);
+		if (converter == null) {
+			throw new IllegalArgumentException("String conversion for value type '" + valueType + "' not supported.");
+		}
+		return converter;
+	}
+
+	// ======================================================================
+	// Inner classes
+	// ======================================================================
+
+	/**
+	 * Utility class restore a {@link FileLink} from given {@code String}.
+	 */
+	private static final class FileLinkParser {
+
+		// ======================================================================
+		// Class variables
+		// ======================================================================
+
+		// markers
+		private static final String NO_DESC_MARKER = "NO_DESC#";
+		private static final String LOCAL_MARKER = "LOCALPATH#";
+
+		// pattern group names
+		private static final String DESCRIPTION = "description";
+		private static final String MIMETYPE = "mimetype";
+		private static final String PATH = "path";
+
+		// pattern
+		private static final Pattern FILE_LINK_PATTERN = Pattern
+				.compile("(?<" + DESCRIPTION + ">.*?)\\[(?<" + MIMETYPE + ">.*?),(?<" + PATH + ">.*?)\\]");
+
+		// ======================================================================
+		// Public methods
+		// ======================================================================
+
+		/**
+		 * Parses given {@code String} and returns it as {@link FileLink}.
+		 *
+		 * @param value The {@code String} value which will be parsed.
+		 * @return The corresponding {@code FileLink} is returned.
+		 */
+		public static FileLink parse(String value) {
+			Matcher matcher = FILE_LINK_PATTERN.matcher(value);
+			if (!matcher.find()) {
+				throw new IllegalStateException("Unable to restore file link.");
+			}
+			String description = matcher.group(DESCRIPTION);
+			String path = matcher.group(PATH);
+			FileLink fileLink;
+			if (path.startsWith(LOCAL_MARKER)) {
+				try {
+					fileLink = FileLink.newLocal(Paths.get(path.replaceFirst(LOCAL_MARKER, "")));
+				} catch (IOException e) {
+					throw new IllegalStateException("Unable to restore local file link.", e);
+				}
+			} else {
+				fileLink = FileLink.newRemote(path, new MimeType(matcher.group(MIMETYPE)), description);
+			}
+
+			fileLink.setDescription(NO_DESC_MARKER.equals(description) ? null : description);
+			return fileLink;
+		}
+
+	}
+
+	/**
+	 * Get string value for FileLinkType
+	 *
+	 * @param value    The {@code Value} value.
+	 * @param sequence The {@code boolean} sequence.
+	 * @return Return {@code String} string value for FileLinkType
+	 */
+	private String getStringValueForFileLinkType(Value value, boolean sequence) {
+		FileLink[] values = sequence ? value.extract() : new FileLink[] { value.extract() };
+		return Stream.of(values).map(fl -> {
+			StringBuilder sb = new StringBuilder();
+			if (fl.getDescription().isEmpty()) {
+				sb.append(FileLinkParser.NO_DESC_MARKER);
+			} else {
+				sb.append(fl.getDescription());
+			}
+			sb.append('[').append(fl.getMimeType()).append(',');
+			if (fl.isRemote()) {
+				sb.append(fl.getRemotePath());
+			} else if (fl.isLocal()) {
+				sb.append(FileLinkParser.LOCAL_MARKER).append(fl.getLocalStream());
+			} else {
+				throw new IllegalStateException("File link is neither in local nor remote state: " + fl);
+			}
+
+			return sb.append(']');
+		}).collect(Collectors.joining(","));
+	}
+}
diff --git a/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/TemplateComponent.java b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/TemplateComponent.java
new file mode 100644
index 0000000..8caa7d2
--- /dev/null
+++ b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/TemplateComponent.java
@@ -0,0 +1,400 @@
+/********************************************************************************
+ * Copyright (c) 2015-2019 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+package org.eclipse.mdm.api.dflt.model;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+import org.eclipse.mdm.api.base.adapter.Core;
+import org.eclipse.mdm.api.base.model.BaseEntity;
+import org.eclipse.mdm.api.base.model.ContextComponent;
+import org.eclipse.mdm.api.base.model.ContextRoot;
+import org.eclipse.mdm.api.base.model.Deletable;
+import org.eclipse.mdm.api.base.model.Sortable;
+import org.eclipse.mdm.api.base.model.TestStep;
+import org.eclipse.mdm.api.base.model.Value;
+
+/**
+ * Implementation of the template component entity type. A template attribute
+ * adds meta data to a {@link CatalogComponent} it is associated with. It always
+ * belongs to a template root or another template component. Its name has to be
+ * unique within all template components belonging to the same
+ * {@link TemplateRoot}. A template component may define {@link TemplateSensor}s
+ * where each extends a {@link CatalogSensor} provided by the associated {@code
+ * CatalogComponent}. It may define {@link TemplateAttribute}s where each
+ * uniquely extends a {@link CatalogAttribute} provided by the associated
+ * {@code CatalogComponent}.
+ *
+ * @since 1.0.0
+ * @author Viktor Stoehr, Gigatronik Ingolstadt GmbH
+ * @see CatalogComponent
+ * @see TemplateRoot
+ * @see TemplateAttribute
+ * @see TemplateSensor
+ */
+public class TemplateComponent extends BaseEntity implements Deletable, Sortable {
+
+	// ======================================================================
+	// Class variables
+	// ======================================================================
+
+	/**
+	 * The optional flag {@code Predicate}.
+	 */
+	public static final Predicate<TemplateComponent> IS_OPTIONAL = TemplateComponent::isOptional;
+
+	/**
+	 * The mandatory flag {@code Predicate}. This is the inversion of
+	 * {@link #IS_OPTIONAL} {@code Predicate}.
+	 */
+	public static final Predicate<TemplateComponent> IS_MANDATORY = IS_OPTIONAL.negate();
+
+	/**
+	 * The default active flag {@code Predicate}.
+	 */
+	public static final Predicate<TemplateComponent> IS_DEFAULT_ACTIVE = TemplateComponent::isDefaultActive;
+
+	/**
+	 * The series constant flag {@code Predicate}.
+	 */
+	public static final Predicate<TemplateComponent> IS_SERIES_CONSTANT = TemplateComponent::isSeriesConstant;
+
+	/**
+	 * The series variable flag {@code Predicate}. This is the inversion of the
+	 * {@link #IS_SERIES_CONSTANT} {@code Predicate}.
+	 */
+	public static final Predicate<TemplateComponent> IS_SERIES_VARIABLE = IS_SERIES_CONSTANT.negate();
+
+	/**
+	 * The implicit create flag {@code Predicate}. This is an OR combination of
+	 * {@link #IS_DEFAULT_ACTIVE} and {@link #IS_MANDATORY} {@code Predicate}s.
+	 */
+	public static final Predicate<TemplateComponent> IS_IMPLICIT_CREATE = IS_DEFAULT_ACTIVE.or(IS_MANDATORY);
+
+	/**
+	 * The 'TestStepSeriesVariable' attribute name.
+	 */
+	public static final String ATTR_SERIES_CONSTANT = "TestStepSeriesVariable";
+
+	/**
+	 * The 'DefaultActive' attribute name.
+	 */
+	public static final String ATTR_DEFAULT_ACTIVE = "DefaultActive";
+
+	/**
+	 * The 'Optional' attribute name.
+	 */
+	public static final String ATTR_OPTIONAL = "Optional";
+
+	// ======================================================================
+	// Constructors
+	// ======================================================================
+
+	/**
+	 * Constructor.
+	 *
+	 * @param core The {@link Core}.
+	 */
+	TemplateComponent(Core core) {
+		super(core);
+	}
+
+	// ======================================================================
+	// Public methods
+	// ======================================================================
+
+	/**
+	 * Returns the optional flag of this template component.
+	 *
+	 * @return Returns {@code true} if it is allowed to omit a
+	 *         {@link ContextComponent} derived from this template component.
+	 */
+	public Boolean isOptional() {
+		return getValue(ATTR_OPTIONAL).extract();
+	}
+
+	/**
+	 * Sets a new optional flag for this template component.
+	 *
+	 * @param optional The new optional flag.
+	 */
+	public void setOptional(Boolean optional) {
+		getValue(ATTR_OPTIONAL).set(optional);
+	}
+
+	/**
+	 * Returns the default active flag of this template component.
+	 *
+	 * @return Returns {@code true} if a {@link ContextComponent} has to be created
+	 *         automatically each time a new {@link ContextRoot} is derived from the
+	 *         {@link TemplateRoot} this template component belongs to.
+	 */
+	public Boolean isDefaultActive() {
+		return getValue(ATTR_DEFAULT_ACTIVE).extract();
+	}
+
+	/**
+	 * Sets a new default active flag for this template component.
+	 *
+	 * @param defaultActive The new default active flag.
+	 */
+	public void setDefaultActive(Boolean defaultActive) {
+		getValue(ATTR_DEFAULT_ACTIVE).set(defaultActive);
+	}
+
+	/**
+	 * Returns the series constant flag of this template component.
+	 *
+	 * @return Returns {@code true} if the {@link ContextComponent}'s {@link Value}s
+	 *         across {@link TestStep} siblings contain the same values.
+	 */
+	public Boolean isSeriesConstant() {
+		return getValue(ATTR_SERIES_CONSTANT).extract();
+	}
+
+	/**
+	 * Sets a new series constant flag for this template component.
+	 *
+	 * @param seriesConstant The new series constant flag.
+	 */
+	public void setSeriesConstant(Boolean seriesConstant) {
+		getValue(ATTR_SERIES_CONSTANT).set(seriesConstant);
+	}
+
+	/**
+	 * Returns the {@link CatalogComponent} this template component is associated
+	 * with.
+	 *
+	 * @return The associated {@code CatalogComponent} is returned.
+	 */
+	public CatalogComponent getCatalogComponent() {
+		return getCore().getMutableStore().get(CatalogComponent.class);
+	}
+
+	/**
+	 * Returns the {@link TemplateRoot} this template component belongs to.
+	 *
+	 * @return The {@code TemplateRoot} is returned.
+	 */
+	public TemplateRoot getTemplateRoot() {
+		TemplateRoot templateRoot = getCore().getPermanentStore().get(TemplateRoot.class);
+		if (templateRoot == null) {
+			return getParentTemplateComponent()
+					.orElseThrow(() -> new IllegalStateException("Parent entity is unknown.")).getTemplateRoot();
+		}
+
+		return templateRoot;
+	}
+
+	/**
+	 * Returns the parent {@link TemplateComponent} of this template component.
+	 *
+	 * @return {@code Optional} is empty if this template component is an immediate
+	 *         child of the {@link TemplateRoot}.
+	 * @see #getTemplateRoot()
+	 */
+	public Optional<TemplateComponent> getParentTemplateComponent() {
+		return Optional.ofNullable(getCore().getPermanentStore().get(TemplateComponent.class));
+	}
+
+	/**
+	 * Returns the {@link TemplateAttribute} identified by given name.
+	 *
+	 * @param name The name of the {@code TemplateAttribute}.
+	 * @return The {@code Optional} is empty if a {@code TemplateAttribute} with
+	 *         given name does not exist.
+	 */
+	public Optional<TemplateAttribute> getTemplateAttribute(String name) {
+		return getTemplateAttributes().stream().filter(ta -> ta.nameEquals(name)).findAny();
+	}
+
+	/**
+	 * Returns all available {@link TemplateAttribute}s related to this template
+	 * component.
+	 *
+	 * @return The returned {@code List} is unmodifiable.
+	 */
+	public List<TemplateAttribute> getTemplateAttributes() {
+		return getCore().getChildrenStore().get(TemplateAttribute.class);
+	}
+
+	/**
+	 * Removes the {@link TemplateAttribute} identified by given name.
+	 *
+	 * @param name Name of the {@code TemplateAttribute} that has to be removed.
+	 * @return Returns {@code true} if the {@code TemplateAttribute} with given name
+	 *         has been removed.
+	 */
+	public boolean removeTemplateAttribute(String name) {
+		Optional<TemplateAttribute> templateAttribute = getTemplateAttribute(name);
+		if (templateAttribute.isPresent()) {
+			getCore().getChildrenStore().remove(templateAttribute.get());
+			return true;
+		}
+
+		return false;
+	}
+
+	/**
+	 * Returns the {@link TemplateComponent} identified by given name.
+	 *
+	 * <p>
+	 * <b>NOTE:</b> The names of <u>all</u> template components belonging to the
+	 * same {@link TemplateRoot} must have unique names (no matter they are
+	 * immediate children or not). Therefore, if this template component does not
+	 * have an immediate template component with the given name, this lookup request
+	 * is recursively delegated to all of its child template components.
+	 *
+	 * @param name The name of the {@code TemplateComponent}.
+	 * @return The {@code Optional} is empty if a {@code TemplateComponent} with
+	 *         given name does not exist (neither this template component nor one of
+	 *         its children has a template component with given name).
+	 */
+	public Optional<TemplateComponent> getTemplateComponent(String name) {
+		List<TemplateComponent> templateComponents = getTemplateComponents();
+		Optional<TemplateComponent> templateComponent = templateComponents.stream().filter(tc -> tc.nameEquals(name))
+				.findAny();
+		if (templateComponent.isPresent()) {
+			return templateComponent;
+		}
+
+		return templateComponents.stream().map(ct -> ct.getTemplateComponent(name)).filter(Optional::isPresent)
+				.map(Optional::get).findAny();
+	}
+
+	/**
+	 * Returns all immediate {@link TemplateComponent}s related to this template
+	 * component.
+	 *
+	 * @return The returned {@code List} is unmodifiable.
+	 */
+	public List<TemplateComponent> getTemplateComponents() {
+		return getCore().getChildrenStore().get(TemplateComponent.class);
+	}
+
+	/**
+	 * Removes the {@link TemplateComponent} identified by given name.
+	 *
+	 * <p>
+	 * <b>NOTE:</b> The names of <u>all</u> template components belonging to the
+	 * same {@link TemplateRoot} must have unique names (no matter they are
+	 * immediate children or not). Therefore, if this template component does not
+	 * have an immediate template component with the given name, this remove request
+	 * is recursively delegated to all of its child template components.
+	 *
+	 * @param name Name of the {@code TemplateComponent} that has to be removed.
+	 * @return Returns {@code true} if the {@code TemplateComponent} with given name
+	 *         has been removed.
+	 */
+	public boolean removeTemplateComponent(String name) {
+		Optional<TemplateComponent> templateComponent = getTemplateComponent(name);
+		if (templateComponent.isPresent()) {
+			Optional<TemplateComponent> parentTemplateComponent = templateComponent.get().getParentTemplateComponent();
+			if (parentTemplateComponent.isPresent()) {
+				parentTemplateComponent.get().removeTemplateComponent(name);
+			} else {
+				getCore().getChildrenStore().remove(templateComponent.get());
+			}
+			return true;
+		}
+
+		return false;
+	}
+
+	/**
+	 * Returns the {@link TemplateSensor} identified by given name.
+	 *
+	 * @param name The name of the {@code TemplateSensor}.
+	 * @return The {@code Optional} is empty if a {@code TemplateSensor} with given
+	 *         name does not exist.
+	 */
+	public Optional<TemplateSensor> getTemplateSensor(String name) {
+		return getTemplateSensors().stream().filter(ts -> ts.nameEquals(name)).findAny();
+	}
+
+	/**
+	 * Returns all available {@link TemplateSensor}s related to this template
+	 * component.
+	 *
+	 * @return The returned {@code List} is unmodifiable.
+	 */
+	public List<TemplateSensor> getTemplateSensors() {
+		if (getCatalogComponent().getContextType().isTestEquipment()) {
+			return getCore().getChildrenStore().get(TemplateSensor.class);
+		}
+
+		return Collections.emptyList();
+	}
+
+	/**
+	 * Removes the {@link TemplateSensor} identified by given name.
+	 *
+	 * @param name Name of the {@code TemplateSensor} that has to be removed.
+	 * @return Returns {@code true} if the {@code TemplateSensor} with given name
+	 *         has been removed.
+	 */
+	public boolean removeTemplateSensor(String name) {
+		Optional<TemplateSensor> templateSensor = getTemplateSensor(name);
+		if (templateSensor.isPresent()) {
+			getCore().getChildrenStore().remove(templateSensor.get());
+			return true;
+		}
+
+		return false;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public String toString() {
+		StringBuilder sb = new StringBuilder(getClass().getSimpleName()).append('(');
+		sb.append(getValues().values().stream().map(Value::toString).collect(Collectors.joining(", ")));
+
+		List<TemplateAttribute> templateAttributes = getTemplateAttributes();
+		if (!templateAttributes.isEmpty()) {
+			sb.append(", TemplateAttributes = ").append(templateAttributes);
+		}
+
+		List<TemplateSensor> templateSensors = getTemplateSensors();
+		if (!templateSensors.isEmpty()) {
+			sb.append(", TemplateSensors = ").append(templateSensors);
+		}
+
+		List<TemplateComponent> templateComponents = getTemplateComponents();
+		if (!templateComponents.isEmpty()) {
+			sb.append(", TemplateComponents = ").append(templateComponents);
+		}
+
+		return sb.append(')').toString();
+	}
+
+	/**
+	 * Returns the {@link TemplateComponent} the given {@link ContextComponent} is
+	 * derived from.
+	 *
+	 * @param contextComponent The {@code ContextComponent} whose {@code
+	 * 		TemplateComponent} is requested.
+	 * @return {@code Optional} is empty if the given {@code ContextComponent} is
+	 *         not derived from a template, which is data source specific.
+	 */
+	public static Optional<TemplateComponent> of(ContextComponent contextComponent) {
+		return Optional.ofNullable(getCore(contextComponent).getMutableStore().get(TemplateComponent.class));
+	}
+
+}
diff --git a/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/TemplateRoot.java b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/TemplateRoot.java
new file mode 100644
index 0000000..21f04a1
--- /dev/null
+++ b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/TemplateRoot.java
@@ -0,0 +1,187 @@
+/********************************************************************************
+ * Copyright (c) 2015-2019 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+package org.eclipse.mdm.api.dflt.model;
+
+import java.util.List;
+import java.util.Locale;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import org.eclipse.mdm.api.base.adapter.Core;
+import org.eclipse.mdm.api.base.model.BaseEntity;
+import org.eclipse.mdm.api.base.model.ContextRoot;
+import org.eclipse.mdm.api.base.model.ContextType;
+import org.eclipse.mdm.api.base.model.Deletable;
+import org.eclipse.mdm.api.base.model.Value;
+
+/**
+ * Implementation of the template attribute entity type. A template root defines
+ * a tree of {@code TemplateComponent}s. Such a tree forms a hierarchical
+ * template structure which is used to describe the composition of a
+ * {@link ContextRoot}. A template root implements the {@link Versionable}
+ * interface and hence has a version and a state. As long as
+ * {@link #isEditable()} returns {@code true} any part of that template root is
+ * allowed to be modified. Once a template root is set to be valid
+ * ({@link #isValid()} == {@code true}) it may be used to compose a
+ * {@link TemplateTestStep} and then is no longer allowed to be modified in any
+ * way. If a valid template root needs to be modified, then a deep copy with a
+ * unique name and version combination has to be created (deep copy means new
+ * instances).
+ *
+ * @since 1.0.0
+ * @author Viktor Stoehr, Gigatronik Ingolstadt GmbH
+ * @see TemplateComponent
+ * @see Versionable
+ */
+public class TemplateRoot extends BaseEntity implements Deletable, Versionable {
+
+	// ======================================================================
+	// Instance variables
+	// ======================================================================
+
+	private final ContextType contextType;
+
+	// ======================================================================
+	// Constructors
+	// ======================================================================
+
+	/**
+	 * Constructor.
+	 *
+	 * @param core The {@link Core}.
+	 */
+	TemplateRoot(Core core) {
+		super(core);
+
+		String typeName = core.getTypeName().toUpperCase(Locale.ROOT);
+		for (ContextType contextTypeCandidate : ContextType.values()) {
+			if (typeName.contains(contextTypeCandidate.name())) {
+				contextType = contextTypeCandidate;
+				return;
+			}
+		}
+
+		throw new IllegalStateException("Core is incompatible.");
+	}
+
+	// ======================================================================
+	// Public methods
+	// ======================================================================
+
+	/**
+	 * Returns the {@link ContextType} of this template root.
+	 *
+	 * @return The {@code ContextType} is returned.
+	 */
+	public ContextType getContextType() {
+		return contextType;
+	}
+
+	/**
+	 * Returns the {@link TemplateComponent} identified by given name.
+	 *
+	 * <p>
+	 * <b>NOTE:</b> The names of <u>all</u> {@code TemplateComponent}s belonging to
+	 * the same template root must have unique names (no matter they are immediate
+	 * children or not). Therefore, if this template root does not have an immediate
+	 * {@code TemplateComponent} with the given name, this lookup request is
+	 * recursively delegated to all of its child {@code TemplateComponent}s.
+	 *
+	 * @param name The name of the {@code TemplateComponent}.
+	 * @return The {@code Optional} is empty if a {@code TemplateComponent} with
+	 *         given name does not exist at all within this template root.
+	 */
+	public Optional<TemplateComponent> getTemplateComponent(String name) {
+		List<TemplateComponent> templateComponents = getTemplateComponents();
+		Optional<TemplateComponent> templateComponent = templateComponents.stream().filter(tc -> tc.nameEquals(name))
+				.findAny();
+		if (templateComponent.isPresent()) {
+			return templateComponent;
+		}
+
+		return templateComponents.stream().map(tc -> tc.getTemplateComponent(name)).filter(Optional::isPresent)
+				.map(Optional::get).findAny();
+	}
+
+	/**
+	 * Returns all immediate {@link TemplateComponent}s related to this template
+	 * component.
+	 *
+	 * @return The returned {@code List} is unmodifiable.
+	 */
+	public List<TemplateComponent> getTemplateComponents() {
+		return getCore().getChildrenStore().get(TemplateComponent.class);
+	}
+
+	/**
+	 * Removes the {@link TemplateComponent} identified by given name.
+	 *
+	 * <p>
+	 * <b>NOTE:</b> The names of <u>all</u> {@code TemplateComponent}s belonging to
+	 * the same template roots must have unique names (no matter they are immediate
+	 * children or not). Therefore, if this template root does not have an immediate
+	 * {@code TemplateComponent} with the given name, this remove request is
+	 * recursively delegated to all of its child {@code TemplateComponent}s.
+	 *
+	 * @param name Name of the {@code TemplateComponent} that has to be removed.
+	 * @return Returns {@code true} if the {@code TemplateComponent} with given name
+	 *         has been removed.
+	 */
+	public boolean removeTemplateComponent(String name) {
+		Optional<TemplateComponent> templateComponent = getTemplateComponent(name);
+		if (templateComponent.isPresent()) {
+			Optional<TemplateComponent> parentTemplateComponent = templateComponent.get().getParentTemplateComponent();
+			if (parentTemplateComponent.isPresent()) {
+				parentTemplateComponent.get().removeTemplateComponent(name);
+			} else {
+				getCore().getChildrenStore().remove(templateComponent.get());
+			}
+			return true;
+		}
+
+		return false;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public String toString() {
+		StringBuilder sb = new StringBuilder(getClass().getSimpleName()).append('(');
+		sb.append("ContextType = ").append(getContextType()).append(", ");
+		sb.append(getValues().values().stream().map(Value::toString).collect(Collectors.joining(", ")));
+
+		List<TemplateComponent> templateComponents = getTemplateComponents();
+		if (!templateComponents.isEmpty()) {
+			sb.append(", TemplateComponents = ").append(templateComponents);
+		}
+
+		return sb.append(')').toString();
+	}
+
+	/**
+	 * Returns the {@link TemplateRoot} the given {@link ContextRoot} is derived
+	 * from.
+	 *
+	 * @param contextRoot The {@code ContextRoot} whose {@code TemplateRoot} is
+	 *                    requested.
+	 * @return {@code Optional} is empty if the given {@code ContextRoot} is not
+	 *         derived from a template, which is data source specific.
+	 */
+	public static Optional<TemplateRoot> of(ContextRoot contextRoot) {
+		return Optional.ofNullable(getCore(contextRoot).getMutableStore().get(TemplateRoot.class));
+	}
+
+}
diff --git a/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/TemplateSensor.java b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/TemplateSensor.java
new file mode 100644
index 0000000..6d38c4a
--- /dev/null
+++ b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/TemplateSensor.java
@@ -0,0 +1,337 @@
+/********************************************************************************
+ * Copyright (c) 2015-2019 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+package org.eclipse.mdm.api.dflt.model;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+import org.eclipse.mdm.api.base.adapter.Core;
+import org.eclipse.mdm.api.base.model.AxisType;
+import org.eclipse.mdm.api.base.model.BaseEntity;
+import org.eclipse.mdm.api.base.model.ContextComponent;
+import org.eclipse.mdm.api.base.model.ContextSensor;
+import org.eclipse.mdm.api.base.model.Deletable;
+import org.eclipse.mdm.api.base.model.Describable;
+import org.eclipse.mdm.api.base.model.Quantity;
+import org.eclipse.mdm.api.base.model.Sortable;
+import org.eclipse.mdm.api.base.model.Value;
+
+/**
+ * Implementation of the template sensor entity type. A template sensor adds
+ * meta data to a {@link CatalogSensor} it is associated with. It always belongs
+ * to a template component or a template sensor. Its name has to be unique
+ * within all template sensors belonging to the same {@link TemplateComponent}.
+ * A template sensor define {@link TemplateAttribute}s where each uniquely
+ * extends a {@link CatalogAttribute} provided by the associated {@code
+ * CatalogSensor}.
+ *
+ * @since 1.0.0
+ * @author Viktor Stoehr, Gigatronik Ingolstadt GmbH
+ * @see CatalogSensor
+ * @see TemplateComponent
+ * @see TemplateAttribute
+ */
+public class TemplateSensor extends BaseEntity implements Deletable, Describable, Sortable {
+
+	// ======================================================================
+	// Class variables
+	// ======================================================================
+
+	/**
+	 * The optional flag {@code Predicate}.
+	 */
+	public static final Predicate<TemplateSensor> IS_OPTIONAL = TemplateSensor::isOptional;
+
+	/**
+	 * The mandatory flag {@code Predicate}. This is the inversion of
+	 * {@link #IS_OPTIONAL} {@code Predicate}.
+	 */
+	public static final Predicate<TemplateSensor> IS_MANDATORY = IS_OPTIONAL.negate();
+
+	/**
+	 * The default active flag {@code Predicate}.
+	 */
+	public static final Predicate<TemplateSensor> IS_DEFAULT_ACTIVE = TemplateSensor::isDefaultActive;
+
+	/**
+	 * The implicit create flag {@code Predicate}. This is an OR combination of
+	 * {@link #IS_DEFAULT_ACTIVE} and {@link #IS_MANDATORY} {@code Predicate}s.
+	 */
+	public static final Predicate<TemplateSensor> IS_IMPLICIT_CREATE = IS_DEFAULT_ACTIVE.or(IS_MANDATORY);
+
+	/**
+	 * The 'Optional' attribute name.
+	 */
+	public static final String ATTR_OPTIONAL = "Optional";
+
+	/**
+	 * The 'DefaultActive' attribute name.
+	 */
+	public static final String ATTR_DEFAULT_ACTIVE = "DefaultActive";
+
+	/**
+	 * The 'MeasuredValuesEditable' attribute name.
+	 */
+	public static final String ATTR_MEASRED_VALUES_EDITABLE = "MeaQuantityValuesEditable";
+
+	/**
+	 * The 'MeasuredValuesGeneratorName' attribute name.
+	 */
+	public static final String ATTR_MEASRED_VALUES_GENERATOR_NAME = "MeaQuantityEditorPlugin";
+
+	/**
+	 * The 'MeasuredValuesIndependent' attribute name.
+	 */
+	public static final String ATTR_MEASRED_VALUES_INDEPENDENT = "MeaQuantityIndependent";
+
+	/**
+	 * The 'MeasuredValuesAxisType' attribute name.
+	 */
+	public static final String ATTR_MEASRED_VALUES_AXISTYPE = "MeaQuantityAxisType";
+
+	// ======================================================================
+	// Constructors
+	// ======================================================================
+
+	/**
+	 * Constructor.
+	 *
+	 * @param core The {@link Core}.
+	 */
+	TemplateSensor(Core core) {
+		super(core);
+	}
+
+	// ======================================================================
+	// Public methods
+	// ======================================================================
+
+	/**
+	 * Returns the measured values editable flag of this template sensor.
+	 *
+	 * @return The measured values editable flag is returned.
+	 */
+	public Boolean areMeasuredValuesEditable() {
+		return getValue(ATTR_MEASRED_VALUES_EDITABLE).extract();
+	}
+
+	/**
+	 * Sets a new measured values editable flag for this template sensor.
+	 *
+	 * @param measuredValuesEditable The measured values editable flag.
+	 */
+	public void setMeasuredValuesEditable(Boolean measuredValuesEditable) {
+		getValue(ATTR_MEASRED_VALUES_EDITABLE).set(measuredValuesEditable);
+	}
+
+	/**
+	 * Returns the measured values generator name of this template sensor.
+	 *
+	 * @return The measured values generator name is returned.
+	 */
+	public String getMeasuredValuesGeneratorName() {
+		return getValue(ATTR_MEASRED_VALUES_GENERATOR_NAME).extract();
+	}
+
+	/**
+	 * Sets a new measured values generator name for this template sensor.
+	 *
+	 * @param measuredValuesGeneratorName The measured values generator name.
+	 */
+	public void setMeasuredValuesGeneratorName(String measuredValuesGeneratorName) {
+		getValue(ATTR_MEASRED_VALUES_GENERATOR_NAME).set(measuredValuesGeneratorName);
+	}
+
+	/**
+	 * Returns the measured values independent flag of this template sensor.
+	 *
+	 * @return The measured values independent flag is returned.
+	 */
+	public Boolean areMeasuredValuesIndependent() {
+		return getValue(ATTR_MEASRED_VALUES_INDEPENDENT).extract();
+	}
+
+	/**
+	 * Sets a new measured values independent flag for this template sensor.
+	 *
+	 * @param measuredValuesIndependent The measured values independent flag.
+	 */
+	public void setMeasuredValuesIndependent(Boolean measuredValuesIndependent) {
+		getValue(ATTR_MEASRED_VALUES_INDEPENDENT).set(measuredValuesIndependent);
+	}
+
+	/**
+	 * Returns the measured values {@link AxisType} of this template sensor.
+	 *
+	 * @return The measured values {@code AxisType} is returned.
+	 */
+	public AxisType getMeasuredValuesAxisType() {
+		return getValue(ATTR_MEASRED_VALUES_AXISTYPE).extract();
+	}
+
+	/**
+	 * Sets a new measured values {@link AxisType} for this template sensor.
+	 *
+	 * @param axisType The measured values {@code AxisType}.
+	 */
+	public void setMeasuredValuesAxisType(AxisType axisType) {
+		getValue(ATTR_MEASRED_VALUES_AXISTYPE).set(axisType);
+	}
+
+	/**
+	 * Returns the optional flag of this template sensor.
+	 *
+	 * @return Returns {@code true} if it is allowed to omit a {@link ContextSensor}
+	 *         derived from this template sensor.
+	 */
+	public Boolean isOptional() {
+		return getValue(ATTR_OPTIONAL).extract();
+	}
+
+	/**
+	 * Sets a new optional flag for this template sensor.
+	 *
+	 * @param optional The new optional flag.
+	 */
+	public void setOptional(Boolean optional) {
+		getValue(ATTR_OPTIONAL).set(optional);
+	}
+
+	/**
+	 * Returns the default active flag of this template sensor.
+	 *
+	 * @return Returns {@code true} if a {@link ContextSensor} has to be created
+	 *         automatically each time a new {@link ContextComponent} is derived
+	 *         from the {@link TemplateComponent} this template sensor belongs to.
+	 */
+	public Boolean isDefaultActive() {
+		return getValue(ATTR_DEFAULT_ACTIVE).extract();
+	}
+
+	/**
+	 * Sets a new default active flag for this template sensor.
+	 *
+	 * @param defaultActive The new default active flag.
+	 */
+	public void setDefaultActive(Boolean defaultActive) {
+		getValue(ATTR_DEFAULT_ACTIVE).set(defaultActive);
+	}
+
+	/**
+	 * Returns the {@link CatalogSensor} this template sensor is associated with.
+	 *
+	 * @return The associated {@code CatalogSensor} is returned.
+	 */
+	public CatalogSensor getCatalogSensor() {
+		return getCore().getMutableStore().get(CatalogSensor.class);
+	}
+
+	/**
+	 * Returns the {@link Quantity} measured data are associated with.
+	 *
+	 * @return The {@code Quantity} is returned.
+	 */
+	public Quantity getQuantity() {
+		return getCore().getMutableStore().get(Quantity.class);
+	}
+
+	/**
+	 * Returns the {@link TemplateRoot} this template sensor belongs to.
+	 *
+	 * @return The {@code TemplateRoot} is returned.
+	 */
+	public TemplateRoot getTemplateRoot() {
+		return getTemplateComponent().getTemplateRoot();
+	}
+
+	/**
+	 * Returns the parent {@link TemplateComponent} of this template sensor.
+	 *
+	 * @return The parent {@code TemplateComponent} is returned.
+	 */
+	public TemplateComponent getTemplateComponent() {
+		return getCore().getPermanentStore().get(TemplateComponent.class);
+	}
+
+	/**
+	 * Returns the {@link TemplateAttribute} identified by given name.
+	 *
+	 * @param name The name of the {@code TemplateAttribute}.
+	 * @return The {@code Optional} is empty if a {@code TemplateAttribute} with
+	 *         given name does not exist.
+	 */
+	public Optional<TemplateAttribute> getTemplateAttribute(String name) {
+		return getTemplateAttributes().stream().filter(ta -> ta.nameEquals(name)).findAny();
+	}
+
+	/**
+	 * Returns all available {@link TemplateAttribute}s related to this template
+	 * sensor.
+	 *
+	 * @return The returned {@code List} is unmodifiable.
+	 */
+	public List<TemplateAttribute> getTemplateAttributes() {
+		return getCore().getChildrenStore().get(TemplateAttribute.class);
+	}
+
+	/**
+	 * Removes the {@link TemplateAttribute} identified by given name.
+	 *
+	 * @param name Name of the {@code TemplateAttribute} that has to be removed.
+	 * @return Returns {@code true} if the {@code TemplateAttribute} with given name
+	 *         has been removed.
+	 */
+	public boolean removeTemplateAttribute(String name) {
+		Optional<TemplateAttribute> templateAttribute = getTemplateAttribute(name);
+		if (templateAttribute.isPresent()) {
+			getCore().getChildrenStore().remove(templateAttribute.get());
+			return true;
+		}
+
+		return false;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public String toString() {
+		StringBuilder sb = new StringBuilder(getClass().getSimpleName()).append('(');
+		sb.append(getValues().values().stream().map(Value::toString).collect(Collectors.joining(", ")));
+
+		List<TemplateAttribute> templateAttributes = getTemplateAttributes();
+		if (!templateAttributes.isEmpty()) {
+			sb.append(", TemplateAttributes = ").append(templateAttributes);
+		}
+
+		return sb.append(')').toString();
+	}
+
+	/**
+	 * Returns the {@link TemplateSensor} the given {@link ContextSensor} is derived
+	 * from.
+	 *
+	 * @param contextSensor The {@code ContextSensor} whose {@code
+	 * 		TemplateSensor} is requested.
+	 * @return {@code Optional} is empty if the given {@code ContextSensor} is not
+	 *         derived from a template, which is data source specific.
+	 */
+	public static Optional<TemplateSensor> of(ContextSensor contextSensor) {
+		return Optional.ofNullable(getCore(contextSensor).getMutableStore().get(TemplateSensor.class));
+	}
+
+}
diff --git a/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/TemplateTest.java b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/TemplateTest.java
new file mode 100644
index 0000000..2d39ad8
--- /dev/null
+++ b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/TemplateTest.java
@@ -0,0 +1,224 @@
+/********************************************************************************
+ * Copyright (c) 2015-2019 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+package org.eclipse.mdm.api.dflt.model;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import org.eclipse.mdm.api.base.adapter.Core;
+import org.eclipse.mdm.api.base.model.BaseEntity;
+import org.eclipse.mdm.api.base.model.ContextComponent;
+import org.eclipse.mdm.api.base.model.Deletable;
+import org.eclipse.mdm.api.base.model.Describable;
+import org.eclipse.mdm.api.base.model.Test;
+import org.eclipse.mdm.api.base.model.Value;
+
+/**
+ * Implementation of the template test entity type. A template test consists of
+ * {@link TemplateTestStepUsage}s with unique names. It describes a template for
+ * a test run and provides meta data to resolve hooks and data sources for
+ * naming, property validation, resolution and other purposes. A template test
+ * implements the {@link Versionable} interface and hence has a version and a
+ * state. As long as {@link #isEditable()} returns {@code true} any part of that
+ * template test is allowed to be modified. Once a template test is set to be
+ * valid ({@link #isValid()} == {@code true}) it may be used to define a test
+ * run therefore is no longer allowed to be modified in any way. If a valid
+ * template test needs to be modified, then a deep copy with a unique name and
+ * version combination has to be created (deep copy means new instances).
+ *
+ * @since 1.0.0
+ * @author Viktor Stoehr, Gigatronik Ingolstadt GmbH
+ * @see TemplateTestStepUsage
+ * @see Versionable
+ */
+public class TemplateTest extends BaseEntity implements Deletable, Describable, Versionable {
+
+	// ======================================================================
+	// Class variables
+	// ======================================================================
+
+	/**
+	 * The 'NameHelperClassname' attribute name.
+	 */
+	public static final String ATTR_NAMEHELPER_CLASSNAME = "NameHelperClassname";
+
+	/**
+	 * The 'DataSourcePluginClassnames' attribute name.
+	 */
+	public static final String ATTR_DATASOURCE_PLUGIN_CLASSNAMES = "DataSourcePluginClassnames";
+
+	/**
+	 * The 'TestOrderActionClassnames' attribute name.
+	 */
+	public static final String ATTR_TEST_ORDER_ACTION_CLASSNAMES = "TestOrderActionClassnames";
+
+	// ======================================================================
+	// Constructors
+	// ======================================================================
+
+	/**
+	 * Constructor.
+	 *
+	 * @param core The {@link Core}.
+	 */
+	TemplateTest(Core core) {
+		super(core);
+	}
+
+	// ======================================================================
+	// Public methods
+	// ======================================================================
+
+	/**
+	 * Returns the name helper class name of this template test.
+	 *
+	 * @return The name helper class name is returned.
+	 */
+	public String getNameHelperClassname() {
+		return getValue(ATTR_NAMEHELPER_CLASSNAME).extract();
+	}
+
+	/**
+	 * Sets a new name helper class name for this template test.
+	 *
+	 * @param nameHelperClassname The new name helper class name.
+	 */
+	public void setNameHelperClassname(String nameHelperClassname) {
+		getValue(ATTR_NAMEHELPER_CLASSNAME).set(nameHelperClassname);
+	}
+
+	/**
+	 * Returns the data source plug-in class names of this template test.
+	 *
+	 * @return The data source plug-in class names are returned.
+	 */
+	public String[] getDataSourcePluginClassnames() {
+		return getValue(ATTR_DATASOURCE_PLUGIN_CLASSNAMES).extract();
+	}
+
+	/**
+	 * Sets new data source plug-in class names for this template test.
+	 *
+	 * @param dataSourcePluginClassnames The new data source plug-in class names.
+	 */
+	public void setDataSourceClassnames(String[] dataSourcePluginClassnames) {
+		getValue(ATTR_DATASOURCE_PLUGIN_CLASSNAMES).set(dataSourcePluginClassnames);
+	}
+
+	/**
+	 * Returns the test order action class names of this template test.
+	 *
+	 * @return The test order action class names are returned.
+	 */
+	public String[] getTestOrderActionClassnames() {
+		return getValue(ATTR_TEST_ORDER_ACTION_CLASSNAMES).extract();
+	}
+
+	/**
+	 * Sets new test order action class names for this template test.
+	 *
+	 * @param testOrderActionClassnames The new test order action class names.
+	 */
+	public void setTestOrderActionClassnames(String[] testOrderActionClassnames) {
+		getValue(ATTR_TEST_ORDER_ACTION_CLASSNAMES).set(testOrderActionClassnames);
+	}
+
+	/**
+	 * Returns the {@link TemplateTestStepUsage} identified by given name.
+	 *
+	 * @param name The name of the {@code TemplateTestStepUsage}.
+	 * @return The {@code Optional} is empty if a {@code TemplateTestStepUsage} with
+	 *         given name does not exist.
+	 */
+	public Optional<TemplateTestStepUsage> getTemplateTestStepUsage(String name) {
+		return getTemplateTestStepUsages().stream().filter(ttsu -> ttsu.nameEquals(name)).findAny();
+	}
+
+	/**
+	 * Returns all available {@link TemplateTestStepUsage}s related to this template
+	 * test.
+	 *
+	 * @return The returned {@code List} is unmodifiable.
+	 */
+	public List<TemplateTestStepUsage> getTemplateTestStepUsages() {
+		return getCore().getChildrenStore().get(TemplateTestStepUsage.class);
+	}
+
+	/**
+	 * Removes the {@link TemplateTestStepUsage} identified by given name.
+	 *
+	 * @param name Name of the {@code TemplateTestStepUsage} that has to be removed.
+	 * @return Returns {@code true} if the {@code TemplateTestStepUsage} with given
+	 *         name has been removed.
+	 */
+	public boolean removeTemplateTestStepUsage(String name) {
+		Optional<TemplateTestStepUsage> templateTestStepUsage = getTemplateTestStepUsage(name);
+		if (templateTestStepUsage.isPresent()) {
+			getCore().getChildrenStore().remove(templateTestStepUsage.get());
+			return true;
+		}
+
+		return false;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public String toString() {
+		StringBuilder sb = new StringBuilder(getClass().getSimpleName()).append('(');
+		sb.append(getValues().values().stream().map(Value::toString).collect(Collectors.joining(", ")));
+
+		List<TemplateTestStepUsage> templateTestStepUsages = getTemplateTestStepUsages();
+		if (!templateTestStepUsages.isEmpty()) {
+			sb.append(", TemplateTestStepUsages = ").append(templateTestStepUsages);
+		}
+
+		return sb.append(')').toString();
+	}
+
+	/**
+	 * Returns the {@link TemplateComponent} the given {@link ContextComponent} is
+	 * derived from.
+	 *
+	 * @param test The {@code ContextComponent} whose {@code TemplateComponent} is
+	 *             requested.
+	 * @return {@code Optional} is empty if the given {@code ContextComponent} is
+	 *         not derived from a template, which is data source specific.
+	 */
+	public static Optional<TemplateTest> of(Test test) {
+		return Optional.ofNullable(getCore(test).getMutableStore().get(TemplateTest.class));
+	}
+
+	// ======================================================================
+	// Package methods
+	// ======================================================================
+
+	/**
+	 * Checks whether given {@link TemplateTestStepUsage} is contained in this
+	 * template test.
+	 *
+	 * @param templateTestStep The {@code TemplateTestStepUsage}.
+	 * @return Returns {@code true} if given {@code TemplateTestStepUsage} is
+	 *         contained in this template test.
+	 */
+	boolean contains(TemplateTestStep templateTestStep) {
+		return getTemplateTestStepUsages().stream().map(TemplateTestStepUsage::getTemplateTestStep)
+				.filter(tts -> tts.getName().equals(templateTestStep.getName()))
+				.filter(tts -> tts.getVersion().equals(templateTestStep.getVersion())).findFirst().isPresent();
+	}
+
+}
diff --git a/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/TemplateTestStep.java b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/TemplateTestStep.java
new file mode 100644
index 0000000..1690562
--- /dev/null
+++ b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/TemplateTestStep.java
@@ -0,0 +1,127 @@
+/********************************************************************************
+ * Copyright (c) 2015-2019 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+package org.eclipse.mdm.api.dflt.model;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+import org.eclipse.mdm.api.base.adapter.Core;
+import org.eclipse.mdm.api.base.model.BaseEntity;
+import org.eclipse.mdm.api.base.model.ContextType;
+import org.eclipse.mdm.api.base.model.Deletable;
+import org.eclipse.mdm.api.base.model.Describable;
+import org.eclipse.mdm.api.base.model.TestStep;
+
+/**
+ * Implementation of the template test step entity type. A template test step
+ * describes the composition of {@link TemplateRoot}s which in finally is a
+ * template for a persisted context description ("as measured", "as ordered"). A
+ * template test step implements the {@link Versionable} interface and hence has
+ * a version and a state. As long as {@link #isEditable()} returns {@code
+ * true} any part of that template test step is allowed to be modified. Once a
+ * template test step is set to be valid ({@link #isValid()} == {@code true}) it
+ * may be used to compose a {@link TemplateTest} and then is no longer allowed
+ * to be modified in any way. If a valid template test step needs to be
+ * modified, then a deep copy with a unique name and version combination has to
+ * be created (deep copy means new instances).
+ *
+ * @since 1.0.0
+ * @author Viktor Stoehr, Gigatronik Ingolstadt GmbH
+ * @see TemplateRoot
+ * @see Versionable
+ */
+public class TemplateTestStep extends BaseEntity implements Deletable, Describable, Versionable {
+
+	// ======================================================================
+	// Constructors
+	// ======================================================================
+
+	/**
+	 * Constructor.
+	 *
+	 * @param core The {@link Core}.
+	 */
+	TemplateTestStep(Core core) {
+		super(core);
+	}
+
+	// ======================================================================
+	// Public methods
+	// ======================================================================
+
+	/**
+	 * Returns the related {@link TemplateRoot} with given {@link ContextType} of
+	 * this template test step.
+	 *
+	 * @param contextType Used as identifier.
+	 * @return {@code Optional} is empty if a {@code TemplateRoot} of given
+	 *         {@code ContextType} does not exist.
+	 */
+	public Optional<TemplateRoot> getTemplateRoot(ContextType contextType) {
+		return Optional.ofNullable(getCore().getMutableStore().get(TemplateRoot.class, contextType));
+	}
+
+	/**
+	 * Returns all available {@link TemplateRoot}s related to this template test
+	 * step.
+	 *
+	 * @return Returns {@code List} contains up to 3 {@code TemplateRoot}s with
+	 *         distinct {@link ContextType}s.
+	 */
+	public List<TemplateRoot> getTemplateRoots() {
+		List<TemplateRoot> templateRoots = new ArrayList<>();
+		getTemplateRoot(ContextType.UNITUNDERTEST).ifPresent(templateRoots::add);
+		getTemplateRoot(ContextType.TESTSEQUENCE).ifPresent(templateRoots::add);
+		getTemplateRoot(ContextType.TESTEQUIPMENT).ifPresent(templateRoots::add);
+		return templateRoots;
+	}
+
+	/**
+	 * Replaces current {@link TemplateRoot} with the given one.
+	 *
+	 * @param templateRoot Is not allowed to be null.
+	 * @see #removeTemplateRoot(ContextType)
+	 */
+	public void setTemplateRoot(TemplateRoot templateRoot) {
+		getCore().getMutableStore().set(templateRoot, templateRoot.getContextType());
+	}
+
+	/**
+	 * Removes current {@link TemplateRoot} with given {@link ContextType}.
+	 *
+	 * @param contextType Used as identifier.
+	 * @return Returns {@code true} if the {@code TemplateRoot} has been removed.
+	 */
+	public boolean removeTemplateRoot(ContextType contextType) {
+		boolean contained = getTemplateRoot(contextType).isPresent();
+		getCore().getMutableStore().remove(TemplateRoot.class, contextType);
+		return contained;
+	}
+
+	/**
+	 * Returns the {@link TemplateTestStep} the given {@link TestStep} is derived
+	 * from.
+	 *
+	 * @param testStep The {@code TestStep} whose {@code TemplateTestStep} is
+	 *                 requested.
+	 * @return {@code Optional} is empty if the given {@code TestStep} is not
+	 *         derived from a template.
+	 */
+	public static Optional<TemplateTestStep> of(TestStep testStep) {
+		return Optional.ofNullable(getCore(testStep).getMutableStore().get(TemplateTestStep.class));
+	}
+
+}
diff --git a/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/TemplateTestStepUsage.java b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/TemplateTestStepUsage.java
new file mode 100644
index 0000000..e7323c1
--- /dev/null
+++ b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/TemplateTestStepUsage.java
@@ -0,0 +1,148 @@
+/********************************************************************************
+ * Copyright (c) 2015-2019 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+package org.eclipse.mdm.api.dflt.model;
+
+import java.util.function.Predicate;
+
+import org.eclipse.mdm.api.base.adapter.Core;
+import org.eclipse.mdm.api.base.model.BaseEntity;
+import org.eclipse.mdm.api.base.model.Deletable;
+import org.eclipse.mdm.api.base.model.Sortable;
+import org.eclipse.mdm.api.base.model.Test;
+import org.eclipse.mdm.api.base.model.TestStep;
+
+/**
+ * Implementation of the template test step usage entity type. A template test
+ * relates a {@link TemplateTestStep} with a parent {@link TemplateTest} (n:m).
+ *
+ * @since 1.0.0
+ * @author Viktor Stoehr, Gigatronik Ingolstadt GmbH
+ * @see TemplateTest
+ * @see TemplateTestStep
+ */
+public class TemplateTestStepUsage extends BaseEntity implements Deletable, Sortable {
+
+	// ======================================================================
+	// Class variables
+	// ======================================================================
+
+	/**
+	 * The optional flag {@code Predicate}.
+	 */
+	public static final Predicate<TemplateTestStepUsage> IS_OPTIONAL = TemplateTestStepUsage::isOptional;
+
+	/**
+	 * The mandatory flag {@code Predicate}. This is the inversion of
+	 * {@link #IS_OPTIONAL} {@code Predicate}.
+	 */
+	public static final Predicate<TemplateTestStepUsage> IS_MANDATORY = IS_OPTIONAL.negate();
+
+	/**
+	 * The default active flag {@code Predicate}.
+	 */
+	public static final Predicate<TemplateTestStepUsage> IS_DEFAULT_ACTIVE = TemplateTestStepUsage::isDefaultActive;
+
+	/**
+	 * The implicit create flag {@code Predicate}. This is an OR combination of
+	 * {@link #IS_DEFAULT_ACTIVE} and {@link #IS_MANDATORY} {@code Predicate}s.
+	 */
+	public static final Predicate<TemplateTestStepUsage> IS_IMPLICIT_CREATE = IS_DEFAULT_ACTIVE.or(IS_MANDATORY);
+
+	/**
+	 * The 'DefaultActive' attribute name.
+	 */
+	public static final String ATTR_DEFAULT_ACTIVE = "DefaultActive";
+
+	/**
+	 * The 'Optional' attribute name.
+	 */
+	public static final String ATTR_OPTIONAL = "Optional";
+
+	// ======================================================================
+	// Constructors
+	// ======================================================================
+
+	/**
+	 * Constructor.
+	 *
+	 * @param core The {@link Core}.
+	 */
+	TemplateTestStepUsage(Core core) {
+		super(core);
+	}
+
+	// ======================================================================
+	// Public methods
+	// ======================================================================
+
+	/**
+	 * Returns the default active flag of this template test step usage.
+	 *
+	 * @return Returns {@code true} if a {@link TestStep} has to be created
+	 *         automatically each time a new {@link Test} is derived from the
+	 *         {@link TemplateTest} this template test step usage belongs to.
+	 */
+	public Boolean isDefaultActive() {
+		return getValue(ATTR_DEFAULT_ACTIVE).extract();
+	}
+
+	/**
+	 * Sets a new default active flag for this template test step usage.
+	 *
+	 * @param defaultActive The new default active flag.
+	 */
+	public void setDefaultActive(Boolean defaultActive) {
+		getValue(ATTR_DEFAULT_ACTIVE).set(defaultActive);
+	}
+
+	/**
+	 * Returns the optional flag of this template test step.
+	 *
+	 * @return Returns {@code true} if it is allowed to omit a {@link TestStep}
+	 *         derived from this template test step usage.
+	 */
+	public Boolean isOptional() {
+		return getValue(ATTR_OPTIONAL).extract();
+	}
+
+	/**
+	 * Sets a new optional flag for this template test step usage.
+	 *
+	 * @param optional The new optional flag.
+	 */
+	public void setOptional(Boolean optional) {
+		getValue(ATTR_OPTIONAL).set(optional);
+	}
+
+	/**
+	 * Returns the parent {@link TemplateTest}.
+	 *
+	 * @return The parent {@code TemplateTest} is returned.
+	 */
+	public TemplateTest getTemplateTest() {
+		return getCore().getPermanentStore().get(TemplateTest.class);
+	}
+
+	/**
+	 * Returns the {@link TemplateTestStep} related to this template test step
+	 * usage.
+	 *
+	 * @return The {@code TemplateTestStep} is returned.
+	 */
+	public TemplateTestStep getTemplateTestStep() {
+		return getCore().getMutableStore().get(TemplateTestStep.class);
+	}
+
+}
diff --git a/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/UserParameter.java b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/UserParameter.java
new file mode 100644
index 0000000..7997ab7
--- /dev/null
+++ b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/UserParameter.java
@@ -0,0 +1,28 @@
+/*******************************************************************************

+ * Copyright (c) 2020 Contributors to the Eclipse Foundation

+ *

+ * See the NOTICE file(s) distributed with this work for additional

+ * information regarding copyright ownership.

+ *

+ * This program and the accompanying materials are made available under the

+ * terms of the Eclipse Public License v. 2.0 which is available at

+ * http://www.eclipse.org/legal/epl-2.0.

+ *

+ * SPDX-License-Identifier: EPL-2.0

+ *******************************************************************************/

+package org.eclipse.mdm.api.dflt.model;

+

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

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

+

+/**

+ * @author akn

+ *

+ */

+public class UserParameter extends BaseEntity {

+

+	UserParameter(Core core) {

+		super(core);

+	}

+

+}

diff --git a/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/ValueList.java b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/ValueList.java
new file mode 100644
index 0000000..b6327b3
--- /dev/null
+++ b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/ValueList.java
@@ -0,0 +1,110 @@
+/********************************************************************************
+ * Copyright (c) 2015-2019 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+package org.eclipse.mdm.api.dflt.model;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import org.eclipse.mdm.api.base.adapter.Core;
+import org.eclipse.mdm.api.base.model.BaseEntity;
+import org.eclipse.mdm.api.base.model.Datable;
+import org.eclipse.mdm.api.base.model.Deletable;
+import org.eclipse.mdm.api.base.model.Describable;
+import org.eclipse.mdm.api.base.model.Value;
+
+/**
+ * Implementation of the value list entity type. A value list provides a set of
+ * default values which may be used as options while defining default values in
+ * templates or modifying context data.
+ *
+ * @since 1.0.0
+ * @author Viktor Stoehr, Gigatronik Ingolstadt GmbH
+ * @see ValueListValue
+ * @see CatalogAttribute
+ */
+public class ValueList extends BaseEntity implements Datable, Describable, Deletable {
+
+	// ======================================================================
+	// Constructors
+	// ======================================================================
+
+	/**
+	 * Constructor.
+	 *
+	 * @param core The {@link Core}.
+	 */
+	ValueList(Core core) {
+		super(core);
+	}
+
+	// ======================================================================
+	// Public methods
+	// ======================================================================
+
+	/**
+	 * Returns the {@link ValueListValue} identified by given name.
+	 *
+	 * @param name The name of the {@code ValueListValue}.
+	 * @return The {@code Optional} is empty if a {@code ValueListValue} with given
+	 *         name does not exist.
+	 */
+	public Optional<ValueListValue> getValueListValue(String name) {
+		return getValueListValues().stream().filter(vlv -> vlv.nameEquals(name)).findAny();
+	}
+
+	/**
+	 * Returns all available {@link ValueListValue}s related to this value list.
+	 *
+	 * @return The returned {@code List} is unmodifiable.
+	 */
+	public List<ValueListValue> getValueListValues() {
+		return getCore().getChildrenStore().get(ValueListValue.class);
+	}
+
+	/**
+	 * Removes the {@link ValueListValue} identified by given name.
+	 *
+	 * @param name Name of the {@code ValueListValue} that has to be removed.
+	 * @return Returns {@code true} if the {@code ValueListValues} with given name
+	 *         has been removed.
+	 */
+	public boolean removeValueListValue(String name) {
+		Optional<ValueListValue> valueListValue = getValueListValue(name);
+		if (valueListValue.isPresent()) {
+			getCore().getChildrenStore().remove(valueListValue.get());
+			return true;
+		}
+
+		return false;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public String toString() {
+		StringBuilder sb = new StringBuilder(getClass().getSimpleName()).append('(');
+		sb.append(getValues().values().stream().map(Value::toString).collect(Collectors.joining(", ")));
+
+		List<ValueListValue> valueListValues = getValueListValues();
+		if (!valueListValues.isEmpty()) {
+			sb.append(", ValueListValues = ").append(valueListValues);
+		}
+
+		return sb.append(')').toString();
+	}
+
+}
diff --git a/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/ValueListValue.java b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/ValueListValue.java
new file mode 100644
index 0000000..936ad5f
--- /dev/null
+++ b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/ValueListValue.java
@@ -0,0 +1,83 @@
+/********************************************************************************
+ * Copyright (c) 2015-2019 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+package org.eclipse.mdm.api.dflt.model;
+
+import org.eclipse.mdm.api.base.adapter.Core;
+import org.eclipse.mdm.api.base.model.BaseEntity;
+import org.eclipse.mdm.api.base.model.Deletable;
+import org.eclipse.mdm.api.base.model.Describable;
+import org.eclipse.mdm.api.base.model.Sortable;
+
+/**
+ * Implementation of the value list value entity type. A value list value is a
+ * unique value option within the parent {@link ValueList}. Therefore the names
+ * of the value list values within a {@code ValueList} have to be unique.
+ *
+ * @since 1.0.0
+ * @author Viktor Stoehr, Gigatronik Ingolstadt GmbH
+ * @see ValueList
+ */
+public class ValueListValue extends BaseEntity implements Deletable, Describable, Sortable {
+
+	// ======================================================================
+	// Class variables
+	// ======================================================================
+
+	/**
+	 * The 'ScalarType' attribute name.
+	 */
+	public static final String ATTR_SCALAR_TYPE = "DataType";
+
+	/**
+	 * The 'Value' attribute name.
+	 */
+	public static final String ATTR_VALUE = "Value";
+
+	// ======================================================================
+	// Class variables
+	// ======================================================================
+
+	/**
+	 * Constructor.
+	 *
+	 * @param core The {@link Core}.
+	 */
+	ValueListValue(Core core) {
+		super(core);
+	}
+
+	// ======================================================================
+	// Public methods
+	// ======================================================================
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void setName(String name) {
+		getValue(ATTR_VALUE).set(name);
+		super.setName(name);
+	}
+
+	/**
+	 * Returns the parent {@link ValueList}.
+	 *
+	 * @return The parent {@code ValueList} is returned.
+	 */
+	public ValueList getValueList() {
+		return getCore().getPermanentStore().get(ValueList.class);
+	}
+
+}
diff --git a/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/Versionable.java b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/Versionable.java
new file mode 100644
index 0000000..4ca00f4
--- /dev/null
+++ b/org.eclipse.mdm.api.default/src/main/java/org/eclipse/mdm/api/dflt/model/Versionable.java
@@ -0,0 +1,120 @@
+/********************************************************************************
+ * Copyright (c) 2015-2019 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+package org.eclipse.mdm.api.dflt.model;
+
+import java.util.Comparator;
+
+import org.eclipse.mdm.api.base.model.Datable;
+import org.eclipse.mdm.api.base.model.VersionState;
+
+/**
+ * This interface extends the {@link Datable} interface and provides getter and
+ * setter methods for the 'Version' and 'VersionState' fields of an entity.
+ *
+ * @since 1.0.0
+ * @author Viktor Stoehr, Gigatronik Ingolstadt GmbH
+ */
+public interface Versionable extends Datable {
+
+	// ======================================================================
+	// Class variables
+	// ======================================================================
+
+	/**
+	 * This {@code Comparator} compares {@link Versionable}s by their name (in
+	 * ascending order) and version (in descending order).
+	 */
+	Comparator<Versionable> COMPARATOR = Comparator.comparing(Versionable::getName)
+			.thenComparing(Comparator.comparing(Versionable::getVersion).reversed());
+
+	/**
+	 * The 'Version' attribute name.
+	 */
+	String ATTR_VERSION = "Version";
+
+	/**
+	 * The 'VersionState' attribute name.
+	 */
+	String ATTR_VERSION_STATE = "ValidFlag";
+
+	// ======================================================================
+	// Public methods
+	// ======================================================================
+
+	/**
+	 * Returns the version of this entity.
+	 *
+	 * @return The version is returned.
+	 */
+	default Integer getVersion() {
+		return Integer.valueOf(getValue(ATTR_VERSION).extract());
+	}
+
+	/**
+	 * Sets new version for this entity.
+	 *
+	 * @param version The new version.
+	 */
+	default void setVersion(Integer version) {
+		getValue(ATTR_VERSION).set(version.toString());
+	}
+
+	/**
+	 * Returns the {@link VersionState} of this entity.
+	 *
+	 * @return The {@code VersionState} is returned.
+	 */
+	default VersionState getVersionState() {
+		return getValue(ATTR_VERSION_STATE).extract();
+	}
+
+	/**
+	 * Sets new {@link VersionState} for this entity.
+	 *
+	 * @param versionState The new {@code VersionState}.
+	 */
+	default void setVersionState(VersionState versionState) {
+		getValue(ATTR_VERSION_STATE).set(versionState);
+	}
+
+	/**
+	 * Checks whether parts of this versionable are allowed to be modified.
+	 *
+	 * @return Returns {@code true} if modifications are allowed.
+	 */
+	default boolean isEditable() {
+		return getVersionState().isEditable();
+	}
+
+	/**
+	 * Checks whether this versionable is valid and therefore is no longer allowed
+	 * to be modified.
+	 *
+	 * @return Returns {@code true} if this versionable is valid.
+	 */
+	default boolean isValid() {
+		return getVersionState().isValid();
+	}
+
+	/**
+	 * Checks whether this versionable is archived.
+	 *
+	 * @return Returns {@code true} if this versionable is archived.
+	 */
+	default boolean isArchived() {
+		return getVersionState().isArchived();
+	}
+
+}
diff --git a/org.eclipse.mdm.api.default/src/test/java/org/eclipse/mdm/api/dflt/model/EntityFactoryTest.java b/org.eclipse.mdm.api.default/src/test/java/org/eclipse/mdm/api/dflt/model/EntityFactoryTest.java
new file mode 100644
index 0000000..fe77bdb
--- /dev/null
+++ b/org.eclipse.mdm.api.default/src/test/java/org/eclipse/mdm/api/dflt/model/EntityFactoryTest.java
@@ -0,0 +1,43 @@
+/********************************************************************************
+ * Copyright (c) 2015-2019 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+package org.eclipse.mdm.api.dflt.model;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.eclipse.mdm.api.base.model.Channel;
+import org.junit.Test;
+
+public class EntityFactoryTest {
+
+	@Test
+	public void createBaseEntities() {
+		EntityFactory entityFactory = mock(EntityFactory.class);
+		when(entityFactory.createBaseEntity(any(), any())).thenCallRealMethod();
+
+		// The Entities below were chosen as representatives of their respective
+		// packages since their constructors don't do anything with the Core instances
+		// passed to them, so a null pointer is sufficient for this test.
+
+		// Channel class is in package org.eclipse.mdm.api.base.model
+		// (BaseEntityFactory's package):
+		assertThat(entityFactory.createBaseEntity(Channel.class, null)).isInstanceOf(Channel.class);
+		// CatalogSensor class is in package org.eclipse.mdm.api.dflt.model
+		// (EntityFactory's package):
+		assertThat(entityFactory.createBaseEntity(CatalogSensor.class, null)).isInstanceOf(CatalogSensor.class);
+	}
+}